forked from Azure/azure-sdk-for-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Azure#224 from daschult/SupportLocationPolling
Add support for Location and Azure-AsyncOperation long running operations
- Loading branch information
Showing
9 changed files
with
817 additions
and
316 deletions.
There are no files selected for viewing
154 changes: 154 additions & 0 deletions
154
...-client-runtime/src/main/java/com/microsoft/azure/v2/AzureAsyncOperationPollStrategy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/** | ||
* Copyright (c) Microsoft Corporation. All rights reserved. | ||
* Licensed under the MIT License. See License.txt in the project root for | ||
* license information. | ||
*/ | ||
|
||
package com.microsoft.azure.v2; | ||
|
||
import com.microsoft.rest.protocol.SerializerAdapter; | ||
import com.microsoft.rest.v2.http.HttpRequest; | ||
import com.microsoft.rest.v2.http.HttpResponse; | ||
import rx.Single; | ||
import rx.functions.Func1; | ||
|
||
import java.io.IOException; | ||
|
||
/** | ||
* A PollStrategy type that uses the Azure-AsyncOperation header value to check the status of a long | ||
* running operation. | ||
*/ | ||
public final class AzureAsyncOperationPollStrategy extends PollStrategy { | ||
private final String fullyQualifiedMethodName; | ||
private final String operationResourceUrl; | ||
private final String originalResourceUrl; | ||
private final SerializerAdapter<?> serializer; | ||
private boolean pollingCompleted; | ||
private boolean pollingSucceeded; | ||
private boolean gotResourceResponse; | ||
|
||
/** | ||
* The name of the header that indicates that a long running operation will use the | ||
* Azure-AsyncOperation strategy. | ||
*/ | ||
public static final String HEADER_NAME = "Azure-AsyncOperation"; | ||
|
||
/** | ||
* The provisioning state of the operation resource if the operation is still in progress. | ||
*/ | ||
public static final String IN_PROGRESS = "InProgress"; | ||
|
||
/** | ||
* The provisioning state of the operation resource if the operation is successful. | ||
*/ | ||
public static final String SUCCEEDED = "Succeeded"; | ||
|
||
/** | ||
* Create a new AzureAsyncOperationPollStrategy object that will poll the provided operation | ||
* resource URL. | ||
* @param fullyQualifiedMethodName The fully qualified name of the method that initiated the | ||
* long running operation. | ||
* @param operationResourceUrl The URL of the operation resource this pollStrategy will poll. | ||
* @param originalResourceUrl The URL of the resource that the long running operation is | ||
* operating on. | ||
* @param serializer The serializer that will deserialize the operation resource and the | ||
* final operation result. | ||
*/ | ||
private AzureAsyncOperationPollStrategy(String fullyQualifiedMethodName, String operationResourceUrl, String originalResourceUrl, SerializerAdapter<?> serializer) { | ||
super(AzureProxy.defaultDelayInMilliseconds()); | ||
|
||
this.fullyQualifiedMethodName = fullyQualifiedMethodName; | ||
this.operationResourceUrl = operationResourceUrl; | ||
this.originalResourceUrl = originalResourceUrl; | ||
this.serializer = serializer; | ||
} | ||
|
||
@Override | ||
public HttpRequest createPollRequest() { | ||
String pollUrl = null; | ||
if (!pollingCompleted) { | ||
pollUrl = operationResourceUrl; | ||
} | ||
else if (pollingSucceeded) { | ||
pollUrl = originalResourceUrl; | ||
} | ||
return new HttpRequest(fullyQualifiedMethodName, "GET", pollUrl); | ||
} | ||
|
||
@Override | ||
public void updateFrom(HttpResponse httpPollResponse) throws IOException { | ||
updateFromAsync(httpPollResponse).toBlocking().value(); | ||
} | ||
|
||
@Override | ||
public Single<HttpResponse> updateFromAsync(final HttpResponse httpPollResponse) { | ||
updateDelayInMillisecondsFrom(httpPollResponse); | ||
|
||
Single<HttpResponse> result; | ||
if (!pollingCompleted) { | ||
result = httpPollResponse.bodyAsStringAsync() | ||
.flatMap(new Func1<String, Single<HttpResponse>>() { | ||
@Override | ||
public Single<HttpResponse> call(String bodyString) { | ||
Single<HttpResponse> result; | ||
try { | ||
final OperationResource operationResource = serializer.deserialize(bodyString, OperationResource.class); | ||
if (operationResource != null) { | ||
final String provisioningState = provisioningState(operationResource); | ||
pollingCompleted = !IN_PROGRESS.equalsIgnoreCase(provisioningState); | ||
if (pollingCompleted) { | ||
pollingSucceeded = SUCCEEDED.equalsIgnoreCase(provisioningState); | ||
clearDelayInMilliseconds(); | ||
} | ||
} | ||
result = Single.just(httpPollResponse); | ||
} catch (IOException e) { | ||
result = Single.error(e); | ||
} | ||
return result; | ||
} | ||
}); | ||
} | ||
else { | ||
if (pollingSucceeded) { | ||
gotResourceResponse = true; | ||
} | ||
|
||
result = Single.just(httpPollResponse); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private static String provisioningState(OperationResource operationResource) { | ||
String provisioningState = null; | ||
|
||
final OperationResource.Properties properties = operationResource.properties(); | ||
if (properties != null) { | ||
provisioningState = properties.provisioningState(); | ||
} | ||
|
||
return provisioningState; | ||
} | ||
|
||
@Override | ||
public boolean isDone() { | ||
return pollingCompleted && (!pollingSucceeded || gotResourceResponse); | ||
} | ||
|
||
/** | ||
* Try to create a new AzureAsyncOperationPollStrategy object that will poll the provided | ||
* operation resource URL. If the provided HttpResponse doesn't have an Azure-AsyncOperation | ||
* header or if the header is empty, then null will be returned. | ||
* @param fullyQualifiedMethodName The fully qualified name of the method that initiated the | ||
* long running operation. | ||
* @param httpResponse The HTTP response that the required header values for this pollStrategy | ||
* will be read from. | ||
*/ | ||
static AzureAsyncOperationPollStrategy tryToCreate(String fullyQualifiedMethodName, HttpResponse httpResponse, String originalResourceUrl, SerializerAdapter<?> serializer) { | ||
final String azureAsyncOperationUrl = httpResponse.headerValue(HEADER_NAME); | ||
return azureAsyncOperationUrl != null && !azureAsyncOperationUrl.isEmpty() | ||
? new AzureAsyncOperationPollStrategy(fullyQualifiedMethodName, azureAsyncOperationUrl, originalResourceUrl, serializer) | ||
: null; | ||
} | ||
} |
Oops, something went wrong.