private async Task ExecuteChangeSet(
            ChangeSetRequestItem changeSet,
            IList<ODataBatchResponseItem> responses,
            CancellationToken cancellation)
        {
            ChangeSetResponseItem changeSetResponse;

            // Create a new ShoppingContext instance, associate it with each of the requests, start a new
            // transaction, execute the changeset and then commit or rollback the transaction depending on
            // whether the responses were all successful or not.
            using (ShoppingContext context = new ShoppingContext())
            {
                foreach (HttpRequestMessage request in changeSet.Requests)
                {
                    request.SetContext(context);
                }

                using (DbContextTransaction transaction = context.Database.BeginTransaction())
                {
                    changeSetResponse = (ChangeSetResponseItem)await changeSet.SendRequestAsync(Invoker, cancellation);
                    responses.Add(changeSetResponse);

                    if (changeSetResponse.Responses.All(r => r.IsSuccessStatusCode))
                    {
                        transaction.Commit();
                    }
                    else
                    {
                        transaction.Rollback();
                    }
                }
            }
        }
        public void SendRequestAsync_ReturnsSingleErrorResponse()
        {
            HttpRequestMessage[] requests = new HttpRequestMessage[]
                {
                    new HttpRequestMessage(HttpMethod.Get, "http://example.com"),
                    new HttpRequestMessage(HttpMethod.Post, "http://example.com"),
                    new HttpRequestMessage(HttpMethod.Put, "http://example.com")
                };
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(requests);

            Mock<HttpMessageInvoker> invoker = new Mock<HttpMessageInvoker>(new HttpServer());
            invoker.Setup(i => i.SendAsync(It.IsAny<HttpRequestMessage>(), CancellationToken.None))
                .Returns<HttpRequestMessage, CancellationToken>((req, c) =>
                {
                    if (req.Method == HttpMethod.Post)
                    {
                        return Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest));
                    }
                    return Task.FromResult(new HttpResponseMessage());
                });

            var response = requestItem.SendRequestAsync(invoker.Object, CancellationToken.None).Result;

            var changesetResponse = Assert.IsType<ChangeSetResponseItem>(response);
            Assert.Equal(1, changesetResponse.Responses.Count());
            Assert.Equal(HttpStatusCode.BadRequest, changesetResponse.Responses.First().StatusCode);
        }
        public void Parameter_Constructor()
        {
            HttpRequestMessage[] requests = new HttpRequestMessage[0];
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(requests);

            Assert.Same(requests, requestItem.Requests);
        }
        public void SendRequestAsync_DisposesResponseInCaseOfException()
        {
            List<MockHttpResponseMessage> responses = new List<MockHttpResponseMessage>();
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(new HttpRequestMessage[]
            {
                new HttpRequestMessage(HttpMethod.Get, "http://example.com"),
                new HttpRequestMessage(HttpMethod.Post, "http://example.com"),
                new HttpRequestMessage(HttpMethod.Put, "http://example.com")
            });
            Mock<HttpMessageInvoker> invoker = new Mock<HttpMessageInvoker>(new HttpServer());
            invoker.Setup(i => i.SendAsync(It.IsAny<HttpRequestMessage>(), CancellationToken.None))
                .Returns<HttpRequestMessage, CancellationToken>((req, cancel) =>
                {
                    if (req.Method == HttpMethod.Put)
                    {
                        throw new InvalidOperationException();
                    }
                    var response = new MockHttpResponseMessage();
                    responses.Add(response);
                    return Task.FromResult<HttpResponseMessage>(response);
                });

            Assert.Throws<InvalidOperationException>(
                () => requestItem.SendRequestAsync(invoker.Object, CancellationToken.None).Result);

            Assert.Equal(2, responses.Count);
            foreach (var response in responses)
            {
                Assert.True(response.IsDisposed);
            }
        }
        public void SendRequestAsync_NullInvoker_Throws()
        {
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(new HttpRequestMessage[0]);

            Assert.ThrowsArgumentNull(
                () => requestItem.SendRequestAsync(null, CancellationToken.None).Wait(),
                "invoker");
        }
		public BatchChangeSetRequestItem(ChangeSetRequestItem copy, HttpRequestMessage parentRequest)
			: base(copy.Requests)
		{
			Contract.Requires<ArgumentNullException>(parentRequest != null);

			_parentRequest = parentRequest;
			_changeSetContext = new ChangeSetContext();
		}
Example #7
0
        /// <summary>
        /// Executes the ChangeSet.
        /// </summary>
        /// <param name="batchReader">The batch reader.</param>
        /// <param name="batchId">The batch id.</param>
        /// <param name="originalRequest">The original request containing all the batch requests.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        /// <returns>The response for the ChangeSet.</returns>
        public virtual async Task <ODataBatchResponseItem> ExecuteChangeSetAsync(ODataBatchReader batchReader, Guid batchId, HttpRequestMessage originalRequest, CancellationToken cancellationToken)
        {
            if (batchReader == null)
            {
                throw Error.ArgumentNull("batchReader");
            }
            if (originalRequest == null)
            {
                throw Error.ArgumentNull("originalRequest");
            }

            Guid changeSetId = Guid.NewGuid();
            List <HttpResponseMessage>  changeSetResponse          = new List <HttpResponseMessage>();
            Dictionary <string, string> contentIdToLocationMapping = new Dictionary <string, string>();

            try
            {
                while (batchReader.Read() && batchReader.State != ODataBatchReaderState.ChangesetEnd)
                {
                    if (batchReader.State == ODataBatchReaderState.Operation)
                    {
                        HttpRequestMessage changeSetOperationRequest = await batchReader.ReadChangeSetOperationRequestAsync(batchId, changeSetId, bufferContentStream : false);

                        changeSetOperationRequest.CopyBatchRequestProperties(originalRequest);
                        try
                        {
                            HttpResponseMessage response = await ODataBatchRequestItem.SendMessageAsync(Invoker, changeSetOperationRequest, cancellationToken, contentIdToLocationMapping);

                            if (response.IsSuccessStatusCode)
                            {
                                changeSetResponse.Add(response);
                            }
                            else
                            {
                                ChangeSetRequestItem.DisposeResponses(changeSetResponse);
                                changeSetResponse.Clear();
                                changeSetResponse.Add(response);
                                return(new ChangeSetResponseItem(changeSetResponse));
                            }
                        }
                        finally
                        {
                            originalRequest.RegisterForDispose(changeSetOperationRequest.GetResourcesForDisposal());
                            originalRequest.RegisterForDispose(changeSetOperationRequest);
                        }
                    }
                }
            }
            catch
            {
                ChangeSetRequestItem.DisposeResponses(changeSetResponse);
                throw;
            }

            return(new ChangeSetResponseItem(changeSetResponse));
        }
        public void GetResourcesForDisposal_ReturnsResourcesRegisteredForDispose()
        {
            var disposeObject1 = new StringContent("foo");
            var request1 = new HttpRequestMessage(HttpMethod.Get, "http://example.com");
            request1.RegisterForDispose(disposeObject1);
            var disposeObject2 = new StringContent("bar");
            var request2 = new HttpRequestMessage(HttpMethod.Post, "http://example.com");
            request2.RegisterForDispose(disposeObject2);

            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(new HttpRequestMessage[] { request1, request2 });

            var resourcesForDisposal = requestItem.GetResourcesForDisposal();

            Assert.Equal(2, resourcesForDisposal.Count());
            Assert.Contains(disposeObject1, resourcesForDisposal);
            Assert.Contains(disposeObject2, resourcesForDisposal);
        }
        public void SendRequestAsync_ReturnsChangeSetResponse()
        {
            HttpRequestMessage[] requests = new HttpRequestMessage[]
                {
                    new HttpRequestMessage(HttpMethod.Get, "http://example.com"),
                    new HttpRequestMessage(HttpMethod.Post, "http://example.com")
                };
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(requests);

            Mock<HttpMessageInvoker> invoker = new Mock<HttpMessageInvoker>(new HttpServer());
            invoker.Setup(i => i.SendAsync(It.IsAny<HttpRequestMessage>(), CancellationToken.None))
                .Returns(() =>
                {
                    return Task.FromResult(new HttpResponseMessage());
                });

            var response = requestItem.SendRequestAsync(invoker.Object, CancellationToken.None).Result;

            var changesetResponse = Assert.IsType<ChangeSetResponseItem>(response);
            Assert.Equal(2, changesetResponse.Responses.Count());
        }
        public void Dispose_DisposesAllHttpRequestMessages()
        {
            ChangeSetRequestItem requestItem = new ChangeSetRequestItem(new MockHttpRequestMessage[]
            {
                new MockHttpRequestMessage(),
                new MockHttpRequestMessage(),
                new MockHttpRequestMessage()
            });

            requestItem.Dispose();

            Assert.Equal(3, requestItem.Requests.Count());
            foreach (var request in requestItem.Requests)
            {
                Assert.True(((MockHttpRequestMessage)request).IsDisposed);
            }
        }