internal static void StartRequestAttempt <T>(ExecutionState <T> executionState)
        {
            executionState.ExceptionRef      = null;
            executionState.Cmd.CurrentResult = new RequestResult
            {
                StartTime = DateTime.Now
            };
            lock (executionState.OperationContext.RequestResults)
            {
                executionState.OperationContext.RequestResults.Add(executionState.Cmd.CurrentResult);
                executionState.Cmd.RequestResults.Add(executionState.Cmd.CurrentResult);
            }
            RESTCommand <T> restCMD = executionState.RestCMD;

            if (restCMD != null)
            {
                if (!restCMD.StorageUri.ValidateLocationMode(restCMD.LocationMode))
                {
                    throw new InvalidOperationException("The Uri for the target storage location is not specified. Please consider changing the request's location mode.");
                }
                switch (restCMD.CommandLocationMode)
                {
                case CommandLocationMode.PrimaryOnly:
                    if (restCMD.LocationMode == LocationMode.SecondaryOnly)
                    {
                        throw new InvalidOperationException("This operation can only be executed against the primary storage location.");
                    }
                    Logger.LogInformational(executionState.OperationContext, "This operation can only be executed against the primary storage location.");
                    executionState.CurrentLocation = StorageLocation.Primary;
                    restCMD.LocationMode           = LocationMode.PrimaryOnly;
                    break;

                case CommandLocationMode.SecondaryOnly:
                    if (restCMD.LocationMode == LocationMode.PrimaryOnly)
                    {
                        throw new InvalidOperationException("This operation can only be executed against the secondary storage location.");
                    }
                    Logger.LogInformational(executionState.OperationContext, "This operation can only be executed against the secondary storage location.");
                    executionState.CurrentLocation = StorageLocation.Secondary;
                    restCMD.LocationMode           = LocationMode.SecondaryOnly;
                    break;
                }
            }
            executionState.Cmd.CurrentResult.TargetLocation = executionState.CurrentLocation;
        }
Beispiel #2
0
        internal static RESTCommand <ServiceStats> GenerateCMDForGetServiceStats(CloudTableClient client, TableRequestOptions requestOptions)
        {
            RESTCommand <ServiceStats> rESTCommand = new RESTCommand <ServiceStats>(client.Credentials, client.StorageUri);

            RESTCommandGeneratorUtils.ApplyTableRequestOptionsToStorageCommand(requestOptions, rESTCommand);
            rESTCommand.HttpClient = client.HttpClient;
            LocationMode?locationMode = requestOptions.LocationMode;

            if (locationMode.GetValueOrDefault() == LocationMode.PrimaryOnly && (locationMode.HasValue ? true : false))
            {
                throw new InvalidOperationException("GetServiceStats cannot be run with a 'PrimaryOnly' location mode.");
            }
            rESTCommand.CommandLocationMode      = CommandLocationMode.PrimaryOrSecondary;
            rESTCommand.BuildRequest             = ((RESTCommand <ServiceStats> cmd, Uri uri, UriQueryBuilder uriBuilder, HttpContent httpContent, int?timeout, OperationContext ctx) => TableRequestMessageFactory.BuildStorageRequestMessageForGetServiceStats(uri, uriBuilder, timeout, SharedKeyCanonicalizer.Instance, client.Credentials, ctx, requestOptions));
            rESTCommand.ParseErrorAsync          = StorageExtendedErrorInformationRestHelper.ReadExtendedErrorInfoFromStreamAsync;
            rESTCommand.PreProcessResponse       = ((RESTCommand <ServiceStats> cmd, HttpResponseMessage resp, Exception ex, OperationContext ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null, cmd, ex));
            rESTCommand.PostProcessResponseAsync = ((RESTCommand <ServiceStats> cmd, HttpResponseMessage resp, OperationContext ctx, CancellationToken token) => TableOperationHttpResponseParsers.ReadServiceStatsAsync(cmd.ResponseStream));
            return(rESTCommand);
        }
Beispiel #3
0
        internal static RESTCommand <TableBatchResult> GenerateCMDForTableBatchOperation(TableBatchOperation batch, CloudTableClient client, CloudTable table, TableRequestOptions requestOptions)
        {
            RESTCommand <TableBatchResult> rESTCommand = new RESTCommand <TableBatchResult>(client.Credentials, client.StorageUri);

            RESTCommandGeneratorUtils.ApplyTableRequestOptionsToStorageCommand(requestOptions, rESTCommand);
            rESTCommand.HttpClient = client.HttpClient;
            TableBatchResult results = new TableBatchResult();

            rESTCommand.CommandLocationMode      = ((!batch.ContainsWrites) ? CommandLocationMode.PrimaryOrSecondary : CommandLocationMode.PrimaryOnly);
            rESTCommand.CommandLocationMode      = CommandLocationMode.PrimaryOnly;
            rESTCommand.ParseErrorAsync          = StorageExtendedErrorInformationRestHelper.ReadExtendedErrorInfoFromStreamAsync;
            rESTCommand.BuildRequest             = ((RESTCommand <TableBatchResult> cmd, Uri uri, UriQueryBuilder builder, HttpContent httpContent, int?timeout, OperationContext ctx) => TableRequestMessageFactory.BuildStorageRequestMessageForTableBatchOperation(uri, batch, SharedKeyCanonicalizer.Instance, table.Name, client.Credentials, ctx, requestOptions));
            rESTCommand.PreProcessResponse       = ((RESTCommand <TableBatchResult> cmd, HttpResponseMessage resp, Exception ex, OperationContext ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp?.StatusCode ?? HttpStatusCode.Unused, results, cmd, ex));
            rESTCommand.PostProcessResponseAsync = ((RESTCommand <TableBatchResult> cmd, HttpResponseMessage resp, OperationContext ctx, CancellationToken token) => TableOperationHttpResponseParsers.TableBatchOperationPostProcessAsync(results, batch, cmd, resp, ctx, requestOptions, client.Credentials.AccountName, token));
            rESTCommand.RecoveryAction           = delegate
            {
                results.Clear();
            };
            return(rESTCommand);
        }
Beispiel #4
0
        public ExecutionState(RESTCommand <T> cmd, IRetryPolicy policy, OperationContext operationContext)
        {
            Cmd = cmd;
            object retryPolicy2;

            if (policy == null)
            {
                IRetryPolicy retryPolicy = new NoRetry();
                retryPolicy2 = retryPolicy;
            }
            else
            {
                retryPolicy2 = policy.CreateInstance();
            }
            RetryPolicy      = (IRetryPolicy)retryPolicy2;
            OperationContext = (operationContext ?? new OperationContext());
            InitializeLocation();
            if (OperationContext.StartTime == DateTimeOffset.MinValue)
            {
                OperationContext.StartTime = DateTimeOffset.Now;
            }
        }
        private static void ProcessStartOfRequest <T>(ExecutionState <T> executionState, string startLogMessage, CancellationTokenSource timeoutTokenSource = null)
        {
            RESTCommand <T> restCMD = executionState.RestCMD;

            executionState.CurrentOperation = ExecutorOperation.BeginOperation;
            HttpContent arg  = (restCMD.BuildContent != null) ? restCMD.BuildContent(restCMD, executionState.OperationContext) : null;
            Uri         uri  = restCMD.StorageUri.GetUri(executionState.CurrentLocation);
            Uri         uri2 = restCMD.Credentials.TransformUri(uri);

            Logger.LogInformational(executionState.OperationContext, "Starting asynchronous request to {0}.", uri2);
            UriQueryBuilder arg2 = new UriQueryBuilder(executionState.RestCMD.Builder);

            executionState.Req = restCMD.BuildRequest(restCMD, uri2, arg2, arg, restCMD.ServerTimeoutInSeconds, executionState.OperationContext);
            ExecutionStateUtils.ApplyUserHeaders(executionState);
            ExecutionStateUtils.FireSendingRequest(executionState);
            if (executionState.OperationExpiryTime.HasValue)
            {
                timeoutTokenSource?.CancelAfter(executionState.RemainingTimeout);
            }
            else
            {
                timeoutTokenSource?.CancelAfter(int.MaxValue);
            }
        }
        public static async Task <T> ExecuteAsync <T>(RESTCommand <T> cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token)
        {
            using (ExecutionState <T> executionState = new ExecutionState <T>(cmd, policy, operationContext))
            {
                using (CancellationTokenSource timeoutTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token))
                {
                    CancellationToken timeoutToken = timeoutTokenSource.Token;
                    bool       shouldRetry         = false;
                    TimeSpan   delay  = TimeSpan.Zero;
                    HttpClient client = cmd.HttpClient ?? HttpClientFactory.Instance;
                    do
                    {
                        try
                        {
                            executionState.Init();
                            ExecutionStateUtils.StartRequestAttempt(executionState);
                            ProcessStartOfRequest(executionState, "Starting asynchronous request to {0}.", timeoutTokenSource);
                            ExecutionStateUtils.CheckTimeout(executionState, throwOnTimeout: true);
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError(executionState.OperationContext, "Exception thrown while initializing request: {0}.", ex.Message);
                            StorageException ex2 = await ExecutionStateUtils.TranslateExceptionBasedOnParseErrorAsync(ex, executionState.Cmd.CurrentResult, executionState.Resp, executionState.Cmd.ParseErrorAsync, timeoutToken).ConfigureAwait(continueOnCapturedContext: false);

                            ex2.IsRetryable             = false;
                            executionState.ExceptionRef = ex2;
                            throw executionState.ExceptionRef;
                        }
                        try
                        {
                            executionState.CurrentOperation = ExecutorOperation.BeginGetResponse;
                            Logger.LogInformational(executionState.OperationContext, "Waiting for response.");
                            ExecutionState <T> executionState2 = executionState;
                            executionState2.Resp = await client.SendAsync(executionState.Req, HttpCompletionOption.ResponseHeadersRead, timeoutToken).ConfigureAwait(continueOnCapturedContext: false);

                            executionState.CurrentOperation = ExecutorOperation.EndGetResponse;
                            if (!executionState.Resp.IsSuccessStatusCode)
                            {
                                executionState2 = executionState;
                                executionState2.ExceptionRef = await StorageExceptionTranslator.PopulateStorageExceptionFromHttpResponseMessage(executionState.Resp, executionState.Cmd.CurrentResult, timeoutToken, executionState.Cmd.ParseErrorAsync).ConfigureAwait(continueOnCapturedContext: false);
                            }
                            Logger.LogInformational(executionState.OperationContext, "Response received. Status code = {0}, Request ID = {1}, Content-MD5 = {2}, ETag = {3}.", executionState.Cmd.CurrentResult.HttpStatusCode, executionState.Cmd.CurrentResult.ServiceRequestID, executionState.Cmd.CurrentResult.ContentMd5, executionState.Cmd.CurrentResult.Etag);
                            ExecutionStateUtils.FireResponseReceived(executionState);
                            if (cmd.PreProcessResponse != null)
                            {
                                executionState.CurrentOperation = ExecutorOperation.PreProcess;
                                try
                                {
                                    executionState.Result       = cmd.PreProcessResponse(cmd, executionState.Resp, executionState.ExceptionRef, executionState.OperationContext);
                                    executionState.ExceptionRef = null;
                                }
                                catch (Exception exceptionRef)
                                {
                                    executionState.ExceptionRef = exceptionRef;
                                }
                                Logger.LogInformational(executionState.OperationContext, "Response headers were processed successfully, proceeding with the rest of the operation.");
                            }
                            executionState.CurrentOperation = ExecutorOperation.GetResponseStream;
                            cmd.ResponseStream = new MemoryStream();
                            await(await executionState.Resp.Content.ReadAsStreamAsync()).WriteToAsync(cmd.ResponseStream, executionState, timeoutTokenSource.Token);
                            cmd.ResponseStream.Position = 0L;
                            if (executionState.ExceptionRef != null)
                            {
                                executionState.CurrentOperation = ExecutorOperation.BeginDownloadResponse;
                                Logger.LogInformational(executionState.OperationContext, "Downloading error response body.");
                                try
                                {
                                    executionState2 = executionState;
                                    executionState2.ExceptionRef = await StorageExceptionTranslator.TranslateExceptionWithPreBufferedStreamAsync(executionState.ExceptionRef, executionState.Cmd.CurrentResult, cmd.ResponseStream, executionState.Resp, executionState.Cmd.ParseErrorAsync, timeoutToken);

                                    throw executionState.ExceptionRef;
                                }
                                finally
                                {
                                    cmd.ResponseStream.Dispose();
                                    cmd.ResponseStream = null;
                                }
                            }
                            await ProcessEndOfRequestAsync(executionState, timeoutToken).ConfigureAwait(continueOnCapturedContext: false);

                            ExecutionStateUtils.FinishRequestAttempt(executionState);
                            return(executionState.Result);
                        }
                        catch (Exception ex3)
                        {
                            Exception ex4 = ex3;
                            Logger.LogWarning(executionState.OperationContext, "Exception thrown during the operation: {0}.", ex4.Message);
                            ExecutionStateUtils.FinishRequestAttempt(executionState);
                            if (ex4 is OperationCanceledException && executionState.OperationExpiryTime.HasValue && DateTime.Now.CompareTo(executionState.OperationExpiryTime.Value) > 0)
                            {
                                ex4 = new TimeoutException("The client could not finish the operation within specified timeout.", ex4);
                            }
                            Exception ex6 = executionState.ExceptionRef = await ExecutionStateUtils.TranslateExceptionBasedOnParseErrorAsync(ex4, executionState.Cmd.CurrentResult, executionState.Resp, executionState.Cmd.ParseErrorAsync, timeoutToken).ConfigureAwait(continueOnCapturedContext: false);

                            Logger.LogInformational(executionState.OperationContext, "Checking if the operation should be retried. Retry count = {0}, HTTP status code = {1}, Retryable exception = {2}, Exception = {3}.", executionState.RetryCount, executionState.Cmd.CurrentResult.HttpStatusCode, ((StorageException)ex6).IsRetryable ? "yes" : "no", ex6.Message);
                            shouldRetry = false;
                            if (((StorageException)ex6).IsRetryable && executionState.RetryPolicy != null)
                            {
                                executionState.CurrentLocation = ExecutionStateUtils.GetNextLocation(executionState.CurrentLocation, cmd.LocationMode);
                                Logger.LogInformational(executionState.OperationContext, "The next location has been set to {0}, based on the location mode.", executionState.CurrentLocation);
                                IExtendedRetryPolicy extendedRetryPolicy = executionState.RetryPolicy as IExtendedRetryPolicy;
                                if (extendedRetryPolicy != null)
                                {
                                    RetryInfo retryInfo = extendedRetryPolicy.Evaluate(new RetryContext(executionState.RetryCount++, cmd.CurrentResult, executionState.CurrentLocation, cmd.LocationMode), executionState.OperationContext);
                                    if (retryInfo != null)
                                    {
                                        Logger.LogInformational(executionState.OperationContext, "The extended retry policy set the next location to {0} and updated the location mode to {1}.", retryInfo.TargetLocation, retryInfo.UpdatedLocationMode);
                                        shouldRetry = true;
                                        executionState.CurrentLocation = retryInfo.TargetLocation;
                                        cmd.LocationMode = retryInfo.UpdatedLocationMode;
                                        delay            = retryInfo.RetryInterval;
                                    }
                                }
                                else
                                {
                                    shouldRetry = executionState.RetryPolicy.ShouldRetry(executionState.RetryCount++, cmd.CurrentResult.HttpStatusCode, executionState.ExceptionRef, out delay, executionState.OperationContext);
                                }
                                if (delay < TimeSpan.Zero || delay > TableRestConstants.MaximumRetryBackoff)
                                {
                                    delay = TableRestConstants.MaximumRetryBackoff;
                                }
                            }
                        }
                        finally
                        {
                            if (executionState.Resp != null)
                            {
                                executionState.Resp.Dispose();
                                executionState.Resp = null;
                            }
                        }
                        if (!shouldRetry || (executionState.OperationExpiryTime.HasValue && (DateTime.Now + delay).CompareTo(executionState.OperationExpiryTime.Value) > 0))
                        {
                            Logger.LogError(executionState.OperationContext, shouldRetry ? "Operation cannot be retried because the maximum execution time has been reached. Failing with {0}." : "Retry policy did not allow for a retry. Failing with {0}.", executionState.ExceptionRef.Message);
                            throw executionState.ExceptionRef;
                        }
                        cmd.RecoveryAction?.Invoke(cmd, executionState.Cmd.CurrentResult.Exception, executionState.OperationContext);
                        if (delay > TimeSpan.Zero)
                        {
                            await Task.Delay(delay, timeoutToken).ConfigureAwait(continueOnCapturedContext: false);
                        }
                        Logger.LogInformational(executionState.OperationContext, "Retrying failed operation.");
                        ExecutionStateUtils.FireRetrying(executionState);
                    }while (shouldRetry);
                    throw new NotImplementedException("Unexpected internal storage client error.");
                }
            }
        }
        internal static async Task <TableResult> TableOperationPostProcessAsync(TableResult result, TableOperation operation, RESTCommand <TableResult> cmd, HttpResponseMessage resp, OperationContext ctx, TableRequestOptions options, string accountName, CancellationToken cancellationToken)
        {
            string text = (resp.Headers.ETag != null) ? resp.Headers.ETag.ToString() : null;

            if (operation.OperationType != TableOperationType.Retrieve && operation.OperationType != 0)
            {
                result.Etag           = text;
                operation.Entity.ETag = result.Etag;
            }
            else if (operation.OperationType == TableOperationType.Insert && !operation.EchoContent)
            {
                if (text != null)
                {
                    result.Etag                = text;
                    operation.Entity.ETag      = result.Etag;
                    operation.Entity.Timestamp = ParseETagForTimestamp(result.Etag);
                }
            }
            else
            {
                MediaTypeHeaderValue contentType = resp.Content.Headers.ContentType;
                if (!contentType.MediaType.Equals("application/json") || !contentType.Parameters.Contains(NameValueHeaderValue.Parse("odata=nometadata")))
                {
                    await ReadOdataEntityAsync(result, operation, cmd.ResponseStream, ctx, accountName, options, cancellationToken);
                }
                else
                {
                    result.Etag = text;
                    await ReadEntityUsingJsonParserAsync(result, operation, cmd.ResponseStream, ctx, options, cancellationToken);
                }
            }
            return(result);
        }
        internal static async Task <TableBatchResult> TableBatchOperationPostProcessAsync(TableBatchResult result, TableBatchOperation batch, RESTCommand <TableBatchResult> cmd, HttpResponseMessage resp, OperationContext ctx, TableRequestOptions options, string accountName, CancellationToken cancellationToken)
        {
            Stream       responseStream = cmd.ResponseStream;
            StreamReader streamReader   = new StreamReader(responseStream);
            await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);

            string currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);

            int  index     = 0;
            bool failError = false;

            while (currentLine3 != null && !currentLine3.StartsWith("--batchresponse"))
            {
                while (!currentLine3.StartsWith("HTTP"))
                {
                    currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);
                }
                int statusCode = int.Parse(currentLine3.Substring(9, 3));
                Dictionary <string, string> headers = new Dictionary <string, string>();
                currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);

                while (!string.IsNullOrWhiteSpace(currentLine3))
                {
                    int num = currentLine3.IndexOf(':');
                    headers[currentLine3.Substring(0, num)] = currentLine3.Substring(num + 2);
                    currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);
                }
                MemoryStream bodyStream = null;
                currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);

                if (statusCode != 204)
                {
                    bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(currentLine3));
                }
                await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);

                currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false);

                TableOperation tableOperation = batch[index];
                TableResult    obj            = new TableResult
                {
                    Result = tableOperation.Entity
                };
                result.Add(obj);
                string arg = null;
                if (headers.ContainsKey("Content-Type"))
                {
                    arg = headers["Content-Type"];
                }
                obj.HttpStatusCode = statusCode;
                bool flag;
                if (tableOperation.OperationType == TableOperationType.Insert)
                {
                    failError = (statusCode == 409);
                    flag      = ((!tableOperation.EchoContent) ? (statusCode != 204) : (statusCode != 201));
                }
                else if (tableOperation.OperationType == TableOperationType.Retrieve)
                {
                    if (statusCode == 404)
                    {
                        index++;
                        continue;
                    }
                    flag = (statusCode != 200);
                }
                else
                {
                    failError = (statusCode == 404);
                    flag      = (statusCode != 204);
                }
                if (failError)
                {
                    if (cmd.ParseErrorAsync != null)
                    {
                        cmd.CurrentResult.ExtendedErrorInformation = cmd.ParseErrorAsync(bodyStream, resp, arg, CancellationToken.None).Result;
                    }
                    cmd.CurrentResult.HttpStatusCode = statusCode;
                    if (!string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage))
                    {
                        string errorMessage = cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage;
                        cmd.CurrentResult.HttpStatusMessage = errorMessage.Substring(0, errorMessage.IndexOf("\n", StringComparison.Ordinal));
                    }
                    else
                    {
                        cmd.CurrentResult.HttpStatusMessage = statusCode.ToString(CultureInfo.InvariantCulture);
                    }
                    throw new StorageException(cmd.CurrentResult, (cmd.CurrentResult.ExtendedErrorInformation != null) ? cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage : "An unknown error has occurred, extended error information not available.", null)
                          {
                              IsRetryable = false
                          };
                }
                if (flag)
                {
                    if (cmd.ParseErrorAsync != null)
                    {
                        cmd.CurrentResult.ExtendedErrorInformation = cmd.ParseErrorAsync(bodyStream, resp, arg, CancellationToken.None).Result;
                    }
                    cmd.CurrentResult.HttpStatusCode = statusCode;
                    if (!string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage))
                    {
                        string errorMessage2 = cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage;
                        cmd.CurrentResult.HttpStatusMessage = errorMessage2.Substring(0, errorMessage2.IndexOf("\n", StringComparison.Ordinal));
                    }
                    else
                    {
                        cmd.CurrentResult.HttpStatusMessage = statusCode.ToString(CultureInfo.InvariantCulture);
                    }
                    string arg2 = Convert.ToString(index, CultureInfo.InvariantCulture);
                    if (cmd.CurrentResult.ExtendedErrorInformation != null && !string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage))
                    {
                        string text = ExtractEntityIndexFromExtendedErrorInformation(cmd.CurrentResult);
                        if (!string.IsNullOrEmpty(text))
                        {
                            arg2 = text;
                        }
                    }
                    throw new StorageException(cmd.CurrentResult, string.Format(CultureInfo.CurrentCulture, "Element {0} in the batch returned an unexpected response code.", arg2), null)
                          {
                              IsRetryable = true
                          };
                }
                if (headers.ContainsKey("ETag") && !string.IsNullOrEmpty(headers["ETag"]))
                {
                    obj.Etag = headers["ETag"];
                    if (tableOperation.Entity != null)
                    {
                        tableOperation.Entity.ETag = obj.Etag;
                    }
                }
                if (tableOperation.OperationType == TableOperationType.Retrieve || (tableOperation.OperationType == TableOperationType.Insert && tableOperation.EchoContent))
                {
                    if (!headers["Content-Type"].Contains("application/json;odata=nometadata"))
                    {
                        await ReadOdataEntityAsync(obj, tableOperation, bodyStream, ctx, accountName, options, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
                    }
                    else
                    {
                        await ReadEntityUsingJsonParserAsync(obj, tableOperation, bodyStream, ctx, options, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
                    }
                }
                else if (tableOperation.OperationType == TableOperationType.Insert)
                {
                    tableOperation.Entity.Timestamp = ParseETagForTimestamp(obj.Etag);
                }
                index++;
            }
            return(result);
        }
 internal static T ProcessExpectedStatusCodeNoException <T>(HttpStatusCode[] expectedStatusCodes, HttpStatusCode actualStatusCode, T retVal, RESTCommand <T> cmd, Exception ex)
 {
     if (ex != null)
     {
         throw ex;
     }
     if (!expectedStatusCodes.Contains(actualStatusCode))
     {
         string arg = string.Join(",", expectedStatusCodes);
         throw new StorageException(cmd.CurrentResult, string.Format(CultureInfo.InvariantCulture, "Unexpected response code, Expected:{0}, Received:{1}", arg, actualStatusCode.ToString()), null);
     }
     return(retVal);
 }
 internal static T ProcessExpectedStatusCodeNoException <T>(HttpStatusCode expectedStatusCode, HttpStatusCode actualStatusCode, T retVal, RESTCommand <T> cmd, Exception ex)
 {
     if (ex != null)
     {
         throw ex;
     }
     if (actualStatusCode != expectedStatusCode)
     {
         throw new StorageException(cmd.CurrentResult, string.Format(CultureInfo.InvariantCulture, "Unexpected response code, Expected:{0}, Received:{1}", expectedStatusCode, actualStatusCode), null);
     }
     return(retVal);
 }
 internal static T ProcessExpectedStatusCodeNoException <T>(HttpStatusCode[] expectedStatusCodes, HttpResponseMessage resp, T retVal, RESTCommand <T> cmd, Exception ex)
 {
     return(ProcessExpectedStatusCodeNoException(expectedStatusCodes, resp?.StatusCode ?? HttpStatusCode.Unused, retVal, cmd, ex));
 }
 internal static void ApplyTableRequestOptionsToStorageCommand <T>(TableRequestOptions options, RESTCommand <T> cmd)
 {
     if (options.LocationMode.HasValue)
     {
         cmd.LocationMode = options.LocationMode.Value;
     }
     if (options.ServerTimeout.HasValue)
     {
         cmd.ServerTimeoutInSeconds = (int)options.ServerTimeout.Value.TotalSeconds;
     }
     if (options.OperationExpiryTime.HasValue)
     {
         cmd.OperationExpiryTime = options.OperationExpiryTime;
     }
     else if (options.MaximumExecutionTime.HasValue)
     {
         cmd.OperationExpiryTime = DateTime.Now + options.MaximumExecutionTime.Value;
     }
 }