public async Task ExecuteChangeSetAsync_ReturnsSingleErrorResponse()
        {
            MockHttpServer server = new MockHttpServer(request =>
            {
                if (request.Method == HttpMethod.Post)
                {
                    return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));
                }
                return(Task.FromResult(new HttpResponseMessage()));
            });
            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler(server);
            HttpRequestMessage          batchRequest = new HttpRequestMessage(HttpMethod.Post, "http://example.com/$batch")
            {
                Content = new MultipartContent("mixed")
                {
                    new MultipartContent("mixed") // ChangeSet
                    {
                        ODataBatchRequestHelper.CreateODataRequestContent(new HttpRequestMessage(HttpMethod.Put, "http://example.com/values")),
                        ODataBatchRequestHelper.CreateODataRequestContent(new HttpRequestMessage(HttpMethod.Post, "http://example.com/values")),
                        ODataBatchRequestHelper.CreateODataRequestContent(new HttpRequestMessage(HttpMethod.Delete, "http://example.com/values")),
                    }
                }
            };
            ODataMessageReader reader = await batchRequest.Content
                                        .GetODataMessageReaderAsync(new ODataMessageReaderSettings { BaseUri = new Uri("http://example.com") }, CancellationToken.None);

            ODataBatchReader batchReader = await reader.CreateODataBatchReaderAsync();

            var response = await batchHandler.ExecuteChangeSetAsync(batchReader, Guid.NewGuid(), batchRequest, CancellationToken.None);

            var changesetResponse = Assert.IsType <ChangeSetResponseItem>(response);

            Assert.Single(changesetResponse.Responses);
            Assert.Equal(HttpStatusCode.BadRequest, changesetResponse.Responses.First().StatusCode);
        }
Esempio n. 2
0
        /// <inheritdoc/>
        public override async Task ProcessBatchAsync(HttpContext context, RequestDelegate nextHandler)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }
            if (nextHandler == null)
            {
                throw Error.ArgumentNull("nextHandler");
            }

            if (!await ValidateRequest(context.Request))
            {
                return;
            }

            // This container is for the overall batch request.
            HttpRequest      request          = context.Request;
            IServiceProvider requestContainer = request.CreateRequestContainer(ODataRouteName);

            requestContainer.GetRequiredService <ODataMessageReaderSettings>().BaseUri = GetBaseUri(request);

            ODataMessageReader reader = request.GetODataMessageReader(requestContainer);

            ODataBatchReader batchReader = await reader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();
            Guid batchId = Guid.NewGuid();

            ODataOptions options = context.RequestServices.GetRequiredService <ODataOptions>();
            bool         enableContinueOnErrorHeader = (options != null)
                ? options.EnableContinueOnErrorHeader
                : false;

            SetContinueOnError(new WebApiRequestHeaders(request.Headers), enableContinueOnErrorHeader);

            while (await batchReader.ReadAsync())
            {
                ODataBatchResponseItem responseItem = null;
                if (batchReader.State == ODataBatchReaderState.ChangesetStart)
                {
                    responseItem = await ExecuteChangeSetAsync(batchReader, batchId, request, nextHandler);
                }
                else if (batchReader.State == ODataBatchReaderState.Operation)
                {
                    responseItem = await ExecuteOperationAsync(batchReader, batchId, request, nextHandler);
                }
                if (responseItem != null)
                {
                    responses.Add(responseItem);
                    if (responseItem.IsResponseSuccessful() == false && ContinueOnError == false)
                    {
                        break;
                    }
                }
            }

            await CreateResponseMessageAsync(responses, request);
        }
Esempio n. 3
0
        public async Task ExecuteChangeSetAsync_CopiesPropertiesFromRequest_WithoutExcludedProperties()
        {
            // Arrange
            RequestDelegate handler = context =>
            {
                context.Features[typeof(UnbufferedODataBatchHandlerTest)] = "bar";
                return(Task.FromResult(context.Response));
            };

            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler();

            string      batchRequest = @"--cb7bb9ee-dce2-4c94-bf11-b742b2bc6072
Content-Type: multipart/mixed; boundary=""09f27d33-41ea-4334-8ace-1738bd2793a9""

--09f27d33-41ea-4334-8ace-1738bd2793a9
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1328966982

POST /values HTTP/1.1
Host: example.com
Content-Type: text/plain; charset=utf-8

foo
--09f27d33-41ea-4334-8ace-1738bd2793a9--

--cb7bb9ee-dce2-4c94-bf11-b742b2bc6072--
";
            HttpRequest request      = RequestFactory.Create("Post", "http://example.com/$batch", opt => opt.AddModel(EdmCoreModel.Instance));
            HttpContext httpContext  = request.HttpContext;

            byte[] requestBytes = Encoding.UTF8.GetBytes(batchRequest);
            request.Body          = new MemoryStream(requestBytes);
            request.ContentType   = "multipart/mixed;boundary=\"09f27d33-41ea-4334-8ace-1738bd2793a9\"";
            request.ContentLength = 431;
            httpContext.ODataFeature().PrefixName = "";
            IServiceProvider sp = request.GetSubServiceProvider();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(request.Body, request.Headers, sp);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri("http://example.com")
            });

            ODataBatchReader batchReader = await oDataMessageReader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();

            // Act
            var response = await batchHandler.ExecuteChangeSetAsync(batchReader, Guid.NewGuid(), request, handler);

            // Arrange
            ChangeSetResponseItem changeSetResponseItem = Assert.IsType <ChangeSetResponseItem>(response);
            HttpContext           changeSetContext      = Assert.Single(changeSetResponseItem.Contexts);

            Assert.Equal("bar", changeSetContext.Features[typeof(UnbufferedODataBatchHandlerTest)]);
        }
Esempio n. 4
0
        /// <summary>
        /// Converts the incoming OData batch request into a collection of request messages.
        /// </summary>
        /// <param name="context">The context containing the batch request messages.</param>
        /// <returns>A collection of <see cref="ODataBatchRequestItem"/>.</returns>
        public virtual async Task <IList <ODataBatchRequestItem> > ParseBatchRequestsAsync(HttpContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            HttpRequest      request          = context.Request;
            IServiceProvider requestContainer = request.CreateRouteServices(PrefixName);

            requestContainer.GetRequiredService <ODataMessageReaderSettings>().BaseUri = GetBaseUri(request);

            using (ODataMessageReader reader = request.GetODataMessageReader(requestContainer))
            {
                CancellationToken            cancellationToken = context.RequestAborted;
                List <ODataBatchRequestItem> requests          = new List <ODataBatchRequestItem>();
                ODataBatchReader             batchReader       = await reader.CreateODataBatchReaderAsync().ConfigureAwait(false);

                Guid batchId = Guid.NewGuid();
                Dictionary <string, string> contentToLocationMapping = new Dictionary <string, string>();

                while (await batchReader.ReadAsync().ConfigureAwait(false))
                {
                    if (batchReader.State == ODataBatchReaderState.ChangesetStart)
                    {
                        IList <HttpContext> changeSetContexts = await batchReader.ReadChangeSetRequestAsync(context, batchId, cancellationToken).ConfigureAwait(false);

                        foreach (HttpContext changeSetContext in changeSetContexts)
                        {
                            changeSetContext.Request.ClearRouteServices();
                        }

                        ChangeSetRequestItem requestItem = new ChangeSetRequestItem(changeSetContexts);
                        requestItem.ContentIdToLocationMapping = contentToLocationMapping;
                        requests.Add(requestItem);
                    }
                    else if (batchReader.State == ODataBatchReaderState.Operation)
                    {
                        HttpContext operationContext = await batchReader.ReadOperationRequestAsync(context, batchId, cancellationToken).ConfigureAwait(false);

                        operationContext.Request.ClearRouteServices();
                        OperationRequestItem requestItem = new OperationRequestItem(operationContext);
                        requestItem.ContentIdToLocationMapping = contentToLocationMapping;
                        requests.Add(requestItem);
                    }
                }

                return(requests);
            }
        }
Esempio n. 5
0
        public async Task ExecuteOperationAsync_CopiesPropertiesFromRequest_WithoutExcludedProperties()
        {
            // Arrange
            RequestDelegate handler = context =>
            {
                context.Features[typeof(UnbufferedODataBatchHandlerTest)] = "foo";
                return(Task.FromResult(context.Response));
            };

            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler();
            string batchRequest = @"--75148e61-e67a-4bb7-ac0f-78fa30d0da30
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 318941389

GET / HTTP/1.1
Host: example.com


--75148e61-e67a-4bb7-ac0f-78fa30d0da30--
";

            HttpRequest request     = RequestFactory.Create("Post", "http://example.com/$batch", opt => opt.AddModel(EdmCoreModel.Instance));
            HttpContext httpContext = request.HttpContext;

            byte[] requestBytes = Encoding.UTF8.GetBytes(batchRequest);
            request.Body          = new MemoryStream(requestBytes);
            request.ContentType   = "multipart/mixed;boundary=\"75148e61-e67a-4bb7-ac0f-78fa30d0da30\"";
            request.ContentLength = 431;
            httpContext.ODataFeature().PrefixName = "";
            IServiceProvider sp = request.GetSubServiceProvider();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(httpContext.Request.Body, request.Headers, sp);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri("http://example.com")
            });

            ODataBatchReader batchReader = await oDataMessageReader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();
            await batchReader.ReadAsync();

            // Act
            var response = await batchHandler.ExecuteOperationAsync(batchReader, Guid.NewGuid(), httpContext.Request, handler);

            // Assert
            OperationResponseItem operationResponseItem = Assert.IsType <OperationResponseItem>(response);

            Assert.Equal("foo", operationResponseItem.Context.Features[typeof(UnbufferedODataBatchHandlerTest)]);
        }
        public async Task ExecuteChangeSetAsync_CopiesPropertiesFromRequest_WithoutExcludedProperties()
        {
            MockHttpServer server = new MockHttpServer(request =>
            {
                return(new HttpResponseMessage
                {
                    RequestMessage = request
                });
            });
            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler(server);
            HttpRequestMessage          batchRequest = new HttpRequestMessage(HttpMethod.Post, "http://example.com/$batch")
            {
                Content = new MultipartContent("mixed")
                {
                    new MultipartContent("mixed") // ChangeSet
                    {
                        ODataBatchRequestHelper.CreateODataRequestContent(new HttpRequestMessage(HttpMethod.Post, "http://example.com/values")
                        {
                            Content = new StringContent("foo")
                        })
                    }
                }
            };

            batchRequest.Properties.Add("foo", "bar");
            batchRequest.SetRouteData(new HttpRouteData(new HttpRoute()));
            batchRequest.RegisterForDispose(new StringContent(String.Empty));
            ODataMessageReader reader = await batchRequest.Content
                                        .GetODataMessageReaderAsync(new ODataMessageReaderSettings { BaseUri = new Uri("http://example.com") }, CancellationToken.None);

            ODataBatchReader batchReader = await reader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();
            Guid batchId = Guid.NewGuid();
            await batchReader.ReadAsync();

            var response = await batchHandler.ExecuteChangeSetAsync(batchReader, Guid.NewGuid(), batchRequest, CancellationToken.None);

            var changeSetResponses = ((ChangeSetResponseItem)response).Responses;

            foreach (var changeSetResponse in changeSetResponses)
            {
                var changeSetRequest = changeSetResponse.RequestMessage;
                Assert.Equal("bar", changeSetRequest.Properties["foo"]);
                Assert.Null(changeSetRequest.GetRouteData());
                Assert.Same(changeSetRequest, changeSetRequest.GetUrlHelper().Request);
                Assert.Empty(changeSetRequest.GetResourcesForDisposal());
            }
        }
        /// <summary>
        /// Converts the incoming OData batch request into a collection of request messages.
        /// </summary>
        /// <param name="context">The context containing the batch request messages.</param>
        /// <returns>A collection of <see cref="ODataBatchRequestItem"/>.</returns>
        public virtual async Task <IList <ODataBatchRequestItem> > ParseBatchRequestsAsync(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            HttpRequest      request          = context.Request;
            IServiceProvider requestContainer = request.CreateSubServiceProvider(PrefixName);

            requestContainer.GetRequiredService <ODataMessageReaderSettings>().BaseUri = GetBaseUri(request);

            using (ODataMessageReader reader = request.GetODataMessageReader(requestContainer))
            {
                CancellationToken            cancellationToken = context.RequestAborted;
                List <ODataBatchRequestItem> requests          = new List <ODataBatchRequestItem>();
                ODataBatchReader             batchReader       = await reader.CreateODataBatchReaderAsync().ConfigureAwait(false);

                Guid batchId = Guid.NewGuid();
                while (await batchReader.ReadAsync().ConfigureAwait(false))
                {
                    if (batchReader.State == ODataBatchReaderState.ChangesetStart)
                    {
                        IList <HttpContext> changeSetContexts = await batchReader.ReadChangeSetRequestAsync(context, batchId, cancellationToken).ConfigureAwait(false);

                        foreach (HttpContext changeSetContext in changeSetContexts)
                        {
                            changeSetContext.Request.CopyBatchRequestProperties(request);
                            changeSetContext.Request.DeleteSubRequestProvider(false);
                        }
                        requests.Add(new ChangeSetRequestItem(changeSetContexts));
                    }
                    else if (batchReader.State == ODataBatchReaderState.Operation)
                    {
                        HttpContext operationContext = await batchReader.ReadOperationRequestAsync(context, batchId, cancellationToken).ConfigureAwait(false);

                        operationContext.Request.CopyBatchRequestProperties(request);
                        operationContext.Request.DeleteSubRequestProvider(false);
                        requests.Add(new OperationRequestItem(operationContext));
                    }
                }

                return(requests);
            }
        }
        public virtual async Task <IList <ODataBatchRequestItem> > ParseBatchRequestsAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            IServiceProvider requestContainer = request.CreateRequestContainer(ODataRouteName);

            requestContainer.GetRequiredService <ODataMessageReaderSettings>().BaseUri = GetBaseUri(request);

            ODataMessageReader reader = await request.Content.GetODataMessageReaderAsync(requestContainer, cancellationToken);

            request.RegisterForDispose(reader);

            List <ODataBatchRequestItem> requests    = new List <ODataBatchRequestItem>();
            ODataBatchReader             batchReader = await reader.CreateODataBatchReaderAsync();

            Guid batchId = Guid.NewGuid();

            while (await batchReader.ReadAsync())
            {
                if (batchReader.State == ODataBatchReaderState.ChangesetStart)
                {
                    IList <HttpRequestMessage> changeSetRequests = await batchReader.ReadChangeSetRequestAsync(batchId, cancellationToken);

                    foreach (HttpRequestMessage changeSetRequest in changeSetRequests)
                    {
                        changeSetRequest.CopyBatchRequestProperties(request);
                        changeSetRequest.DeleteRequestContainer(false);
                    }
                    requests.Add(new ChangeSetRequestItem(changeSetRequests));
                }
                else if (batchReader.State == ODataBatchReaderState.Operation)
                {
                    HttpRequestMessage operationRequest = await batchReader.ReadOperationRequestAsync(batchId, bufferContentStream : true, cancellationToken : cancellationToken);

                    operationRequest.CopyBatchRequestProperties(request);
                    operationRequest.DeleteRequestContainer(false);
                    requests.Add(new OperationRequestItem(operationRequest));
                }
            }

            return(requests);
        }
Esempio n. 9
0
        /// <inheritdoc/>
        public override async Task <HttpResponseMessage> ProcessBatchAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw Error.ArgumentNull("request");
            }

            ValidateRequest(request);

            // This container is for the overall batch request.
            IServiceProvider requestContainer = request.CreateRequestContainer(ODataRouteName);

            requestContainer.GetRequiredService <ODataMessageReaderSettings>().BaseUri = GetBaseUri(request);

            ODataMessageReader reader = await request.Content.GetODataMessageReaderAsync(requestContainer, cancellationToken);

            request.RegisterForDispose(reader);

            ODataBatchReader batchReader = await reader.CreateODataBatchReaderAsync();

            List <ODataBatchResponseItem> responses = new List <ODataBatchResponseItem>();
            Guid batchId = Guid.NewGuid();

            HttpConfiguration configuration  = request.GetConfiguration();
            bool enableContinueOnErrorHeader = (configuration != null)
                ? configuration.HasEnabledContinueOnErrorHeader()
                : false;

            SetContinueOnError(new WebApiRequestHeaders(request.Headers), enableContinueOnErrorHeader);

            try
            {
                while (await batchReader.ReadAsync())
                {
                    ODataBatchResponseItem responseItem = null;
                    if (batchReader.State == ODataBatchReaderState.ChangesetStart)
                    {
                        responseItem = await ExecuteChangeSetAsync(batchReader, batchId, request, cancellationToken);
                    }
                    else if (batchReader.State == ODataBatchReaderState.Operation)
                    {
                        responseItem = await ExecuteOperationAsync(batchReader, batchId, request, cancellationToken);
                    }
                    if (responseItem != null)
                    {
                        responses.Add(responseItem);
                        if (responseItem.IsResponseSuccessful() == false && ContinueOnError == false)
                        {
                            break;
                        }
                    }
                }
            }
            catch
            {
                foreach (ODataBatchResponseItem response in responses)
                {
                    if (response != null)
                    {
                        response.Dispose();
                    }
                }
                throw;
            }

            return(await CreateResponseMessageAsync(responses, request, cancellationToken));
        }
Esempio n. 10
0
        public async Task ExecuteChangeSetAsync_ReturnsSingleErrorResponse()
        {
            // Arrange
            RequestDelegate handler = context =>
            {
                if (context.Request.Method.ToUpperInvariant() == "POST")
                {
                    context.Response.StatusCode = StatusCodes.Status400BadRequest;
                    return(Task.FromResult(context.Response));
                }

                return(Task.FromResult(context.Response));
            };

            UnbufferedODataBatchHandler batchHandler = new UnbufferedODataBatchHandler();
            string batchRequest = @"--86aef3eb-4af6-4750-a66d-df65e3f31ab0
Content-Type: multipart/mixed; boundary=""7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6""

--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: -1233709575

PUT /values HTTP/1.1
Host: example.com


--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: -1854117385

POST /values HTTP/1.1
Host: example.com


--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: -1665098746

DELETE /values HTTP/1.1
Host: example.com


--7a61b8c1-a80e-4e6b-bac7-2f65564e3fd6--

--86aef3eb-4af6-4750-a66d-df65e3f31ab0--";

            IEdmModel   model       = new EdmModel();
            HttpRequest request     = RequestFactory.Create("Post", "http://example.com/$batch", opt => opt.AddModel(model));
            HttpContext httpContext = request.HttpContext;

            byte[] requestBytes = Encoding.UTF8.GetBytes(batchRequest);
            httpContext.Request.Body          = new MemoryStream(requestBytes);
            httpContext.Request.ContentType   = "multipart/mixed;boundary=\"86aef3eb-4af6-4750-a66d-df65e3f31ab0\"";
            httpContext.Request.ContentLength = 431;
            httpContext.ODataFeature().PrefixName = "";
            IServiceProvider sp = request.GetSubServiceProvider();

            IODataRequestMessage oDataRequestMessage = ODataMessageWrapperHelper.Create(httpContext.Request.Body, request.Headers, sp);
            ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri("http://example.com")
            });

            ODataBatchReader batchReader = await oDataMessageReader.CreateODataBatchReaderAsync();

            // Act
            var response = await batchHandler.ExecuteChangeSetAsync(batchReader, Guid.NewGuid(), httpContext.Request, handler);

            // Assert
            var changesetResponse = Assert.IsType <ChangeSetResponseItem>(response);
            var returnContext     = Assert.Single(changesetResponse.Contexts);

            Assert.Equal(StatusCodes.Status400BadRequest, returnContext.Response.StatusCode);
        }