/// <summary> /// Updates PollingState from Location header on Put operations. /// </summary> /// <typeparam name="TBody">Type of the resource body.</typeparam> /// <typeparam name="THeader">Type of the resource header.</typeparam> /// <param name="client">IAzureClient</param> /// <param name="pollingState">Current polling state.</param> /// <param name="customHeaders">Headers that will be added to request</param> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Task.</returns> private static async Task UpdateStateFromLocationHeaderOnPut <TBody, THeader>( IAzureClient client, PollingState <TBody, THeader> pollingState, Dictionary <string, List <string> > customHeaders, CancellationToken cancellationToken) where TBody : class where THeader : class { AzureOperationResponse <JObject, JObject> responseWithResource = await client.GetRawAsync( pollingState.LocationHeaderLink, customHeaders, cancellationToken).ConfigureAwait(false); pollingState.Response = responseWithResource.Response; pollingState.Request = responseWithResource.Request; var statusCode = responseWithResource.Response.StatusCode; if (statusCode == HttpStatusCode.Accepted) { pollingState.Status = AzureAsyncOperation.InProgressStatus; } else if (statusCode == HttpStatusCode.OK || statusCode == HttpStatusCode.Created) { if (responseWithResource.Body == null) { throw new CloudException(Resources.NoBody); } // In 202 pattern on PUT ProvisioningState may not be present in // the response. In that case the assumption is the status is Succeeded. var resource = responseWithResource.Body; if (resource["properties"] != null && resource["properties"]["provisioningState"] != null) { pollingState.Status = (string)resource["properties"]["provisioningState"]; } else { pollingState.Status = AzureAsyncOperation.SuccessStatus; } pollingState.Error = new CloudError() { Code = pollingState.Status, Message = string.Format(Resources.LongRunningOperationFailed, pollingState.Status) }; pollingState.Resource = responseWithResource.Body.ToObject <TBody>(JsonSerializer .Create(client.DeserializationSettings)); pollingState.ResourceHeaders = responseWithResource.Headers.ToObject <THeader>(JsonSerializer .Create(client.DeserializationSettings)); } }
/// <summary> /// Updates PollingState from Location header. /// </summary> /// <typeparam name="TBody">Type of the resource body.</typeparam> /// <typeparam name="THeader">Type of the resource header.</typeparam> /// <param name="client">IAzureClient</param> /// <param name="pollingState">Current polling state.</param> /// <param name="customHeaders">Headers that will be added to request</param> /// <param name="cancellationToken">Cancellation token</param> /// <param name="method">Http method of the initial long running operation request</param> /// <returns>Task.</returns> private static async Task UpdateStateFromLocationHeader <TBody, THeader>( IAzureClient client, PollingState <TBody, THeader> pollingState, Dictionary <string, List <string> > customHeaders, CancellationToken cancellationToken, HttpMethod method) where TBody : class where THeader : class { AzureOperationResponse <JObject, JObject> responseWithResource = await client.GetRawAsync( pollingState.LocationHeaderLink, customHeaders, cancellationToken).ConfigureAwait(false); pollingState.Response = responseWithResource.Response; pollingState.Request = responseWithResource.Request; var statusCode = responseWithResource.Response.StatusCode; if (statusCode == HttpStatusCode.Accepted) { pollingState.Status = AzureAsyncOperation.InProgressStatus; } else if (statusCode == HttpStatusCode.OK || (statusCode == HttpStatusCode.Created && method == HttpMethod.Put) || (statusCode == HttpStatusCode.NoContent && (method == HttpMethod.Delete || method == HttpMethod.Post))) { pollingState.Status = AzureAsyncOperation.SuccessStatus; pollingState.Error = new CloudError() { Code = pollingState.Status, Message = string.Format(Resources.LongRunningOperationFailed, pollingState.Status) }; pollingState.Resource = responseWithResource.Body == null ? null : responseWithResource.Body.ToObject <TBody>(JsonSerializer .Create(client.DeserializationSettings)); pollingState.ResourceHeaders = responseWithResource.Headers.ToObject <THeader>(JsonSerializer .Create(client.DeserializationSettings)); } else { throw new CloudException("The response from long running operation does not have a valid status code."); } }
/// <summary> /// Updates PollingState from Location header. /// </summary> /// <typeparam name="TBody">Type of the resource body.</typeparam> /// <typeparam name="THeader">Type of the resource header.</typeparam> /// <param name="client">IAzureClient</param> /// <param name="pollingState">Current polling state.</param> /// <param name="customHeaders">Headers that will be added to request</param> /// <param name="cancellationToken">Cancellation token</param> /// <param name="initialRequestMethod">Http method of the initial long running operation request</param> /// <returns>Task.</returns> private static async Task UpdateStateFromLocationHeader <TBody, THeader>( IAzureClient client, PollingState <TBody, THeader> pollingState, Dictionary <string, List <string> > customHeaders, CancellationToken cancellationToken, HttpMethod initialRequestMethod) where TBody : class where THeader : class { AzureAsyncOperation asyncOperation = null; AzureOperationResponse <JObject, JObject> responseWithResource = await client.GetRawAsync( pollingState.LocationHeaderLink, customHeaders, cancellationToken).ConfigureAwait(false); string responseContent = await responseWithResource.Response.Content.ReadAsStringAsync().ConfigureAwait(false); pollingState.Status = responseWithResource.Response.StatusCode.ToString(); pollingState.Response = responseWithResource.Response; pollingState.Request = responseWithResource.Request; pollingState.Resource = responseWithResource.Body == null ? null : responseWithResource.Body.ToObject <TBody>(JsonSerializer .Create(client.DeserializationSettings)); pollingState.ResourceHeaders = responseWithResource.Headers.ToObject <THeader>(JsonSerializer .Create(client.DeserializationSettings)); // We try to check if the response had status/error returned // the reason we deserialize it as AsyncOperation is simply because we are trying to reuse the AsyncOperation model for deserialization (which has Error, Code and Message model types) // which is how the response is returned // Ideally the response body should be provided as a type TBody, but TBody is a type defined in the swagger and so we cannot provide that type in the constraint hence we end up using a generic // JBody type try { asyncOperation = responseWithResource.Body.ToObject <AzureAsyncOperation>(JsonSerializer.Create(client.DeserializationSettings)); } catch { } pollingState = GetUpdatedPollingStatus <TBody, THeader>(asyncOperation, responseWithResource, pollingState, responseContent, initialRequestMethod); }