internal static IList <TableResult> TableBatchOperationPostProcess(IList <TableResult> result, TableBatchOperation batch, RESTCommand <IList <TableResult> > cmd, HttpWebResponse resp, OperationContext ctx, TableRequestOptions options, string accountName) { ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, cmd.ResponseStream), readerSettings)) { // create a reader ODataBatchReader reader = responseReader.CreateODataBatchReader(); // Initial => changesetstart if (reader.State == ODataBatchReaderState.Initial) { reader.Read(); } if (reader.State == ODataBatchReaderState.ChangesetStart) { // ChangeSetStart => Operation reader.Read(); } int index = 0; bool failError = false; bool failUnexpected = false; while (reader.State == ODataBatchReaderState.Operation) { TableOperation currentOperation = batch[index]; TableResult currentResult = new TableResult() { Result = currentOperation.Entity }; result.Add(currentResult); ODataBatchOperationResponseMessage mimePartResponseMessage = reader.CreateOperationResponseMessage(); string contentType = mimePartResponseMessage.GetHeader(Constants.ContentTypeElement); currentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; // Validate Status Code. if (currentOperation.OperationType == TableOperationType.Insert) { failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.Conflict; if (currentOperation.EchoContent) { failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.Created; } else { failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.NoContent; } } else if (currentOperation.OperationType == TableOperationType.Retrieve) { if (mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound) { index++; // Operation => next reader.Read(); continue; } failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.OK; } else { failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound; failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.NoContent; } if (failError) { // If the parse error is null, then don't get the extended error information and the StorageException will contain SR.ExtendedErrorUnavailable message. if (cmd.ParseError != null) { cmd.CurrentResult.ExtendedErrorInformation = cmd.ParseError(mimePartResponseMessage.GetStream(), resp, contentType); } cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; if (!string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string msg = cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage; cmd.CurrentResult.HttpStatusMessage = msg.Substring(0, msg.IndexOf("\n", StringComparison.Ordinal)); } else { cmd.CurrentResult.HttpStatusMessage = mimePartResponseMessage.StatusCode.ToString(CultureInfo.InvariantCulture); } throw new StorageException( cmd.CurrentResult, cmd.CurrentResult.ExtendedErrorInformation != null ? cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage : SR.ExtendedErrorUnavailable, null) { IsRetryable = false }; } if (failUnexpected) { // If the parse error is null, then don't get the extended error information and the StorageException will contain SR.ExtendedErrorUnavailable message. if (cmd.ParseError != null) { cmd.CurrentResult.ExtendedErrorInformation = cmd.ParseError(mimePartResponseMessage.GetStream(), resp, contentType); } cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; if (!string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string msg = cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage; cmd.CurrentResult.HttpStatusMessage = msg.Substring(0, msg.IndexOf("\n", StringComparison.Ordinal)); } else { cmd.CurrentResult.HttpStatusMessage = mimePartResponseMessage.StatusCode.ToString(CultureInfo.InvariantCulture); } string indexString = Convert.ToString(index, CultureInfo.InvariantCulture); // Attempt to extract index of failing entity from extended error info if (cmd.CurrentResult.ExtendedErrorInformation != null && !string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string tempIndex = TableRequest.ExtractEntityIndexFromExtendedErrorInformation(cmd.CurrentResult); if (!string.IsNullOrEmpty(tempIndex)) { indexString = tempIndex; } } throw new StorageException(cmd.CurrentResult, string.Format(CultureInfo.CurrentCulture, SR.BatchErrorInOperation, indexString), null) { IsRetryable = true }; } // Update etag if (!string.IsNullOrEmpty(mimePartResponseMessage.GetHeader(Constants.HeaderConstants.EtagHeader))) { currentResult.Etag = mimePartResponseMessage.GetHeader(Constants.HeaderConstants.EtagHeader); if (currentOperation.Entity != null) { currentOperation.Entity.ETag = currentResult.Etag; } } // Parse Entity if needed if (currentOperation.OperationType == TableOperationType.Retrieve || (currentOperation.OperationType == TableOperationType.Insert && currentOperation.EchoContent)) { if (mimePartResponseMessage.GetHeader(Constants.ContentTypeElement).Contains(Constants.JsonNoMetadataAcceptHeaderValue)) { ReadEntityUsingJsonParser(currentResult, currentOperation, mimePartResponseMessage.GetStream(), ctx, options); } else { ReadOdataEntity(currentResult, currentOperation, mimePartResponseMessage, ctx, readerSettings, accountName, options); } } else if (currentOperation.OperationType == TableOperationType.Insert) { currentOperation.Entity.Timestamp = ParseETagForTimestamp(currentResult.Etag); } index++; // Operation => reader.Read(); } } return(result); }
internal static IList <TableResult> TableBatchOperationPostProcess(IList <TableResult> result, TableBatchOperation batch, RESTCommand <IList <TableResult> > cmd, HttpWebResponse resp, OperationContext ctx) { ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas = new ODataMessageQuotas() { MaxPartsPerBatch = TableConstants.TableServiceMaxResults, MaxReceivedMessageSize = TableConstants.TableServiceMaxPayload }; using (ODataMessageReader responseReader = new ODataMessageReader(new HttpResponseAdapterMessage(resp, cmd.ResponseStream), readerSettings)) { // create a reader ODataBatchReader reader = responseReader.CreateODataBatchReader(); // Initial => changesetstart if (reader.State == ODataBatchReaderState.Initial) { reader.Read(); } if (reader.State == ODataBatchReaderState.ChangesetStart) { // ChangeSetStart => Operation reader.Read(); } int index = 0; bool failError = false; bool failUnexpected = false; while (reader.State == ODataBatchReaderState.Operation) { TableOperation currentOperation = batch[index]; TableResult currentResult = new TableResult() { Result = currentOperation.Entity }; result.Add(currentResult); ODataBatchOperationResponseMessage mimePartResponseMessage = reader.CreateOperationResponseMessage(); currentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; // Validate Status Code if (currentOperation.OperationType == TableOperationType.Insert) { failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.Conflict; failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.Created; } else if (currentOperation.OperationType == TableOperationType.Retrieve) { if (mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound) { index++; // Operation => next reader.Read(); continue; } failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.OK; } else { failError = mimePartResponseMessage.StatusCode == (int)HttpStatusCode.NotFound; failUnexpected = mimePartResponseMessage.StatusCode != (int)HttpStatusCode.NoContent; } if (failError) { cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; throw new StorageException( cmd.CurrentResult, cmd.CurrentResult.ExtendedErrorInformation != null ? cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage : SR.ExtendedErrorUnavailable, null) { IsRetryable = false }; } if (failUnexpected) { cmd.CurrentResult.ExtendedErrorInformation = StorageExtendedErrorInformation.ReadFromStream(mimePartResponseMessage.GetStream()); cmd.CurrentResult.HttpStatusCode = mimePartResponseMessage.StatusCode; string indexString = Convert.ToString(index); // Attempt to extract index of failing entity from extended error info if (cmd.CurrentResult.ExtendedErrorInformation != null && !string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string tempIndex = TableRequest.ExtractEntityIndexFromExtendedErrorInformation(cmd.CurrentResult); if (!string.IsNullOrEmpty(tempIndex)) { indexString = tempIndex; } } throw new StorageException(cmd.CurrentResult, SR.UnexpectedResponseCodeForOperation + indexString, null) { IsRetryable = true }; } // Update etag if (!string.IsNullOrEmpty(mimePartResponseMessage.GetHeader("ETag"))) { currentResult.Etag = mimePartResponseMessage.GetHeader("ETag"); if (currentOperation.Entity != null) { currentOperation.Entity.ETag = currentResult.Etag; } } // Parse Entity if needed if (currentOperation.OperationType == TableOperationType.Retrieve || currentOperation.OperationType == TableOperationType.Insert) { ReadOdataEntity(currentResult, currentOperation, mimePartResponseMessage, ctx, readerSettings); } index++; // Operation => reader.Read(); } } return(result); }