public static void ParseBatchResponse(BatchResponse response) { string contentType = response.ContentType; string[] pieces = contentType.Split(new string[] { "; boundary=" }, StringSplitOptions.None); if (pieces.Length < 2) AstoriaTestLog.FailAndThrow(String.Format("Could not retrieve boundary from response's content-type header. Value found was '{0}'", contentType)); string boundary = pieces[1].Trim(); // even if content-id is specified, we may not get it back in error cases. This doesn't feel entirely correct, it seems like there should // always be a 1-1 mapping that explicitly honors content-id's // TODO: responses / requests without content IDs should be matched up in order within changeset only // changesets should have the right number of responses too BatchRequest batchRequest = response.Request as BatchRequest; List<ResponseFragment> unmatchedFragments = new List<ResponseFragment>(); List<AstoriaRequest> unmatchedRequests = batchRequest.Requests .Union(batchRequest.Changesets.SelectMany(changeset => changeset.AsEnumerable())) .ToList(); using (StringReader reader = new StringReader(response.Payload)) { foreach (ResponseFragment fragment in ParseBatchResponse(reader, boundary)) { AstoriaRequest request = null; if (fragment.ContentID != null) request = unmatchedRequests .FirstOrDefault(r => r.Headers.ContainsKey("Content-ID") && r.Headers["Content-ID"].Equals(fragment.ContentID)); if (request == null) unmatchedFragments.Add(fragment); else { unmatchedRequests.Remove(request); response.Responses.Add(FragmentToResponse(request, fragment)); } } } if (unmatchedFragments.Any()) { if (unmatchedFragments.Count < unmatchedRequests.Count) AstoriaTestLog.WriteLine("Warning: recieved fewer batch response fragments than expected"); else if (unmatchedFragments.Count > unmatchedRequests.Count) AstoriaTestLog.FailAndThrow("Recieved more batch fragments than expected"); for (int i = 0; i < unmatchedFragments.Count; i++) { response.Responses.Add(FragmentToResponse(unmatchedRequests[i], unmatchedFragments[i])); } } }
public virtual AstoriaResponse GetResponse() { LogRequest(); OnSend(this); // NOTHING should come in between this and actually sending the request #if !ClientSKUFramework SetupAPICallLog(); #endif AstoriaResponse response; if (AstoriaTestProperties.BatchAllRequests) { BatchRequest batchRequest = new BatchRequest(Workspace); if (Verb_Internal == RequestVerb.Get) { batchRequest.Add(this); } else { BatchChangeset changeset = batchRequest.GetChangeset(); changeset.Add(this); } BatchResponse batchResponse = batchRequest.GetResponse() as BatchResponse; response = batchResponse.Responses.FirstOrDefault(); } else { response = RequestSender.SendRequest(this); } #if !ClientSKUFramework // NOTHING should come in between this and actually recieving the response RetrieveAPICallLog(); #endif OnReceive(this, response); return(response); }
public static void ParseBatchResponse(BatchResponse response) { string contentType = response.ContentType; string[] pieces = contentType.Split(new string[] { "; boundary=" }, StringSplitOptions.None); if (pieces.Length < 2) { AstoriaTestLog.FailAndThrow(String.Format("Could not retrieve boundary from response's content-type header. Value found was '{0}'", contentType)); } string boundary = pieces[1].Trim(); // even if content-id is specified, we may not get it back in error cases. This doesn't feel entirely correct, it seems like there should // always be a 1-1 mapping that explicitly honors content-id's // TODO: responses / requests without content IDs should be matched up in order within changeset only // changesets should have the right number of responses too BatchRequest batchRequest = response.Request as BatchRequest; List <ResponseFragment> unmatchedFragments = new List <ResponseFragment>(); List <AstoriaRequest> unmatchedRequests = batchRequest.Requests .Union(batchRequest.Changesets.SelectMany(changeset => changeset.AsEnumerable())) .ToList(); using (StringReader reader = new StringReader(response.Payload)) { foreach (ResponseFragment fragment in ParseBatchResponse(reader, boundary)) { AstoriaRequest request = null; if (fragment.ContentID != null) { request = unmatchedRequests .FirstOrDefault(r => r.Headers.ContainsKey("Content-ID") && r.Headers["Content-ID"].Equals(fragment.ContentID)); } if (request == null) { unmatchedFragments.Add(fragment); } else { unmatchedRequests.Remove(request); response.Responses.Add(FragmentToResponse(request, fragment)); } } } if (unmatchedFragments.Any()) { if (unmatchedFragments.Count < unmatchedRequests.Count) { AstoriaTestLog.WriteLine("Warning: recieved fewer batch response fragments than expected"); } else if (unmatchedFragments.Count > unmatchedRequests.Count) { AstoriaTestLog.FailAndThrow("Recieved more batch fragments than expected"); } for (int i = 0; i < unmatchedFragments.Count; i++) { response.Responses.Add(FragmentToResponse(unmatchedRequests[i], unmatchedFragments[i])); } } }