/// <summary> /// Generates extra operations to go into a request changeset /// </summary> /// <param name="random">For generating the payloads to go in the extra operations</param> /// <param name="requestManager">For building the operations</param> /// <param name="model">To add any new types to.</param> /// <param name="baseUri">Base uri for the extra operations.</param> /// <param name="version">Maximum version for </param> /// <returns>An array of extra request operations.</returns> public static IHttpRequest[] ExtraRequestChangesetOperations( IRandomNumberGenerator random, IODataRequestManager requestManager, EdmModel model, ODataUri baseUri, ODataVersion version = ODataVersion.V4) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); var headers = new Dictionary <string, string> { { "RequestHeader", "RequestHeaderValue" } }; string mergeContentType = HttpUtilities.BuildContentType(MimeTypes.ApplicationXml, Encoding.UTF8.WebName, null); List <IHttpRequest> requests = new List <IHttpRequest>(); ODataRequest request = null; for (int i = 0; i < 4; i++) { request = requestManager.BuildRequest(baseUri, HttpVerb.Post, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Put, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Patch, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Delete, headers); requests.Add(request); } return(requests.ToArray()); }
/// <summary> /// Generates extra request changesets. /// </summary> /// <param name="random">For generating arbitrary changesets.</param> /// <param name="requestManager">For building changesets.</param> /// <param name="model">For adding any generated types to.</param> /// <param name="baseUri">Base uri for the changesets.</param> /// <param name="version">Maximum version of any generated types.</param> /// <returns>An array of request changesets.</returns> public static BatchRequestChangeset[] ExtraRequestChangesets( IRandomNumberGenerator random, IODataRequestManager requestManager, EdmModel model, ODataUri baseUri, ODataVersion version = ODataVersion.V4 ) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); var headers = new Dictionary <string, string> { { "RequestHeader", "RequestHeaderValue" } }; string mergeContentType = HttpUtilities.BuildContentType(MimeTypes.ApplicationXml, Encoding.UTF8.WebName, null); var requests = ExtraRequestChangesetOperations(random, requestManager, model, baseUri, version); List <BatchRequestChangeset> changesets = new List <BatchRequestChangeset>(); for (int x = 0; x < 5; ++x) { IEnumerable <IHttpRequest> operations = Enumerable.Range(0, random.Next(10)).Select(i => random.ChooseFrom(requests)); changesets.Add(BatchPayloadBuilder.RequestChangeset("changeset_" + Guid.NewGuid().ToString(), "", operations.ToArray())); } return(changesets.ToArray()); }
/// <summary> /// Constructor /// </summary> /// <param name="response">true if payload represents a response payload, false if it's a request payload.</param> /// <param name="requestManager">The request manager used to convert batch payloads.</param> /// <param name="payloadContainsIdentityMetadata">Whether or not the payload contains identity values for entries.</param> /// <param name="payloadContainsEtagPropertiesForType">A function for determining whether the payload contains etag property values for a given type.</param> public ObjectModelToPayloadElementConverterVisitor(bool response, IODataRequestManager requestManager, bool payloadContainsIdentityMetadata, Func <string, bool> payloadContainsEtagPropertiesForType) { this.response = response; this.requestManager = requestManager; this.payloadContainsIdentityMetadata = payloadContainsIdentityMetadata; this.payloadContainsEtagPropertiesForType = payloadContainsEtagPropertiesForType; }
/// <summary> /// Generates extra operations to go into a request changeset /// </summary> /// <param name="random">For generating the payloads to go in the extra operations</param> /// <param name="requestManager">For building the operations</param> /// <param name="model">To add any new types to.</param> /// <param name="baseUri">Base uri for the extra operations.</param> /// <param name="version">Maximum version for </param> /// <returns>An array of extra request operations.</returns> public static IHttpRequest[] ExtraRequestChangesetOperations( IRandomNumberGenerator random, IODataRequestManager requestManager, EdmModel model, ODataUri baseUri, ODataVersion version = ODataVersion.V4) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); var headers = new Dictionary<string, string> { { "RequestHeader", "RequestHeaderValue" } }; string mergeContentType = HttpUtilities.BuildContentType(MimeTypes.ApplicationXml, Encoding.UTF8.WebName, null); List<IHttpRequest> requests = new List<IHttpRequest>(); ODataRequest request = null; for (int i = 0; i < 4; i++) { request = requestManager.BuildRequest(baseUri, HttpVerb.Post, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Put, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Patch, headers); request.Body = requestManager.BuildBody(mergeContentType, baseUri, RandomPayloadBuilder.GetRandomPayload(random, model, version)); requests.Add(request); request = requestManager.BuildRequest(baseUri, HttpVerb.Delete, headers); requests.Add(request); } return requests.ToArray(); }
internal static void SetupProtocolRequest(QueryExpression expression, IODataRequestManager requestManager, IQueryToODataPayloadConverter queryToPayloadConverter, ODataUri uri, HttpHeaderCollection headers, string actionContentType, out Contracts.OData.ODataRequest request) { HttpVerb requestVerb = HttpVerb.Get; if (uri.IsAction()) { requestVerb = HttpVerb.Post; } if (uri.IsWebInvokeServiceOperation()) { requestVerb = HttpVerb.Post; } request = requestManager.BuildRequest(uri, requestVerb, headers); if (uri.IsAction()) { var procedurePayload = queryToPayloadConverter.ComputePayload(expression) as ComplexInstance; if (procedurePayload != null) { request.Headers.Add(HttpHeaders.ContentType, actionContentType); FixupAddingResultWrappers(actionContentType, procedurePayload); // TODO: Need to understand if product allow an Html form even if no parameters specified request.Body = requestManager.BuildBody(actionContentType, uri, procedurePayload); } } }
/// <summary> /// Puts payload in a response operation with given status code. /// </summary> /// <typeparam name="T">Must be a PayloadTestDescriptor.</typeparam> /// <param name="payload">Payload to put in operation.</param> /// <param name="statusCode">Status code for response.</param> /// <param name="requestManager">Used to construct the body of the response.</param> /// <param name="contentType">The (optional) content type to be used for the operation content.</param> /// <returns>The response encapsulating the <paramref name="payload"/>.</returns> public static ODataResponse InResponseOperation <T>( this T payload, int statusCode, IODataRequestManager requestManager, string contentType = null) where T : PayloadTestDescriptor { ExceptionUtilities.CheckArgumentNotNull(payload, "payload"); ExceptionUtilities.CheckArgumentNotNull(statusCode, "statusCode"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); var httpResponseData = new HttpResponseData { StatusCode = (HttpStatusCode)statusCode }; httpResponseData.Headers.Add("GivenPayloadResponseHeader", "ResponseHeaderValue"); if (payload.PayloadElement != null) { if (string.IsNullOrEmpty(contentType)) { contentType = payload.PayloadElement.GetDefaultContentType(); } httpResponseData.Headers.Add(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, contentType); // Convert the payload element to the byte[] representation httpResponseData.Body = requestManager.BuildBody(contentType, /*ODataUri*/ null, payload.PayloadElement).SerializedValue; } return(new ODataResponse(httpResponseData) { RootElement = payload.PayloadElement }); }
/// <summary> /// Puts given payload in an operation for a changeset. /// </summary> /// <typeparam name="T"> Must be a PayloadTestDescriptor.</typeparam> /// <param name="payload">Payload to be put into changeset operation.</param> /// <param name="verb">Verb associated with payload.</param> /// <param name="baseUri">Baseuri for operation.</param> /// <param name="requestManager">RequestManager to build the request</param> /// <param name="contentType">The (optional) content type to be used for the operation content.</param> /// <returns>IHttpRequest containing payload with specified verb and uri</returns> public static ODataRequest InRequestOperation <T>( this T payload, HttpVerb verb, ODataUri baseUri, IODataRequestManager requestManager, string contentType = null) where T : PayloadTestDescriptor { ExceptionUtilities.CheckArgumentNotNull(payload, "payload"); ExceptionUtilities.CheckArgumentNotNull(verb, "verb"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); var headers = new Dictionary <string, string> { { "GivenPayloadRequestHeader", "PayloadHeaderValue" } }; var request = requestManager.BuildRequest(baseUri, verb, headers); if (payload.PayloadElement != null) { if (string.IsNullOrEmpty(contentType)) { contentType = payload.PayloadElement.GetDefaultContentType(); } contentType = HttpUtilities.BuildContentType(contentType, Encoding.UTF8.WebName, null); request.Headers.Add(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, contentType); request.Body = requestManager.BuildBody(contentType, baseUri, payload.PayloadElement); } return(request); }
/// <summary> /// Puts the specified <paramref name="payload"/> into a changeset. /// </summary> /// <param name="payload">The payload to be used as content for the expanded link.</param> /// <param name="verb">The verb associated with the payload.</param> /// <param name="operationsBefore">Number of extra operations before payload.</param> /// <param name="operationsAfter">Number of extra operations after payload.</param> /// <param name="version">Highest version of allowed features</param> /// <returns>An entry payload with an expanded link that contains the specified <paramref name="payload"/>.</returns> public static BatchResponseChangeset InResponseChangeset <T>( this T payload, int statuscode, IRandomNumberGenerator random, IODataRequestManager requestManager, int operationsBefore = 0, int operationsAfter = 0, ODataVersion version = ODataVersion.V4) where T : PayloadTestDescriptor { ExceptionUtilities.CheckArgumentNotNull(payload, "payload"); ExceptionUtilities.CheckArgumentNotNull(statuscode, "statuscode"); ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); var extraOperations = BatchUtils.ExtraResponseOperations(random, (EdmModel)payload.PayloadEdmModel, version); // Build the list of all properties IEnumerable <IMimePart> operations = Enumerable.Range(0, operationsBefore).Select(i => random.ChooseFrom(extraOperations)); operations.ConcatSingle(InResponseOperation(payload, statuscode, requestManager)); operations = operations.Concat(Enumerable.Range(0, operationsAfter).Select(i => random.ChooseFrom(extraOperations))); var changeset = BatchPayloadBuilder.ResponseChangeset("changeset_" + Guid.NewGuid().ToString(), Encoding.UTF8.WebName, operations.ToArray()); return(changeset); }
/// <summary> /// Puts the specified <paramref name="payload"/> into a changeset. /// </summary> /// <param name="payload">The payload to be used as content for the expanded link.</param> /// <param name="verb">The verb associated with the payload.</param> /// <param name="random">Use of random makes this method non deterministic.</param> /// <param name="requestManager">Used to construct requests</param> /// <param name="operationsBefore">Number of extra operations before payload.</param> /// <param name="operationsAfter">Number of extra operations after payload.</param> /// <param name="version">Highest version of allowed features</param> /// <returns>An entry payload with an expanded link that contains the specified <paramref name="payload"/>.</returns> public static BatchRequestChangeset InRequestChangeset <T>( this T payload, HttpVerb verb, IRandomNumberGenerator random, IODataRequestManager requestManager, int operationsBefore = 0, int operationsAfter = 0, ODataVersion version = ODataVersion.V4 ) where T : PayloadTestDescriptor { ExceptionUtilities.CheckArgumentNotNull(payload, "payload"); ExceptionUtilities.CheckArgumentNotNull(verb, "verb"); ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); var baseUri = new ODataUri(ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc"))); var extraOperations = BatchUtils.ExtraRequestChangesetOperations(random, requestManager, (EdmModel)payload.PayloadEdmModel, baseUri, version); // Build the list of all properties IEnumerable <IHttpRequest> operations = Enumerable.Range(0, operationsBefore).Select(i => random.ChooseFrom(extraOperations)); operations.ConcatSingle(payload.InRequestOperation(verb, baseUri, requestManager)); operations = operations.Concat(Enumerable.Range(0, operationsAfter).Select(i => extraOperations[extraOperations.Length - 1 - (i % extraOperations.Length)])); var changeset = BatchPayloadBuilder.RequestChangeset("changeset_" + Guid.NewGuid().ToString(), Encoding.UTF8.WebName, operations.ToArray()); return(changeset); }
/// <summary> /// Generates extra request operations /// </summary> /// <param name="requestManager">RequestManager to build the operations.</param> /// <param name="baseUri">Base uri for the operations</param> /// <returns>An array of request operations.</returns> public static IMimePart[] ExtraRequestOperations(IODataRequestManager requestManager, ODataUri baseUri) { ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); var headers = new Dictionary <string, string> { { "RequestHeader", "RequestHeaderValue" } }; string mergeContentType = HttpUtilities.BuildContentType(MimeTypes.ApplicationXml, Encoding.UTF8.WebName, null); List <IHttpRequest> requests = new List <IHttpRequest>(); requests.Add(requestManager.BuildRequest(baseUri, HttpVerb.Get, headers)); var segments = baseUri.Segments; ODataUriSegment[] segmentstoadd = { ODataUriBuilder.EntitySet(new EntitySet("Set1")), ODataUriBuilder.EntityType(new EntityType("EntityType")), ODataUriBuilder.EntitySet(new EntitySet("Set2")), ODataUriBuilder.EntityType(new EntityType("EntityType2")), }; foreach (var segment in segmentstoadd) { requests.Add(requestManager.BuildRequest(new ODataUri(segments.ConcatSingle(segment)), HttpVerb.Get, headers)); } return(requests.ToArray()); }
/// <summary> /// Puts payload in a batch response. /// </summary> /// <typeparam name="T">T must be a PayloadTestDescriptor.</typeparam> /// <param name="originalPayload">Payload to be inserted into batch.</param> /// <param name="statusCode">Status code associated with payload</param> /// <param name="random">Use of random makes this method non deterministic</param> /// <param name="requestManager">Used to construct the response payload.</param> /// <param name="inChangeset">Specifies whether this is in a changeset or an operation.</param> /// <param name="operationsBefore">Number of operations/changesets to go before payload.</param> /// <param name="operationsAfter">Number of operations/changesets to go after payload.</param> /// <param name="version">Maximum version for extra generated payloads</param> /// <returns>Test descriptor for the new BatchResponsePayload.</returns> public static T InBatchResponse <T>( this T originalPayload, int statusCode, IRandomNumberGenerator random, IODataRequestManager requestManager, bool inChangeset = false, int operationsBefore = 0, int operationsAfter = 0, ODataVersion version = ODataVersion.V4 ) where T : PayloadTestDescriptor { ExceptionUtilities.CheckArgumentNotNull(originalPayload, "originalPayload"); ExceptionUtilities.CheckArgumentNotNull(statusCode, "statusCode"); ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); var payload = (T)originalPayload.Clone(); var headers = new Dictionary <string, string> { { "ResponseHeader", "ResponseValue" } }; var baseUri = new ODataUri(ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc"))); IMimePart[] extraoperations = BatchUtils.ExtraResponseChangesets(random, (EdmModel)payload.PayloadEdmModel, version); // add extraChangesets methods extraoperations.Concat(BatchUtils.ExtraResponseOperations(random, (EdmModel)payload.PayloadEdmModel, version)); //Work out the operations and changesets to go before the payload var parts = Enumerable.Range(0, operationsBefore).Select(i => random.ChooseFrom(extraoperations)); if (!inChangeset) { extraoperations.ConcatSingle(payload.InResponseOperation(statusCode, requestManager)); } else { extraoperations.ConcatSingle(payload.InResponseChangeset(statusCode, random, requestManager, random.NextFromRange(0, 2), random.NextFromRange(0, 2), version)); } parts.Concat(Enumerable.Range(0, operationsAfter).Select(i => random.ChooseFrom(extraoperations))); var batchResponse = new BatchResponsePayload(); foreach (var part in parts) { HttpResponseData operation = part as HttpResponseData; if (operation != null) { batchResponse.Add(operation.AsBatchFragment()); } BatchResponseChangeset changeset = part as BatchResponseChangeset; if (changeset != null) { batchResponse.Add(changeset); } } //payload.PayloadEdmModel.Fixup(); payload.PayloadElement = batchResponse; return(payload); }
/// <summary> /// Gets the response changeset with the specified mime parts and content type. /// </summary> /// <param name="operations">Operations to go into changeset</param> /// <param name="contentTypeName">ContentType associated with changeset</param> /// <param name="requestManager">RequestManager to build the response changeset.</param> /// <returns>A batch response changeset.</returns> public static BatchResponseChangeset GetResponseChangeset( IMimePart[] operations, IODataRequestManager requestManager ) { ExceptionUtilities.CheckArgumentNotNull(operations, "operations"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); return(BatchPayloadBuilder.ResponseChangeset("changeset_" + Guid.NewGuid().ToString(), Encoding.UTF8.WebName, operations.ToArray())); }
/// <summary> /// Puts payload in a batch request. /// </summary> /// <typeparam name="T">T must be a PayloadTestDescriptor.</typeparam> /// <param name="originalPayload">Payload to put into batch.</param> /// <param name="verb">HttpVerb associated with payload.</param> /// <param name="random">Use of random makes this method non deterministic.</param> /// <param name="requestManager">Used to construct requests.</param> /// <param name="operationsBefore">Number of operations/changesets to go before payload.</param> /// <param name="operationsAfter">Number of operations/changesets to go after payload.</param> /// <param name="version">Maximum version for extra payloads</param> /// <returns>The test descriptor for the new BatchRequestPayload</returns> public static T InBatchRequest <T>( this T originalPayload, HttpVerb verb, IRandomNumberGenerator random, IODataRequestManager requestManager, int operationsBefore = 0, int operationsAfter = 0, ODataVersion version = ODataVersion.V4 ) where T : PayloadTestDescriptor { ExceptionUtilities.CheckArgumentNotNull(originalPayload, "originalPayload"); ExceptionUtilities.CheckArgumentNotNull(verb, "verb"); ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); var payload = (T)originalPayload.Clone(); var baseUri = new ODataUri(ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc"))); IMimePart[] extraOperations = BatchUtils.ExtraRequestChangesets(random, requestManager, (EdmModel)payload.PayloadEdmModel, baseUri, version); // add extraChangesets methods extraOperations.Concat(BatchUtils.ExtraRequestChangesets(random, requestManager, (EdmModel)payload.PayloadEdmModel, baseUri, version)); //Work out the operations and changesets to go before the payload var parts = Enumerable.Range(0, operationsBefore).Select(i => random.ChooseFrom(extraOperations)); if (verb != HttpVerb.Get) { extraOperations.ConcatSingle(payload.InRequestOperation(HttpVerb.Get, baseUri, requestManager)); } else { extraOperations.ConcatSingle(payload.InRequestChangeset(verb, random, requestManager, random.NextFromRange(0, 2), random.NextFromRange(0, 2), version)); } parts.Concat(Enumerable.Range(0, operationsAfter).Select(i => random.ChooseFrom(extraOperations))); var batchRequest = new BatchRequestPayload(); foreach (var part in parts) { IHttpRequest operation = part as IHttpRequest; if (operation != null) { batchRequest.Add(operation.AsBatchFragment()); } BatchRequestChangeset changeset = part as BatchRequestChangeset; if (changeset != null) { batchRequest.Add(changeset); } } //payload.PayloadEdmModel.Fixup(); payload.PayloadElement = batchRequest; return(payload); }
/// <summary> /// Gets the request changeset with the specified mime parts and content type. /// </summary> /// <param name="operations">Operations to go into changeset</param> /// <param name="requestManager">RequestManager to build the request.</param> /// <returns>A batch request changeset.</returns> public static BatchRequestChangeset GetRequestChangeset( IMimePart[] operations, IODataRequestManager requestManager ) { ExceptionUtilities.CheckArgumentNotNull(operations, "operations"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); return BatchPayloadBuilder.RequestChangeset("changeset_" + Guid.NewGuid().ToString(), Encoding.UTF8.WebName, operations.ToArray()); }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="batchBoundary">The batch boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultQueryBatch( IODataRequestManager requestManager, int queryCount, bool forRequest, string batchBoundary = null) { Debug.Assert(queryCount >= 0, "batchSize >= 0"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[queryCount]; if (forRequest) { var queryOperation = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i = 0; i < queryCount; ++i) { parts[i] = queryOperation; } ; string requestBoundary = batchBoundary ?? "bb_multiple_request_queries_" + queryCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }); } // Response operation with no payload and a status code of 200 var emptyPayloadResponse = emptyPayload.InResponseOperation(200, requestManager); for (int i = 0; i < queryCount; ++i) { parts[i] = emptyPayloadResponse; } ; string responseBoundary = batchBoundary ?? "bb_multiple_response_queries_" + queryCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }); }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="changeSetBoundary">The changeset boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultChangeSetBatch( IODataRequestManager requestManager, int changeSetCount, int[] changeSetSizes, bool forRequest, string changeSetBoundary = null) { Debug.Assert(changeSetCount >= 0, "batchSize >= 0"); Debug.Assert(changeSetSizes != null, "changeSetSizes != null"); Debug.Assert(changeSetSizes.Length == changeSetCount, "Size of the batch must match the length of the change set sizes array!"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[changeSetCount]; if (forRequest) { // Delete operation with no payload var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i = 0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var deleteOperations = new IMimePart[changeSetSize]; for (int j = 0; j < changeSetSize; ++j) { deleteOperations[j] = deleteOperation; } var changeset = BatchUtils.GetRequestChangeset(deleteOperations, requestManager); parts[i] = changeset; } ; string requestBoundary = changeSetBoundary ?? "bb_multiple_request_changesets_" + changeSetCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }); } // Response operation with no payload and a status code of 200 var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager); for (int i = 0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var operationResponses = new IMimePart[changeSetSize]; for (int j = 0; j < changeSetSize; ++j) { operationResponses[j] = emptyPayloadOperation; } var changeset = BatchUtils.GetResponseChangeset(operationResponses, requestManager); parts[i] = changeset; } ; string responseBoundary = changeSetBoundary ?? "bb_multiple_response_changesets_" + changeSetCount; return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }); }
/// <summary> /// Creates several PayloadTestDescriptors containing Batch Requests /// </summary> /// <param name="requestManager">Used for building the requests</param> /// <param name="model">The model to use for adding additional types.</param> /// <param name="withTypeNames">Whether or not to use full type names.</param> /// <returns>PayloadTestDescriptors</returns> public static IEnumerable <PayloadTestDescriptor> CreateBatchRequestTestDescriptors( IODataRequestManager requestManager, EdmModel model, bool withTypeNames = false) { ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); EdmEntityType personType = null; EdmComplexType carType = null; EdmEntitySet personsEntitySet = null; EdmEntityContainer container = model.EntityContainer as EdmEntityContainer; if (model != null) { //TODO: Clone EdmModel //model = model.Clone(); if (container == null) { container = new EdmEntityContainer("TestModel", "DefaultContainer"); model.AddElement(container); } personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType; carType = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType; // Create the metadata types for the entity instance used in the entity set if (carType == null) { carType = new EdmComplexType("TestModel", "TFCar"); model.AddElement(carType); carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true); carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true); } if (personType == null) { personType = new EdmEntityType("TestModel", "TFPerson"); model.AddElement(personType); personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true); personType.AddStructuralProperty("Car", carType.ToTypeReference()); container.AddEntitySet("Customers", personType); } personsEntitySet = container.AddEntitySet("People", personType); } ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null) .Property("Make", PayloadBuilder.PrimitiveValue("Ford")) .Property("Color", PayloadBuilder.PrimitiveValue("Blue")); ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance) .WithTypeAnnotation(personType); EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null) .Property("Id", PayloadBuilder.PrimitiveValue(1)) .Property("Name", PayloadBuilder.PrimitiveValue("John Doe")) .Property("Car", carInstance) .WithTypeAnnotation(personType); var carPropertyPayload = new PayloadTestDescriptor() { PayloadElement = carProperty, PayloadEdmModel = model }; var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var personPayload = new PayloadTestDescriptor() { PayloadElement = personInstance, PayloadEdmModel = model }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); var entityset = ODataUriBuilder.EntitySet(personsEntitySet); // Get operations var queryOperation1 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); var queryOperation2 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); // Post operation containing a complex property var postOperation = carPropertyPayload.InRequestOperation(HttpVerb.Post, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager, MimeTypes.ApplicationJsonLight); // Delete operation with no payload var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager); // Put operation where the payload is an EntityInstance var putOperation = personPayload.InRequestOperation(HttpVerb.Put, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager); // A changeset containing a delete with no payload and a put var twoOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { postOperation, deleteOperation }, requestManager); // A changeset containing a delete with no payload var oneOperationChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { deleteOperation }, requestManager); // A changeset containing a put, post and delete var threeOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { putOperation, postOperation, deleteOperation }, requestManager); // A changeset containing no operations var emptyChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { }, requestManager); // Empty Batch yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload() .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")), PayloadEdmModel = emptyPayload.PayloadEdmModel, SkipTestConfiguration = (tc) => !tc.IsRequest, }); // Single Operation yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1) .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); // Multiple Operations yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2) .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); // Single Changeset yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); // Multiple Changesets (different content types) yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, oneOperationChangeset, emptyChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); // Operations and changesets yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, queryOperation1, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, oneOperationChangeset, queryOperation2) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2, twoOperationsChangeset, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, threeOperationsChangeset, queryOperation2, twoOperationsChangeset, queryOperation1, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, emptyChangeset, queryOperation1, threeOperationsChangeset, queryOperation2, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_5")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }); }
/// <summary> /// Creates several PayloadTestDescriptors containing Batch Responses /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="model">The model to use for adding additional types.</param> /// <param name="withTypeNames">Whether or not to use full type names.</param> /// <returns>PayloadTestDescriptors</returns> public static IEnumerable <PayloadTestDescriptor> CreateBatchResponseTestDescriptors( IODataRequestManager requestManager, EdmModel model, bool withTypeNames = false) { EdmEntityType personType = null; EdmComplexType carType = null; if (model != null) { //TODO: CLONE for EdmModel //model = model.Clone(); personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType; carType = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType; // Create the metadata types for the entity instance used in the entity set if (carType == null) { carType = new EdmComplexType("TestModel", "TFCar"); model.AddElement(carType); carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true); carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true); } if (personType == null) { personType = new EdmEntityType("TestModel", "TFPerson"); model.AddElement(personType); personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true); personType.AddStructuralProperty("Car", carType.ToTypeReference()); EdmEntityContainer container = (EdmEntityContainer)model.EntityContainer; if (container == null) { container = new EdmEntityContainer("TestModel", "DefaultContainer"); model.AddElement(container); container.AddEntitySet("Customers", personType); container.AddEntitySet("TFPerson", personType); } } } ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null) .Property("Make", PayloadBuilder.PrimitiveValue("Ford")) .Property("Color", PayloadBuilder.PrimitiveValue("Blue")); ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance) .WithTypeAnnotation(carType); EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null) .Property("Id", PayloadBuilder.PrimitiveValue(1)) .Property("Name", PayloadBuilder.PrimitiveValue("John Doe")) .Property("Car", carInstance) .WithTypeAnnotation(personType); ODataErrorPayload errorInstance = PayloadBuilder.Error("ErrorCode") .Message("ErrorValue") .InnerError( PayloadBuilder.InnerError().Message("InnerErrorMessage").StackTrace("InnerErrorStackTrace").TypeName("InnerErrorTypeName")); var carPropertyPayload = new PayloadTestDescriptor() { PayloadElement = carProperty, PayloadEdmModel = model }; var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var personPayload = new PayloadTestDescriptor() { // This payload will be serialised to JSON so we need the annotation to mark it as a response. PayloadElement = personInstance.AddAnnotation(new PayloadFormatVersionAnnotation() { Response = true, ResponseWrapper = true }), PayloadEdmModel = model }; var errorPayload = new PayloadTestDescriptor() { PayloadElement = errorInstance, PayloadEdmModel = model, }; // response operation with a status code of 5 containing a complex instance var carPropertyPayloadOperation = carPropertyPayload.InResponseOperation(5, requestManager); // response operation with no payload and a status code of 200 var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager); // response operation with a status code of 418 containing an entity instance var personPayloadOperation = personPayload.InResponseOperation(418, requestManager, MimeTypes.ApplicationJsonLight); // response operation with a status code of 404 containing an error instance var errorPayloadOperation = errorPayload.InResponseOperation(404, requestManager); // changeset with multiple operations var twoOperationsChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation }, requestManager); // changesets with a single operation var oneOperationChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { personPayloadOperation }, requestManager); var oneErrorChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { errorPayloadOperation }, requestManager); // empty changeset var emptyChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { }, requestManager); // Empty Batch yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { }) .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")), PayloadEdmModel = emptyPayload.PayloadEdmModel, SkipTestConfiguration = (tc) => tc.IsRequest, }); // Single Operation yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); // Multiple Operations yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation, errorPayloadOperation, personPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); // Single Changeset yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); // Multiple Changesets yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, oneOperationChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); // Operations and changesets yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, carPropertyPayloadOperation, oneOperationChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, oneOperationChangeset, emptyPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { errorPayloadOperation, carPropertyPayloadOperation, emptyPayloadOperation, twoOperationsChangeset, oneOperationChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); yield return(new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload( new IMimePart[] { oneErrorChangeset, carPropertyPayloadOperation, emptyChangeset, emptyPayloadOperation, twoOperationsChangeset, personPayloadOperation, oneOperationChangeset, errorPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }); }
/// <summary> /// Constructor /// </summary> /// <param name="response">true if payload represents a response payload, false if it's a request payload.</param> /// <param name="requestManager">The request manager used to convert batch payloads.</param> public AtomObjectModelToPayloadElementConverterVisitor(bool response, IODataRequestManager requestManager) : base(response, requestManager) { }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="changeSetBoundary">The changeset boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultChangeSetBatch( IODataRequestManager requestManager, int changeSetCount, int[] changeSetSizes, bool forRequest, string changeSetBoundary = null) { Debug.Assert(changeSetCount >= 0, "batchSize >= 0"); Debug.Assert(changeSetSizes != null, "changeSetSizes != null"); Debug.Assert(changeSetSizes.Length == changeSetCount, "Size of the batch must match the length of the change set sizes array!"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[changeSetCount]; if (forRequest) { // Delete operation with no payload var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i=0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var deleteOperations = new IMimePart[changeSetSize]; for(int j=0; j< changeSetSize; ++j) { deleteOperations[j] = deleteOperation; } var changeset = BatchUtils.GetRequestChangeset(deleteOperations, requestManager); parts[i] = changeset; }; string requestBoundary = changeSetBoundary ?? "bb_multiple_request_changesets_" + changeSetCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }; } // Response operation with no payload and a status code of 200 var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager); for (int i=0; i < changeSetCount; ++i) { int changeSetSize = changeSetSizes[i]; var operationResponses = new IMimePart[changeSetSize]; for(int j=0; j< changeSetSize; ++j) { operationResponses[j] = emptyPayloadOperation; } var changeset = BatchUtils.GetResponseChangeset(operationResponses, requestManager); parts[i] = changeset; }; string responseBoundary = changeSetBoundary ?? "bb_multiple_response_changesets_" + changeSetCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }; }
/// <summary> /// Creates a batch payload with the specified number of changesets and the specified number of operations in each changeset. /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="changeSetCount">The number of changesets to create in the batch payload.</param> /// <param name="changeSetSizes">The size of each changeset.</param> /// <param name="forRequest">true if creating a batch request payload; otherwise false.</param> /// <param name="batchBoundary">The batch boundary to use; or null to use an auto-generated one.</param> /// <returns>A <see cref="PayloadTestDescriptor"/> for the batch payload.</returns> public static PayloadTestDescriptor CreateDefaultQueryBatch( IODataRequestManager requestManager, int queryCount, bool forRequest, string batchBoundary = null) { Debug.Assert(queryCount >= 0, "batchSize >= 0"); var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); IMimePart[] parts = new IMimePart[queryCount]; if (forRequest) { var queryOperation = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); for (int i = 0; i < queryCount; ++i) { parts[i] = queryOperation; }; string requestBoundary = batchBoundary ?? "bb_multiple_request_queries_" + queryCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(requestBoundary)), }; } // Response operation with no payload and a status code of 200 var emptyPayloadResponse = emptyPayload.InResponseOperation(200, requestManager); for (int i=0; i < queryCount; ++i) { parts[i] = emptyPayloadResponse; }; string responseBoundary = batchBoundary ?? "bb_multiple_response_queries_" + queryCount; return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(parts) .AddAnnotation(new BatchBoundaryAnnotation(responseBoundary)), }; }
/// <summary> /// Initializes a new instance of the ODataRequest class /// </summary> /// <param name="uriToStringConverter">The OData uri to string converter to use when sending the request</param> /// <param name="requestManager">The IODataRequestManager used for building the ODataRequest (which is needed for cloning)</param> internal ODataRequest(IODataUriToStringConverter uriToStringConverter, IODataRequestManager requestManager = null) { ExceptionUtilities.CheckArgumentNotNull(uriToStringConverter, "uriToStringConverter"); this.uriToStringConverter = uriToStringConverter; this.RequestManager = requestManager; }
/// <summary> /// Generates extra request changesets. /// </summary> /// <param name="random">For generating arbitrary changesets.</param> /// <param name="requestManager">For building changesets.</param> /// <param name="model">For adding any generated types to.</param> /// <param name="baseUri">Base uri for the changesets.</param> /// <param name="version">Maximum version of any generated types.</param> /// <returns>An array of request changesets.</returns> public static BatchRequestChangeset[] ExtraRequestChangesets( IRandomNumberGenerator random, IODataRequestManager requestManager, EdmModel model, ODataUri baseUri, ODataVersion version = ODataVersion.V4 ) { ExceptionUtilities.CheckArgumentNotNull(random, "random"); ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); var headers = new Dictionary<string, string> { { "RequestHeader", "RequestHeaderValue" } }; string mergeContentType = HttpUtilities.BuildContentType(MimeTypes.ApplicationXml, Encoding.UTF8.WebName, null); var requests = ExtraRequestChangesetOperations(random, requestManager, model, baseUri, version); List<BatchRequestChangeset> changesets = new List<BatchRequestChangeset>(); for (int x = 0; x < 5; ++x) { IEnumerable<IHttpRequest> operations = Enumerable.Range(0, random.Next(10)).Select(i => random.ChooseFrom(requests)); changesets.Add(BatchPayloadBuilder.RequestChangeset("changeset_" + Guid.NewGuid().ToString(), "", operations.ToArray())); } return changesets.ToArray(); }
/// <summary> /// Creates several PayloadTestDescriptors containing Batch Requests /// </summary> /// <param name="requestManager">Used for building the requests</param> /// <param name="model">The model to use for adding additional types.</param> /// <param name="withTypeNames">Whether or not to use full type names.</param> /// <returns>PayloadTestDescriptors</returns> public static IEnumerable<PayloadTestDescriptor> CreateBatchRequestTestDescriptors( IODataRequestManager requestManager, EdmModel model, bool withTypeNames = false) { ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); EdmEntityType personType = null; EdmComplexType carType = null; EdmEntitySet personsEntitySet = null; EdmEntityContainer container = model.EntityContainer as EdmEntityContainer; if (model != null) { //TODO: Clone EdmModel //model = model.Clone(); if (container == null) { container = new EdmEntityContainer("TestModel", "DefaultContainer"); model.AddElement(container); } personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType; carType = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType; // Create the metadata types for the entity instance used in the entity set if (carType == null) { carType = new EdmComplexType("TestModel", "TFCar"); model.AddElement(carType); carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true); carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true); } if (personType == null) { personType = new EdmEntityType("TestModel", "TFPerson"); model.AddElement(personType); personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true); personType.AddStructuralProperty("Car", carType.ToTypeReference()); container.AddEntitySet("Customers", personType); } personsEntitySet = container.AddEntitySet("People", personType); } ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null) .Property("Make", PayloadBuilder.PrimitiveValue("Ford")) .Property("Color", PayloadBuilder.PrimitiveValue("Blue")); ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance) .WithTypeAnnotation(personType); EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null) .Property("Id", PayloadBuilder.PrimitiveValue(1)) .Property("Name", PayloadBuilder.PrimitiveValue("John Doe")) .Property("Car", carInstance) .WithTypeAnnotation(personType); var carPropertyPayload = new PayloadTestDescriptor() { PayloadElement = carProperty, PayloadEdmModel = model }; var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var personPayload = new PayloadTestDescriptor() { PayloadElement = personInstance, PayloadEdmModel = model }; var root = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc")); var entityset = ODataUriBuilder.EntitySet(personsEntitySet); // Get operations var queryOperation1 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); var queryOperation2 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager); // Post operation containing a complex property var postOperation = carPropertyPayload.InRequestOperation(HttpVerb.Post, new ODataUri(new ODataUriSegment[] {root, entityset}) , requestManager, MimeTypes.ApplicationJsonLight); // Delete operation with no payload var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager); // Put operation where the payload is an EntityInstance var putOperation = personPayload.InRequestOperation(HttpVerb.Put, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager); // A changeset containing a delete with no payload and a put var twoOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { postOperation, deleteOperation }, requestManager); // A changeset containing a delete with no payload var oneOperationChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { deleteOperation }, requestManager); // A changeset containing a put, post and delete var threeOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { putOperation, postOperation, deleteOperation }, requestManager); // A changeset containing no operations var emptyChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { }, requestManager); // Empty Batch yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload() .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")), PayloadEdmModel = emptyPayload.PayloadEdmModel, SkipTestConfiguration = (tc) => !tc.IsRequest, }; // Single Operation yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1) .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; // Multiple Operations yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2) .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; // Single Changeset yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; // Multiple Changesets (different content types) yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, oneOperationChangeset, emptyChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; // Operations and changesets yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, queryOperation1, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, oneOperationChangeset, queryOperation2) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2, twoOperationsChangeset, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, threeOperationsChangeset, queryOperation2, twoOperationsChangeset, queryOperation1, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, emptyChangeset, queryOperation1, threeOperationsChangeset, queryOperation2, oneOperationChangeset) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_5")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => !tc.IsRequest, }; }
/// <summary> /// Constructor /// </summary> /// <param name="response">true if payload represents a response payload, false if it's a request payload.</param> /// <param name="requestManager">The request manager used to convert batch payloads.</param> public ObjectModelToPayloadElementWithPayloadOrderConverterVisitor(bool response, IODataRequestManager requestManager) : base(response, requestManager) { }
/// <summary> /// Generates extra request operations /// </summary> /// <param name="requestManager">RequestManager to build the operations.</param> /// <param name="baseUri">Base uri for the operations</param> /// <returns>An array of request operations.</returns> public static IMimePart[] ExtraRequestOperations(IODataRequestManager requestManager, ODataUri baseUri) { ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager"); ExceptionUtilities.CheckArgumentNotNull(baseUri, "baseUri"); var headers = new Dictionary<string, string> { { "RequestHeader", "RequestHeaderValue" } }; string mergeContentType = HttpUtilities.BuildContentType(MimeTypes.ApplicationXml, Encoding.UTF8.WebName, null); List<IHttpRequest> requests = new List<IHttpRequest>(); requests.Add(requestManager.BuildRequest(baseUri, HttpVerb.Get, headers)); var segments = baseUri.Segments; ODataUriSegment[] segmentstoadd = { ODataUriBuilder.EntitySet(new EntitySet("Set1")), ODataUriBuilder.EntityType(new EntityType("EntityType")), ODataUriBuilder.EntitySet(new EntitySet("Set2")), ODataUriBuilder.EntityType(new EntityType("EntityType2")), }; foreach (var segment in segmentstoadd) { requests.Add(requestManager.BuildRequest(new ODataUri(segments.ConcatSingle(segment)), HttpVerb.Get, headers)); } return requests.ToArray(); }
/// <summary> /// Constructor /// </summary> /// <param name="response">true if payload represents a response payload, false if it's a request payload.</param> /// <param name="requestManager">The request manager used to convert batch payloads.</param> public JsonLightObjectModelToPayloadElementConverterVisitor(bool response, IODataRequestManager requestManager) : base(response, requestManager, true, (t) => true) { }
/// <summary> /// Creates several PayloadTestDescriptors containing Batch Responses /// </summary> /// <param name="requestManager">Used for building the requests/responses.</param> /// <param name="model">The model to use for adding additional types.</param> /// <param name="withTypeNames">Whether or not to use full type names.</param> /// <returns>PayloadTestDescriptors</returns> public static IEnumerable<PayloadTestDescriptor> CreateBatchResponseTestDescriptors( IODataRequestManager requestManager, EdmModel model, bool withTypeNames = false) { EdmEntityType personType = null; EdmComplexType carType = null; if (model != null) { //TODO: CLONE for EdmModel //model = model.Clone(); personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType; carType = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType; // Create the metadata types for the entity instance used in the entity set if (carType == null) { carType = new EdmComplexType("TestModel", "TFCar"); model.AddElement(carType); carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true); carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true); } if (personType == null) { personType = new EdmEntityType("TestModel", "TFPerson"); model.AddElement(personType); personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true); personType.AddStructuralProperty("Car", carType.ToTypeReference()); EdmEntityContainer container = (EdmEntityContainer) model.EntityContainer; if (container == null) { container = new EdmEntityContainer("TestModel", "DefaultContainer"); model.AddElement(container); container.AddEntitySet("Customers", personType); container.AddEntitySet("TFPerson", personType); } } } ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null) .Property("Make", PayloadBuilder.PrimitiveValue("Ford")) .Property("Color", PayloadBuilder.PrimitiveValue("Blue")); ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance) .WithTypeAnnotation(carType); EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null) .Property("Id", PayloadBuilder.PrimitiveValue(1)) .Property("Name", PayloadBuilder.PrimitiveValue("John Doe")) .Property("Car", carInstance) .WithTypeAnnotation(personType); ODataErrorPayload errorInstance = PayloadBuilder.Error("ErrorCode") .Message("ErrorValue") .InnerError( PayloadBuilder.InnerError().Message("InnerErrorMessage").StackTrace("InnerErrorStackTrace").TypeName("InnerErrorTypeName")); var carPropertyPayload = new PayloadTestDescriptor() { PayloadElement = carProperty, PayloadEdmModel = model }; var emptyPayload = new PayloadTestDescriptor() { PayloadEdmModel = CreateEmptyEdmModel() }; var personPayload = new PayloadTestDescriptor() { // This payload will be serialised to JSON so we need the annotation to mark it as a response. PayloadElement = personInstance.AddAnnotation(new PayloadFormatVersionAnnotation() { Response = true, ResponseWrapper = true }), PayloadEdmModel = model }; var errorPayload = new PayloadTestDescriptor() { PayloadElement = errorInstance, PayloadEdmModel = model, }; // response operation with a status code of 5 containing a complex instance var carPropertyPayloadOperation = carPropertyPayload.InResponseOperation(5, requestManager); // response operation with no payload and a status code of 200 var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager); // response operation with a status code of 418 containing an entity instance var personPayloadOperation = personPayload.InResponseOperation(418, requestManager, MimeTypes.ApplicationJsonLight); // response operation with a status code of 404 containing an error instance var errorPayloadOperation = errorPayload.InResponseOperation(404, requestManager); // changeset with multiple operations var twoOperationsChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation }, requestManager); // changesets with a single operation var oneOperationChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { personPayloadOperation }, requestManager); var oneErrorChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { errorPayloadOperation }, requestManager); // empty changeset var emptyChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { }, requestManager); // Empty Batch yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { }) .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")), PayloadEdmModel = emptyPayload.PayloadEdmModel, SkipTestConfiguration = (tc) => tc.IsRequest, }; // Single Operation yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; // Multiple Operations yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation, errorPayloadOperation, personPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; // Single Changeset yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; // Multiple Changesets yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, oneOperationChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; // Operations and changesets yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, carPropertyPayloadOperation, oneOperationChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, oneOperationChangeset, emptyPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { errorPayloadOperation, carPropertyPayloadOperation, emptyPayloadOperation, twoOperationsChangeset, oneOperationChangeset }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; yield return new PayloadTestDescriptor() { PayloadElement = PayloadBuilder.BatchResponsePayload( new IMimePart[] { oneErrorChangeset, carPropertyPayloadOperation, emptyChangeset, emptyPayloadOperation, twoOperationsChangeset, personPayloadOperation, oneOperationChangeset, errorPayloadOperation }) .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")), PayloadEdmModel = model, SkipTestConfiguration = (tc) => tc.IsRequest, }; }