/// <summary> /// Initializes a new instance of the <see cref="PartitionKeyRangeBatchResponse"/> class. /// </summary> /// <param name="originalOperationsCount">Original operations that generated the server responses.</param> /// <param name="serverResponse">Response from the server.</param> /// <param name="serializer">Serializer to deserialize response resource body streams.</param> internal PartitionKeyRangeBatchResponse( int originalOperationsCount, BatchResponse serverResponse, CosmosSerializer serializer) { this.StatusCode = serverResponse.StatusCode; this.ServerResponse = serverResponse; this.resultsByOperationIndex = new BatchOperationResult[originalOperationsCount]; StringBuilder errorMessageBuilder = new StringBuilder(); List <string> activityIds = new List <string>(); List <ItemBatchOperation> itemBatchOperations = new List <ItemBatchOperation>(); // We expect number of results == number of operations here for (int index = 0; index < serverResponse.Operations.Count; index++) { int operationIndex = serverResponse.Operations[index].OperationIndex; if (this.resultsByOperationIndex[operationIndex] == null || this.resultsByOperationIndex[operationIndex].StatusCode == (HttpStatusCode)StatusCodes.TooManyRequests) { this.resultsByOperationIndex[operationIndex] = serverResponse[index]; } } itemBatchOperations.AddRange(serverResponse.Operations); this.RequestCharge += serverResponse.RequestCharge; if (!string.IsNullOrEmpty(serverResponse.ErrorMessage)) { errorMessageBuilder.AppendFormat("{0}; ", serverResponse.ErrorMessage); } this.ActivityId = serverResponse.ActivityId; this.ErrorMessage = errorMessageBuilder.Length > 2 ? errorMessageBuilder.ToString(0, errorMessageBuilder.Length - 2) : null; this.Operations = itemBatchOperations; this.Serializer = serializer; }
internal static async Task <BatchResponse> FromResponseMessageAsync( ResponseMessage responseMessage, ServerBatchRequest serverRequest, CosmosSerializer serializer) { using (responseMessage) { BatchResponse response = null; if (responseMessage.IsSuccessStatusCode && responseMessage.Content != null) { response = await BatchResponse.PopulateFromContentAsync(responseMessage, serverRequest, serializer); if (response == null) { // Convert any payload read failures as InternalServerError response = new BatchResponse( HttpStatusCode.InternalServerError, SubStatusCodes.Unknown, ClientResources.ServerResponseDeserializationFailure, responseMessage.Headers.RequestCharge, responseMessage.Headers.RetryAfter, responseMessage.Headers.ActivityId, serverRequest, serializer); } } else { response = new BatchResponse( responseMessage.StatusCode, responseMessage.Headers.SubStatusCode, responseMessage.ErrorMessage, responseMessage.Headers.RequestCharge, responseMessage.Headers.RetryAfter, responseMessage.Headers.ActivityId, serverRequest, serializer); } if (response.results == null || response.results.Count != serverRequest.Operations.Count) { if (responseMessage.IsSuccessStatusCode) { // Server should be guaranteeing number of results equal to operations when // batch request is successful - so fail as InternalServerError if this is not the case. response = new BatchResponse( HttpStatusCode.InternalServerError, SubStatusCodes.Unknown, ClientResources.InvalidServerResponse, responseMessage.Headers.RequestCharge, responseMessage.Headers.RetryAfter, responseMessage.Headers.ActivityId, serverRequest, serializer); } // When the overall response status code is TooManyRequests, propagate the RetryAfter into the individual operations. int retryAfterMilliseconds = 0; if ((int)responseMessage.StatusCode == (int)StatusCodes.TooManyRequests) { if (!responseMessage.Headers.TryGetValue(HttpConstants.HttpHeaders.RetryAfterInMilliseconds, out string retryAfter) || retryAfter == null || !int.TryParse(retryAfter, out retryAfterMilliseconds)) { retryAfterMilliseconds = 0; } } response.results = new List <BatchOperationResult>(); for (int i = 0; i < serverRequest.Operations.Count; i++) { response.results.Add( new BatchOperationResult(response.StatusCode) { SubStatusCode = response.SubStatusCode, RetryAfter = TimeSpan.FromMilliseconds(retryAfterMilliseconds), }); } } return(response); } }