internal override IEdmTypeReference GetReturnType(IEdmOperationImport operationImport)
        {
            if (operationImport != null && operationImport.Operation.ReturnType != null)
            {
                return this.ResolveTypeReference(operationImport.Operation.ReturnType);
            }

            return null;
        }
Esempio n. 2
0
        private static IEnumerable<IEdmOperationParameter> GetNonBindingParameters(IEdmOperationImport operation)
        {
            IEnumerable<IEdmOperationParameter> functionParameters = operation.Operation.Parameters;
            if (operation.Operation.IsBound)
            {
                // skip the binding parameter(first one by convention) for matching.
                functionParameters = functionParameters.Skip(1);
            }

            return functionParameters;
        }
Esempio n. 3
0
        /// <summary>
        /// Gets the target entity set for the given operation import.
        /// </summary>
        /// <param name="operationImport">The operation import.</param>
        /// <param name="sourceEntitySet">The source entity set.</param>
        /// <param name="model">The model.</param>
        /// <returns>The target entity set of the operation import or null if it could not be determined.</returns>
        internal static IEdmEntitySetBase GetTargetEntitySet(this IEdmOperationImport operationImport, IEdmEntitySetBase sourceEntitySet, IEdmModel model)
        {
            IEdmEntitySetBase targetEntitySet;

            if (operationImport.TryGetStaticEntitySet(model, out targetEntitySet))
            {
                return(targetEntitySet);
            }

            if (sourceEntitySet == null)
            {
                return(null);
            }

            if (operationImport.Operation.IsBound && operationImport.Operation.Parameters.Any())
            {
                IEdmOperationParameter parameter;
                Dictionary <IEdmNavigationProperty, IEdmPathExpression> path;
                IEnumerable <EdmError> errors;

                if (operationImport.TryGetRelativeEntitySetPath(model, out parameter, out path, out errors))
                {
                    IEdmEntitySetBase currentEntitySet = sourceEntitySet;

                    foreach (var navigation in path)
                    {
                        currentEntitySet = currentEntitySet.FindNavigationTarget(navigation.Key, navigation.Value) as IEdmEntitySetBase;
                        if (currentEntitySet is IEdmUnknownEntitySet)
                        {
                            return(currentEntitySet);
                        }
                    }

                    return(currentEntitySet);
                }
                else
                {
                    if (errors.Any(
                            e => e.ErrorCode == EdmErrorCode.InvalidPathFirstPathParameterNotMatchingFirstParameterName))
                    {
                        throw ExceptionUtil.CreateSyntaxError();
                    }
                }
            }

            return(null);
        }
Esempio n. 4
0
        public void MetadataDocumentWithODataAnnotationsWriterTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildODataAnnotationTestModel(false);

            // NamedStream
            IEdmEntityType personType = model.FindType("TestModel.PersonType") as IEdmEntityType;

            this.Assert.IsNotNull(personType, "Expected to find the person type.");

            // MIME types
            IEdmProperty nameProperty = personType.DeclaredProperties.Where(p => p.Name == "Name").Single();

            model.SetMimeType(nameProperty, "text/plain");

            IEdmProperty    addressProperty = personType.DeclaredProperties.Where(p => p.Name == "Address").Single();
            IEdmComplexType addressType     = addressProperty.Type.Definition as IEdmComplexType;

            this.Assert.IsNotNull(addressType, "Expected address to have a complex type.");
            IEdmProperty zipProperty = addressType.DeclaredProperties.Where(p => p.Name == "Zip").Single();

            model.SetMimeType(zipProperty, "text/plain");

            IEnumerable <IEdmOperationImport> functionGroup = model.EntityContainer.FindOperationImports("ServiceOperation1");
            IEdmOperationImport functionImport = functionGroup.Single() as IEdmOperationImport;

            this.Assert.IsNotNull(functionImport, "Expected to find the function import.");
            model.SetMimeType(functionImport.Operation, "img/jpeg");

            MetadataWriterTestDescriptor[] testDescriptors = new MetadataWriterTestDescriptor[]
            {
                new MetadataWriterTestDescriptor(this.Settings)
                {
                    EdmVersion = EdmVersion.V40,
                    Model      = model,
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.DefaultFormatConfigurationsWithIndent
                .Where(tc => tc.Synchronous && !tc.IsRequest),
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration, this.Logger);
            });
        }
        /// <summary>
        /// Load operation imports from model's metadata provider.
        /// </summary>
        /// <param name="qualifiedName">The name of the entity set to be loaded.</param>
        /// <returns>Operation imports that are loaded.</returns>
        internal List <IEdmOperationImport> LazyLoadServiceOperationImports(string qualifiedName)
        {
            List <IEdmOperationImport> operationImports = new List <IEdmOperationImport>();

            OperationWrapper operationWrapper = this.model.MetadataProvider.TryResolveServiceOperation(qualifiedName);

            if (operationWrapper != null)
            {
                IEdmOperationImport foundOperationImport = this.model.EnsureDefaultEntityContainer().EnsureOperationImport(operationWrapper);
                if (foundOperationImport != null)
                {
                    operationImports.Add(foundOperationImport);
                }
            }
            else
            {
                var operationWrapperQaulified = this.model.MetadataProvider.TryResolveServiceOperation(this.containerName + "." + qualifiedName);
                if (operationWrapperQaulified != null)
                {
                    IEdmOperationImport foundOperationImport = this.model.EnsureDefaultEntityContainer().EnsureOperationImport(operationWrapperQaulified);
                    if (foundOperationImport != null)
                    {
                        operationImports.Add(foundOperationImport);
                    }
                }
            }

            // metadata interface in addition to the action provider interface.
            if (this.model.ActionProviderWrapper != null)
            {
                bool nameIsContainerQualified;
                var  operationName = this.model.MetadataProvider.GetNameFromContainerQualifiedName(qualifiedName, out nameIsContainerQualified);
                var  operation     = this.model.ActionProviderWrapper.TryResolveServiceAction(operationName, MetadataProviderUtils.GetResourceType((IEdmType)null));
                if (operation != null)
                {
                    // Only top level actions will have an operation import.
                    IEdmOperationImport foundOperationImport = this.model.EnsureDefaultEntityContainer().EnsureOperationImport(operation);
                    if (foundOperationImport != null)
                    {
                        operationImports.Add(foundOperationImport);
                    }
                }
            }

            return(operationImports);
        }
        /// <summary>
        /// Returns the return type of the given operation import group.
        /// </summary>
        /// <param name="functionImportGroup">The operation import group to get the return type from.</param>
        /// <returns>The <see cref="IEdmType"/> representing the return type fo the <paramref name="functionImportGroup"/>.</returns>
        internal override IEdmTypeReference GetReturnType(IEnumerable <IEdmOperationImport> functionImportGroup)
        {
            Debug.Assert(functionImportGroup != null, "functionImportGroup != null");

            IEdmOperationImport firstFunctionImport = functionImportGroup.FirstOrDefault();

            Debug.Assert(firstFunctionImport != null, "firstFunctionImport != null");
            Debug.Assert(
                functionImportGroup.All(f =>
            {
                IEdmTypeReference returnType = this.GetReturnType(f);
                IEdmTypeReference actual     = this.GetReturnType(firstFunctionImport);
                return(returnType == null && actual == null || returnType.IsEquivalentTo(actual));
            }),
                "In a valid model, the return type of operation imports from the same operation import group should be the same.");
            return(this.GetReturnType(firstFunctionImport));
        }
Esempio n. 7
0
        public void ParameterReaderAdditionalNullValueTest()
        {
            IEdmModel           model = TestModels.BuildModelWithFunctionImport();
            IEdmOperationImport functionImport_Complex             = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Complex").First();
            IEdmOperationImport functionImport_PrimitiveCollection = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_PrimitiveCollection").First();
            IEdmOperationImport functionImport_ComplexCollection   = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_ComplexCollection").First();

            var testConfigurations = this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest);

            this.CombinatorialEngineProvider.RunCombinations(
                testConfigurations,
                (testConfiguration) =>
            {
                ODataParameterReader reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_PrimitiveCollection, testConfiguration, "{\"primitiveCollection\":null}");
                reader.Read();
                this.Assert.AreEqual("primitiveCollection", reader.Name, "Unexpected first parameter name.");
                this.Assert.IsNull(reader.Value, "Unexpected first parameter value.");
                this.Assert.AreEqual(ODataParameterReaderState.Value, reader.State, "Unexpected first parameter state.");

                reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_PrimitiveCollection, testConfiguration, "{\"primitiveCollection\":123}");
                this.Assert.ExpectedException(
                    () => reader.Read(),
                    ODataExpectedExceptions.ODataException("ODataJsonLightParameterDeserializer_NullCollectionExpected", "PrimitiveValue", "123"),
                    this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected first parameter state.");

                reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_ComplexCollection, testConfiguration, "{\"complexCollection\":null}");
                reader.Read();
                this.Assert.AreEqual("complexCollection", reader.Name, "Unexpected first parameter name.");
                this.Assert.IsNull(reader.Value, "Unexpected first parameter value.");
                this.Assert.AreEqual(ODataParameterReaderState.Value, reader.State, "Unexpected first parameter state.");

                reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_ComplexCollection, testConfiguration, "{\"complexCollection\":123}");
                this.Assert.ExpectedException(
                    () => reader.Read(),
                    ODataExpectedExceptions.ODataException("ODataJsonLightParameterDeserializer_NullCollectionExpected", "PrimitiveValue", "123"),
                    this.ExceptionVerifier);
                this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected first parameter state.");

                reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Complex, testConfiguration, "{\"complex\":null}");
                reader.Read();
                this.Assert.AreEqual("complex", reader.Name, "Unexpected first parameter name.");
                this.Assert.IsNull(reader.Value, "Unexpected first parameter value.");
                this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected first parameter state.");
            });
        }
Esempio n. 8
0
        public static IEdmModel GetEdmModel(IEdmModel edmModel, ODataPath path)
        {
            if (path.FirstSegment is EntitySetSegment entitySetSegment)
            {
                IEdmEntitySet entitySet = OeEdmClrHelper.GetEntitySet(edmModel, entitySetSegment.EntitySet.Name);
                return(edmModel.GetEdmModel(entitySet.Container));
            }

            if (path.FirstSegment is OperationImportSegment importSegment)
            {
                IEdmOperationImport operationImport = importSegment.OperationImports.Single();
                operationImport = edmModel.FindDeclaredOperationImports(operationImport.Name).Single();
                return(edmModel.GetEdmModel(operationImport.Container));
            }

            throw new InvalidOperationException("Not supported segment type " + path.FirstSegment.GetType().FullName);
        }
        /// <summary>
        ///     Create the Swagger path for the Edm operation import.
        /// </summary>
        /// <param name="operationImport">The Edm operation import</param>
        /// <returns>The <see cref="Newtonsoft.Json.Linq.JObject" /> represents the related Edm operation import.</returns>
        public static PathItem CreateSwaggerPathForOperationImport(IEdmOperationImport operationImport)
        {
            if (operationImport == null)
            {
                return(new PathItem());
            }

            var isFunctionImport  = operationImport is IEdmFunctionImport;
            var swaggerParameters = new List <Parameter>();

            foreach (var parameter in operationImport.Operation.Parameters)
            {
                swaggerParameters.Parameter(parameter.Name, isFunctionImport ? "path" : "body", "parameter: " + parameter.Name, parameter.Type.Definition);
            }

            var swaggerResponses = new Dictionary <string, Response>();

            if (operationImport.Operation.ReturnType == null)
            {
                swaggerResponses.Response("204", "Empty response");
            }
            else
            {
                swaggerResponses.Response("200", "Response from " + operationImport.Name, operationImport.Operation.ReturnType.Definition);
            }

            var swaggerOperationImport = new Operation()
                                         .Summary("Call operation import  " + operationImport.Name)
                                         .OperationId(operationImport.Name + (isFunctionImport ? "_FunctionImportGet" : "_ActionImportPost"))
                                         .Description("Call operation import  " + operationImport.Name)
                                         .Tags(isFunctionImport ? "Function Import" : "Action Import");

            if (swaggerParameters.Count > 0)
            {
                swaggerOperationImport.Parameters(swaggerParameters);
            }
            swaggerOperationImport.Responses(swaggerResponses.DefaultErrorResponse());

            return(isFunctionImport ? new PathItem
            {
                get = swaggerOperationImport
            } : new PathItem
            {
                post = swaggerOperationImport
            });
        }
Esempio n. 10
0
        public void ParameterReaderIgnoreMissingMultipleNullableParameterTest()
        {
            IEdmModel           model          = TestModels.BuildModelWithFunctionImport();
            IEdmOperationImport functionImport = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_MultipleNullableParameters").Single();

            var parameterValues = new[]
            {
                "\"p1\" : \"AAEC\"",
                "\"p2\" : true",
                "\"p3\" : 1",
                "\"p5\" : \"2012-05-25T09:00:42.5018138-07:00\"",
                "\"p6\" : 79228162514264337593543950335",
                "\"p7\" : \"INF\"",
                "\"p8\" : \"446806b7-7d7f-4e60-9e2b-bc28d9671a4f\"",
                "\"p9\" : \"32767\"",
                "\"p10\" : 2147483647",
                "\"p11\" : 0",
                "\"p12\" : \"1\"",
                "\"p13\" : \"0.01\"",
                "\"p14\" : { type: \"Point\", coordinates: [ -122.107711791992, 47.6472206115723 ], crs: { type: \"name\", properties: { name: \"EPSG:4326\" } } }",
                "\"p15\" : \"foo\"",
                "\"p16\" : { @odata.type: \"#TestModel.ComplexTypeWithNullableProperties\", IntegerProperty: 1 }",
                "\"p17\" : \"enumType1_value2\"", // supports reading enum values without validation
            };

            var multipleParameterTestCases = parameterValues.Combinations(false, new[] { 1, 2, 16 }).ToArray();

            this.CombinatorialEngineProvider.RunCombinations(
                multipleParameterTestCases,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest == true),
                (testCase, testConfiguration) =>
            {
                string payload = "{" + string.Join(",", testCase) + "}";

                var reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, payload);
                foreach (var parameter in testCase)
                {
                    this.Assert.IsTrue(reader.Read(), "Read() should not fail for payload " + payload);
                    this.Assert.AreEqual(ODataParameterReaderState.Value, reader.State, "State should be Value.");
                }

                this.Assert.IsFalse(reader.Read(), "Read() should fail after reading all parameters");
                this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "State should be Complete.");
            });
        }
Esempio n. 11
0
        public void FindOperationImportInExtendedContainer()
        {
            string mainModelxml = @"<?xml version=""1.0"" encoding=""utf-16""?>
<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
  <edmx:Reference Uri=""http://host/schema/Location.xml"">
    <edmx:Include Namespace=""Namespace1"" Alias=""A1"" />
  </edmx:Reference>
  <edmx:DataServices>
    <Schema Namespace=""Namespace0"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
        <EntityContainer Name=""DefaultContainer0"" Extends=""Namespace1.Container_sub"">
        </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>";
            string model1xml    = @"<?xml version=""1.0"" encoding=""utf-16""?>
<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
  <edmx:DataServices>
    <Schema Namespace=""Namespace1"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">  
        <Function Name=""Function1"">
            <ReturnType Type=""Edm.Int16"" />
        </Function>
        <EntityContainer Name=""Container_sub"">
            <FunctionImport Name=""FunctionImport1"" Function=""Namespace1.Function1""/>
        </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>";

            IEnumerable <EdmError> errors;
            IEdmModel model1;
            bool      parsed = CsdlReader.TryParse(XmlReader.Create(new StringReader(model1xml)), out model1, out errors);

            Assert.IsTrue(parsed);

            IEdmModel mainModel;

            parsed = CsdlReader.TryParse(XmlReader.Create(new StringReader(mainModelxml)), new IEdmModel[] { model1 }, out mainModel, out errors);
            Assert.IsTrue(parsed);

            IEnumerable <IEdmOperationImport> operationImports1 = mainModel.FindDeclaredOperationImports("FunctionImport1");
            IEdmOperationImport operationImport1 = operationImports1.Single();
            IEdmOperationImport operationImport1FromContainer = mainModel.EntityContainer.FindOperationImportsExtended("FunctionImport1").Single();

            Assert.AreEqual("FunctionImport1", operationImport1.Name);
        }
Esempio n. 12
0
        /// <summary>
        /// Create the Swagger path for the Edm operation import.
        /// </summary>
        /// <param name="operationImport">The Edm operation import</param>
        /// <returns>The <see cref="Newtonsoft.Json.Linq.JObject"/> represents the related Edm operation import.</returns>
        public static JObject CreateSwaggerPathForOperationImport(IEdmOperationImport operationImport)
        {
            if (operationImport == null)
            {
                return(new JObject());
            }

            bool   isFunctionImport  = operationImport is IEdmFunctionImport;
            JArray swaggerParameters = new JArray();

            foreach (var parameter in operationImport.Operation.Parameters)
            {
                swaggerParameters.Parameter(parameter.Name, isFunctionImport ? "path" : "body",
                                            "parameter: " + parameter.Name, parameter.Type.Definition);
            }

            JObject swaggerResponses = new JObject();

            if (operationImport.Operation.ReturnType == null)
            {
                swaggerResponses.Response("204", "Empty response");
            }
            else
            {
                swaggerResponses.Response("200", "Response from " + operationImport.Name,
                                          operationImport.Operation.ReturnType.Definition);
            }

            JObject swaggerOperationImport = new JObject()
                                             .Summary("Call operation import  " + operationImport.Name)
                                             .OperationId(operationImport.Name + (isFunctionImport ? "_FunctionImportGet" : "_ActionImportPost"))
                                             .Description("Call operation import  " + operationImport.Name)
                                             .Tags(isFunctionImport ? "Function Import" : "Action Import");

            if (swaggerParameters.Count > 0)
            {
                swaggerOperationImport.Parameters(swaggerParameters);
            }
            swaggerOperationImport.Responses(swaggerResponses.DefaultErrorResponse());

            return(new JObject()
            {
                { isFunctionImport ? "get" : "post", swaggerOperationImport }
            });
        }
Esempio n. 13
0
        public void BuildPathWithFunctionImport()
        {
            ODataUri odataUri = new ODataUri();

            odataUri.ServiceRoot = new Uri("http://gobbledygook/");
            IEdmOperationImport functionImport         = HardCodedTestModel.TestModel.EntityContainer.FindOperationImports("GetPet1").Single();
            IEdmEntitySetReferenceExpression reference = functionImport.EntitySet as IEdmEntitySetReferenceExpression;

            OperationSegmentParameter[] parameters = new OperationSegmentParameter[] { new OperationSegmentParameter("id", new ConstantNode(1, "1")) };
            odataUri.Path = new ODataPath(new OperationImportSegment(
                                              new IEdmOperationImport[] { functionImport },
                                              reference.ReferencedEntitySet,
                                              parameters));
            ODataUriBuilder odataUriBuilder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Uri             actual          = odataUriBuilder.BuildUri();

            Assert.Equal(new Uri("http://gobbledygook/GetPet1(id=1)"), actual);
        }
Esempio n. 14
0
        public void BuildPathWithFunctionImport()
        {
            ODataUri odataUri = new ODataUri();

            odataUri.ServiceRoot = new Uri("http://gobbledygook/");
            IEdmOperationImport functionImport = HardCodedTestModel.TestModel.EntityContainer.FindOperationImports("GetPet1").Single();
            IEdmEntitySetBase   entitySet;

            Assert.True(functionImport.TryGetStaticEntitySet(HardCodedTestModel.TestModel, out entitySet));
            OperationSegmentParameter[] parameters = { new OperationSegmentParameter("id", new ConstantNode(1, "1")) };
            odataUri.Path = new ODataPath(new OperationImportSegment(
                                              new [] { functionImport },
                                              entitySet,
                                              parameters));
            Uri actual = odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses);

            Assert.Equal(new Uri("http://gobbledygook/GetPet1(id=1)"), actual);
        }
        internal override void WriteOperationImportAttributes(IEdmOperationImport operationImport, string operationAttributeName)
        {
            this.WriteRequiredAttribute(CsdlConstants.Attribute_Name, operationImport.Name, EdmValueWriter.StringAsXml);
            this.WriteRequiredAttribute(operationAttributeName, operationImport.Operation.FullName(), EdmValueWriter.StringAsXml);

            if (operationImport.EntitySet != null)
            {
                var pathExpression = operationImport.EntitySet as IEdmPathExpression;
                if (pathExpression != null)
                {
                    this.WriteOptionalAttribute(CsdlConstants.Attribute_EntitySet, pathExpression.PathSegments, PathAsXml);
                }
                else
                {
                    throw new InvalidOperationException(Strings.EdmModel_Validator_Semantic_OperationImportEntitySetExpressionIsInvalid(operationImport.Name));
                }
            }
        }
Esempio n. 16
0
        public IAsyncEnumerable <Object> GetAsyncEnumerable(ODataUri odataUri, Stream?requestStream, OeRequestHeaders headers, Object dataContext, CancellationToken cancellationToken, out bool isScalar)
        {
            isScalar = true;
            var importSegment = (OperationImportSegment)odataUri.Path.LastSegment;
            IReadOnlyList <KeyValuePair <String, Object?> > parameters = OeOperationHelper.GetParameters(_edmModel, importSegment, odataUri.ParameterAliasNodes, requestStream, headers.ContentType);

            IEdmOperationImport operationImport = importSegment.OperationImports.Single();
            IEdmEntitySet?      entitySet       = OeOperationHelper.GetEntitySet(operationImport);

            if (entitySet == null)
            {
                if (operationImport.Operation.ReturnType == null)
                {
                    return(_dataAdapter.OperationAdapter.ExecuteProcedureNonQuery(dataContext, operationImport.Name, parameters));
                }

                Type returnType = _edmModel.GetClrType(operationImport.Operation.ReturnType.Definition);
                if (operationImport.Operation.ReturnType.IsCollection())
                {
                    isScalar   = false;
                    returnType = typeof(IEnumerable <>).MakeGenericType(returnType);
                }

                if (_edmModel.IsDbFunction(operationImport.Operation))
                {
                    return(_dataAdapter.OperationAdapter.ExecuteFunctionPrimitive(dataContext, operationImport.Name, parameters, returnType, cancellationToken));
                }
                else
                {
                    return(_dataAdapter.OperationAdapter.ExecuteProcedurePrimitive(dataContext, operationImport.Name, parameters, returnType, cancellationToken));
                }
            }

            isScalar = false;
            Db.OeEntitySetAdapter entitySetAdapter = _dataAdapter.EntitySetAdapters.Find(entitySet);
            if (_edmModel.IsDbFunction(operationImport.Operation))
            {
                return(_dataAdapter.OperationAdapter.ExecuteFunctionReader(dataContext, operationImport.Name, parameters, entitySetAdapter));
            }
            else
            {
                return(_dataAdapter.OperationAdapter.ExecuteProcedureReader(dataContext, operationImport.Name, parameters, entitySetAdapter));
            }
        }
Esempio n. 17
0
        public void Cant_SetFunctionTitle_OnNonBindableFunctions()
        {
            // Arrange
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");

            function.Returns <int>();
            function.Title = "My Function";

            // Act
            IEdmModel           model          = builder.GetEdmModel();
            IEdmOperationImport functionImport = model.EntityContainer.OperationImports().OfType <IEdmFunctionImport>().Single();

            Assert.NotNull(functionImport);
            OperationTitleAnnotation functionTitleAnnotation = model.GetOperationTitleAnnotation(functionImport.Operation);

            // Assert
            Assert.Null(functionTitleAnnotation);
        }
        private IEdmOperationImport FindParameterizedOperationImport(string parameterizedName, Func <string, IEnumerable <IEdmOperationImport> > findFunctions, Func <IEnumerable <IEdmOperationImport>, IEdmOperationImport> ambiguityCreator)
        {
            IEnumerable <IEdmOperationImport> matchingFunctions = findFunctions(parameterizedName);

            if (matchingFunctions.Count() == 0)
            {
                return(null);
            }

            if (matchingFunctions.Count() == 1)
            {
                return(matchingFunctions.First());
            }
            else
            {
                IEdmOperationImport ambiguous = ambiguityCreator(matchingFunctions);
                return(ambiguous);
            }
        }
        /// <summary>
        /// Gets the target entity set for the given operation import.
        /// </summary>
        /// <param name="operationImport">The operation import.</param>
        /// <param name="sourceEntitySet">The source entity set.</param>
        /// <param name="model">The model.</param>
        /// <returns>The target entity set of the operation import or null if it could not be determined.</returns>
        internal static IEdmEntitySetBase GetTargetEntitySet(this IEdmOperationImport operationImport, IEdmEntitySetBase sourceEntitySet, IEdmModel model)
        {
            IEdmEntitySet targetEntitySet;

            if (operationImport.TryGetStaticEntitySet(out targetEntitySet))
            {
                return(targetEntitySet);
            }

            if (sourceEntitySet == null)
            {
                return(null);
            }

            if (operationImport.Operation.IsBound && operationImport.Operation.Parameters.Any())
            {
                IEdmOperationParameter parameter;
                IEnumerable <IEdmNavigationProperty> path;
                IEnumerable <EdmError> errors;

                if (operationImport.TryGetRelativeEntitySetPath(model, out parameter, out path, out errors))
                {
                    IEdmEntitySetBase currentEntitySet = sourceEntitySet;
                    foreach (var navigation in path)
                    {
                        currentEntitySet = currentEntitySet.FindNavigationTarget(navigation) as IEdmEntitySetBase;
                        if (currentEntitySet == null || currentEntitySet is IEdmUnknownEntitySet)
                        {
                            return(currentEntitySet);
                        }
                    }

                    return(currentEntitySet);
                }
                else
                {
                    bool foundSyntaxError = !errors.Any(e => e.ErrorCode == EdmErrorCode.InvalidPathFirstPathParameterNotMatchingFirstParameterName);
                    ExceptionUtil.ThrowSyntaxErrorIfNotValid(foundSyntaxError);
                }
            }

            return(null);
        }
        private IEdmOperationImport CreateAmbiguousOperationImport(IEnumerable <IEdmOperationImport> operations)
        {
            Debug.Assert(operations.Count() > 1, "Should not make an ambiguous thing with fewer than two items");
            IEnumerator <IEdmOperationImport> operationEnumerator = operations.GetEnumerator();

            operationEnumerator.MoveNext();
            IEdmOperationImport first = operationEnumerator.Current;

            operationEnumerator.MoveNext();
            IEdmOperationImport             second    = operationEnumerator.Current;
            AmbiguousOperationImportBinding ambiguous = new AmbiguousOperationImportBinding(first, second);

            while (operationEnumerator.MoveNext())
            {
                ambiguous.AddBinding(operationEnumerator.Current);
            }

            return(ambiguous);
        }
        /// <summary>
        /// Creates an <see cref="ODataParameterWriter" /> to write a parameter payload.
        /// </summary>
        /// <param name="functionImport">The function import whose parameters will be written.</param>
        /// <returns>The created parameter writer.</returns>
        public ODataParameterWriter CreateODataParameterWriter(IEdmOperationImport functionImport)
        {
            IEdmOperation operation = functionImport != null ? functionImport.Operation : null;

            if (this.testConfiguration.Synchronous)
            {
                return(new ODataParameterWriterTestWrapper(this.messageWriter.CreateODataParameterWriter(operation), this.testConfiguration));
            }
            else
            {
#if SILVERLIGHT
                throw new TaupoNotSupportedException("This test is not supported in aSynchronous mode in Silverlight");
#else
                return(this.messageWriter.CreateODataParameterWriterAsync(operation)
                       .ContinueWith(task => new ODataParameterWriterTestWrapper(task.Result, this.testConfiguration), TaskContinuationOptions.ExecuteSynchronously)
                       .WaitForResult());
#endif
            }
        }
        public void CreateResponseForEdmFunctionReturnCorrectResponses(bool isFunctionImport)
        {
            // Arrange
            string       operationName = "GetPersonWithMostFriends";
            IEdmModel    model         = EdmModelHelper.TripServiceModel;
            ODataContext context       = new ODataContext(model);

            // Act
            OpenApiResponses responses;

            if (isFunctionImport)
            {
                IEdmOperationImport operationImport = model.EntityContainer.OperationImports().First(o => o.Name == operationName);
                Assert.NotNull(operationImport); // guard
                responses = context.CreateResponses(operationImport);
            }
            else
            {
                IEdmOperation operation = model.SchemaElements.OfType <IEdmOperation>().First(o => o.Name == operationName);
                Assert.NotNull(operation); // guard
                responses = context.CreateResponses(operation);
            }

            // Assert
            Assert.NotNull(responses);
            Assert.NotEmpty(responses);
            Assert.Equal(2, responses.Count);
            Assert.Equal(new string[] { "200", "default" }, responses.Select(r => r.Key));

            OpenApiResponse response = responses["200"];

            Assert.NotNull(response.Content);
            OpenApiMediaType mediaType = response.Content["application/json"];

            Assert.NotNull(mediaType.Schema);
            Assert.True(mediaType.Schema.Nullable);
            Assert.Null(mediaType.Schema.Reference);
            Assert.NotNull(mediaType.Schema.AnyOf);
            var anyOf = Assert.Single(mediaType.Schema.AnyOf);

            Assert.Equal("Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person", anyOf.Reference.Id);
        }
Esempio n. 23
0
        /// <summary>
        /// Creates an <see cref="ODataCollectionReader" /> to read a collection of primitive or complex values (as result of a service operation invocation).
        /// </summary>
        /// <param name="producingFunctionImport">The function import producing the collection to be read.</param>
        /// <returns>The created collection reader.</returns>
        public ODataCollectionReader CreateODataCollectionReader(IEdmOperationImport producingFunctionImport)
        {
            IEdmTypeReference itemTypeReference = ((IEdmCollectionTypeReference)producingFunctionImport.Operation.ReturnType).GetCollectionItemType();

            if (this.testConfiguration.Synchronous)
            {
                return(new ODataCollectionReaderTestWrapper(this.messageReader.CreateODataCollectionReader(itemTypeReference), this.testConfiguration));
            }
            else
            {
#if SILVERLIGHT || WINDOWS_PHONE
                throw new PlatformNotSupportedException("Asynchronous reading is only supported on desktop");
#else
                return(this.messageReader.CreateODataCollectionReaderAsync(itemTypeReference).ContinueWith(
                           task => new ODataCollectionReaderTestWrapper(task.Result, this.testConfiguration),
                           TaskContinuationOptions.ExecuteSynchronously)
                       .WaitForResult());
#endif
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Creates an <see cref="ODataParameterReader" /> to read the parameters for <paramref name="expectedFunctionImport"/>.
        /// </summary>
        /// <param name="expectedFunctionImport">The expected function import whose parameters are being read.</param>
        /// <returns>The created parameter reader.</returns>
        public ODataParameterReaderTestWrapper CreateODataParameterReader(IEdmOperationImport expectedFunctionImport)
        {
            IEdmOperation operation = expectedFunctionImport != null ? expectedFunctionImport.Operation : null;

            if (this.testConfiguration.Synchronous)
            {
                return(new ODataParameterReaderTestWrapper(this.messageReader.CreateODataParameterReader(operation), this.testConfiguration));
            }
            else
            {
#if SILVERLIGHT || WINDOWS_PHONE
                throw new PlatformNotSupportedException("Asynchronous reading is only supported on desktop");
#else
                return(this.messageReader.CreateODataParameterReaderAsync(operation).ContinueWith(
                           task => new ODataParameterReaderTestWrapper(task.Result, this.testConfiguration),
                           TaskContinuationOptions.ExecuteSynchronously)
                       .WaitForResult());
#endif
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Get the Uri Swagger path for Edm operation import.
        /// </summary>
        /// <param name="routePrefix">The route prefix.</param>
        /// <param name="operationImport">The Edm operation import.</param>
        /// <returns>
        /// The <see cref="string" /> path represents the related Edm operation import.
        /// </returns>
        public static string GetPathForOperationImport(string routePrefix, IEdmOperationImport operationImport)
        {
            Contract.Requires(routePrefix != null);
            Contract.Requires(operationImport != null);

            var swaggerOperationImportPath = routePrefix.AppendPathSegment(operationImport.Name) + "(";

            if (operationImport.IsFunctionImport())
            {
                swaggerOperationImportPath = operationImport.Operation?.Parameters?.Aggregate(swaggerOperationImportPath, (current, parameter) => current + parameter.Name + "=" + "{" + parameter.Name + "},");
            }
            Contract.Assume(swaggerOperationImportPath != null);
            if (swaggerOperationImportPath.EndsWith(",", StringComparison.Ordinal))
            {
                swaggerOperationImportPath = swaggerOperationImportPath.Substring(0, swaggerOperationImportPath.Length - 1);
            }
            swaggerOperationImportPath += ")";

            return(swaggerOperationImportPath);
        }
Esempio n. 26
0
        static string GetPathForOperationImport(IEdmOperationImport operationImport)
        {
            string swaggerOperationImportPath = "/" + operationImport.Name + "(";

            if (operationImport.IsFunctionImport())
            {
                foreach (var parameter in operationImport.Operation.Parameters)
                {
                    swaggerOperationImportPath += parameter.Name + "=" + "{" + parameter.Name + "},";
                }
            }
            if (swaggerOperationImportPath.EndsWith(","))
            {
                swaggerOperationImportPath = swaggerOperationImportPath.Substring(0,
                                                                                  swaggerOperationImportPath.Length - 1);
            }
            swaggerOperationImportPath += ")";

            return(swaggerOperationImportPath);
        }
Esempio n. 27
0
        public void ParameterReaderIgnoreMissingNullableParameterTest()
        {
            IEdmModel           model          = TestModels.BuildModelWithFunctionImport();
            IEdmOperationImport functionImport = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_NullablePrimitive").First();

            this.CombinatorialEngineProvider.RunCombinations(
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest == true),
                (testConfiguration) =>
            {
                // Reading an empty payload should not fail
                ODataParameterReaderTestWrapper reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration);
                this.Assert.IsFalse(reader.Read(), "Read() should return false on an empty payload.");
                this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "State should be completed.");

                // Reading a parameter payload with no parameter should not fail
                reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, "{}");
                this.Assert.IsFalse(reader.Read(), "Read() should return false on a parameter payload with no parameter.");
                this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "State should be completed.");
            });
        }
Esempio n. 28
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FunctionImportSegmentTemplate" /> class.
        /// </summary>
        /// <param name="segment">The input function import segment.</param>
        public FunctionImportSegmentTemplate(OperationImportSegment segment)
        {
            if (segment == null)
            {
                throw Error.ArgumentNull(nameof(segment));
            }

            IEdmOperationImport operationImport = segment.OperationImports.First();

            if (!operationImport.IsFunctionImport())
            {
                throw new ODataException(Error.Format(SRResources.SegmentShouldBeKind, "FunctionImport", "FunctionImportSegmentTemplate"));
            }

            FunctionImport = (IEdmFunctionImport)operationImport;

            NavigationSource = segment.EntitySet;

            ParameterMappings = segment.Parameters.BuildParameterMappings(operationImport.Name);
        }
Esempio n. 29
0
        public static IEdmModel GetEdmModel(this IEdmModel edmModel, ODataPath path)
        {
            if (path.FirstSegment is EntitySetSegment entitySetSegment)
            {
                return(edmModel.GetEdmModel(entitySetSegment.EntitySet));
            }

            if (path.FirstSegment is OperationImportSegment importSegment)
            {
                IEdmOperationImport operationImport = importSegment.OperationImports.Single();
                return(edmModel.GetEdmModel(operationImport.Container));
            }

            if (path.FirstSegment == null)
            {
                throw new InvalidOperationException("Invalid path first sgment is null");
            }

            throw new InvalidOperationException("Not supported segment type " + path.FirstSegment.GetType().FullName);
        }
        /// <summary>
        /// Write payload kind to message.
        /// </summary>
        /// <param name="messageWriter">Message writer to write payload to.</param>
        /// <param name="payloadKind">The kind of payload we are writing.</param>
        /// <param name="payload">The payload to write.</param>
        /// <param name="functionImport">Function import whose parameters are to be written when the payload kind is Parameters.</param>
        /// <returns>The object read after writing.</returns>
        public ODataItem WriteMessage(ODataMessageWriterTestWrapper messageWriter, ODataMessageReaderTestWrapper messageReader, ODataPayloadKind payloadKind, object payload, IEdmOperationImport functionImport = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(messageWriter, "messageWriter");
            ExceptionUtilities.CheckArgumentNotNull(messageReader, "messageReader");

            switch (payloadKind)
            {
                case ODataPayloadKind.Feed:
                    this.WriteTopLevelFeed(messageWriter, messageReader, (ODataFeed)payload);
                    break;
                case ODataPayloadKind.Entry:
                    this.WriteTopLevelEntry(messageWriter, messageReader, (ODataEntry)payload);
                    break;
                default:
                    ExceptionUtilities.Assert(false, "The payload kind '{0}' is not yet supported by ObjectModelWriteReadStreamer.", payloadKind);
                    break;
            }

            return readItems.SingleOrDefault();
        }
Esempio n. 31
0
        /// <summary>
        /// Gets the parameter value.
        /// </summary>
        /// <param name="segment">The function import segment</param>
        /// <param name="parameterName">The parameter name</param>
        /// <returns>The parameter value</returns>
        public static object GetParameterValue(this OperationImportSegment segment, string parameterName)
        {
            if (segment == null)
            {
                throw Error.ArgumentNull("segment");
            }

            if (String.IsNullOrEmpty(parameterName))
            {
                throw Error.ArgumentNullOrEmpty("parameterName");
            }

            if (!segment.OperationImports.Any() || !segment.OperationImports.First().IsFunctionImport())
            {
                throw Error.Argument("segment", SRResources.OperationImportSegmentMustBeFunction);
            }

            OperationSegmentParameter parameter = segment.Parameters.FirstOrDefault(p => p.Name == parameterName);

            if (parameter == null)
            {
                throw Error.Argument("parameterName", SRResources.FunctionParameterNotFound, parameterName);
            }

            object value = TranslateNode(parameter.Value);

            if (value == null || value is ODataNullValue)
            {
                IEdmOperationImport    operation          = segment.OperationImports.First();
                IEdmOperationParameter operationParameter = operation.Operation.Parameters.First(p => p.Name == parameterName);
                Contract.Assert(operationParameter != null);

                if (!operationParameter.Type.IsNullable)
                {
                    throw new ODataException(String.Format(CultureInfo.InvariantCulture,
                                                           SRResources.NullOnNonNullableFunctionParameter, operationParameter.Type.FullName()));
                }
            }

            return(value);
        }
        /// <summary>
        /// Checks if the operation import should be included.
        /// </summary>
        /// <param name="operationImport">Operation import.</param>
        /// <param name="excludedTypes">A collection of excluded types.</param>
        /// <returns>true if the operation import should be included, otherwise false.</returns>
        public bool IsOperationImportIncluded(IEdmOperationImport operationImport, ICollection <string> excludedTypes)
        {
            IEnumerable <IEdmOperationParameter> parameters = operationImport.Operation.Parameters;

            foreach (var parameter in parameters)
            {
                if (excludedTypes.Contains(parameter.Type.FullName()))
                {
                    return(false);
                }
            }

            string returnType = operationImport.Operation.ReturnType?.FullName();

            if (excludedTypes.Contains(returnType))
            {
                return(false);
            }

            return(true);
        }
        private static string GetEntitySetString(IEdmOperationImport operationImport)
        {
            if (operationImport.EntitySet != null)
            {
                var entitySetReference = operationImport.EntitySet as IEdmEntitySetReferenceExpression;
                if (entitySetReference != null)
                {
                    return(entitySetReference.ReferencedEntitySet.Name);
                }
                else
                {
                    var pathExpression = operationImport.EntitySet as IEdmPathExpression;
                    if (pathExpression != null)
                    {
                        return(EdmModelCsdlSchemaWriter.PathAsXml(pathExpression.Path));
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Creates an <see cref="ODataParameterReader" /> to read the parameters for <paramref name="expectedFunctionImport"/>.
        /// </summary>
        /// <param name="expectedFunctionImport">The expected function import whose parameters are being read.</param>
        /// <returns>The created parameter reader.</returns>
        public ODataParameterReaderTestWrapper CreateODataParameterReader(IEdmOperationImport expectedFunctionImport)
        {
            IEdmOperation operation = expectedFunctionImport != null ? expectedFunctionImport.Operation : null;
            if (this.testConfiguration.Synchronous)
            {
                return new ODataParameterReaderTestWrapper(this.messageReader.CreateODataParameterReader(operation), this.testConfiguration);
            }
            else
            {
#if SILVERLIGHT || WINDOWS_PHONE
                throw new PlatformNotSupportedException("Asynchronous reading is only supported on desktop");
#else
                return this.messageReader.CreateODataParameterReaderAsync(operation).ContinueWith(
                    task => new ODataParameterReaderTestWrapper(task.Result, this.testConfiguration),
                    TaskContinuationOptions.ExecuteSynchronously)
                    .WaitForResult();
#endif
            }
        }
        /// <summary>
        /// Reads an <see cref="ODataProperty"/> as message payload.
        /// </summary>
        /// <param name="producingFunctionImport">The function import producing the collection to be read.</param>
        /// <returns>The property read from the payload.</returns>
        public ODataProperty ReadProperty(IEdmOperationImport producingFunctionImport)
        {
            if (this.testConfiguration.Synchronous)
            {
                return this.messageReader.ReadProperty(producingFunctionImport.Operation.ReturnType);
            }
            else
            {
#if SILVERLIGHT || WINDOWS_PHONE
                throw new PlatformNotSupportedException("Asynchronous reading is only supported on desktop");
#else
                return this.messageReader.ReadPropertyAsync(producingFunctionImport.Operation.ReturnType).WaitForResult();
#endif
            }
        }
Esempio n. 36
0
File: Program.cs Progetto: TomDu/lab
        static string GetPathForOperationImport(IEdmOperationImport operationImport)
        {
            string swaggerOperationImportPath = "/" + operationImport.Name + "(";
            if (operationImport.IsFunctionImport())
            {
                foreach (var parameter in operationImport.Operation.Parameters)
                {
                    swaggerOperationImportPath += parameter.Name + "=" + "{" + parameter.Name + "},";
                }
            }
            if (swaggerOperationImportPath.EndsWith(","))
            {
                swaggerOperationImportPath = swaggerOperationImportPath.Substring(0,
                    swaggerOperationImportPath.Length - 1);
            }
            swaggerOperationImportPath += ")";

            return swaggerOperationImportPath;
        }
        /// <summary>
        /// Creates an <see cref="ODataCollectionReader" /> to read a collection of primitive or complex values (as result of a service operation invocation).
        /// </summary>
        /// <param name="producingFunctionImport">The function import producing the collection to be read.</param>
        /// <returns>The created collection reader.</returns>
        public ODataCollectionReader CreateODataCollectionReader(IEdmOperationImport producingFunctionImport)
        {
            IEdmTypeReference itemTypeReference = ((IEdmCollectionTypeReference)producingFunctionImport.Operation.ReturnType).GetCollectionItemType();
            if (this.testConfiguration.Synchronous)
            {
                return new ODataCollectionReaderTestWrapper(this.messageReader.CreateODataCollectionReader(itemTypeReference), this.testConfiguration);
            }
            else
            {
#if SILVERLIGHT || WINDOWS_PHONE
                throw new PlatformNotSupportedException("Asynchronous reading is only supported on desktop");
#else
                return this.messageReader.CreateODataCollectionReaderAsync(itemTypeReference).ContinueWith(
                    task => new ODataCollectionReaderTestWrapper(task.Result, this.testConfiguration),
                    TaskContinuationOptions.ExecuteSynchronously)
                    .WaitForResult();
#endif
            }
        }
Esempio n. 38
0
 public static void VerifyServiceOperationsAreEqual(IEdmOperationImport expected, IEdmOperationImport actual, AssertionHandler assert)
 {
     if (expected == null)
     {
         assert.IsNull(actual, "The service operation should be null.");
     }
     else
     {
         assert.IsNotNull(actual, "The service operation should not be null.");
         assert.AreEqual(expected.Name, actual.Name, "The service operation names are different.");
     }
 }
 private static void ValidateProcedureEntitySetPath(IEdmModel model, IEdmOperationImport operationImport, ProcedureConfiguration procedure)
 {
     IEdmOperationParameter procedureParameter;
     IEnumerable<IEdmNavigationProperty> navPath;
     IEnumerable<EdmError> edmErrors;
     if (procedure.EntitySetPath != null && !operationImport.TryGetRelativeEntitySetPath(model, out procedureParameter, out navPath, out edmErrors))
     {
         throw Error.InvalidOperation(SRResources.ProcedureHasInvalidEntitySetPath, String.Join("/", procedure.EntitySetPath), procedure.FullyQualifiedName);
     }
 }
Esempio n. 40
0
        /// <summary>
        /// Creates an ODataParameterReader with the given input.
        /// </summary>
        /// <param name="model">Model containing the function import.</param>
        /// <param name="functionImport">function import whose parameters are being read.</param>
        /// <param name="testConfiguration">test configuration.</param>
        /// <param name="payload">optional parameter payload.</param>
        /// <returns>Returns the created ODataParameterReader</returns>
        internal static ODataParameterReaderTestWrapper CreateODataParameterReader(IEdmModel model, IEdmOperationImport functionImport, ReaderTestConfiguration testConfiguration, string payload = null)
        {
            // TODO: ODataLib test item: Add new ODataPayloadElement for parameters payload
            // Once the bug is fixed, we should generate the parameters payload from the new ODataPayloadElement to make
            // tests in this file format agnostic.
            TestStream messageStream;
            if (payload != null)
            {
                messageStream = new TestStream(new MemoryStream(Encoding.UTF8.GetBytes(payload)));
            }
            else
            {
                messageStream = new TestStream();
            }

            TestMessage message = TestReaderUtils.CreateInputMessageFromStream(messageStream, testConfiguration, ODataPayloadKind.Parameter, /*customContentTypeHeader*/null, /*urlResolver*/null);
            ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(message, model, testConfiguration);
            return messageReader.CreateODataParameterReader(functionImport);
        }
            /// <summary>
            /// Read parameters as the message content.
            /// </summary>
            /// <param name="messageReader">The message reader to use for reading.</param>
            /// <param name="functionImport">The function import to pass to the parameter reader.</param>
            /// <returns>A ComplexInstance representing parameters.</returns>
            public object ReadParameters(ODataMessageReaderTestWrapper messageReader, IEdmOperationImport functionImport)
            {
                // TODO: ODataLib test item: Add new ODataPayloadElement for parameters payload
                ODataParameterReader parameterReader = messageReader.CreateODataParameterReader(functionImport);
                ODataParameters odataParameters = new ODataParameters();
                List<ODataProperty> parameters = new List<ODataProperty>();
                try
                {
                    // read the start of the parameters
                    this.assert.AreEqual(ODataParameterReaderState.Start, parameterReader.State, "Reader states don't match.");
                    while (parameterReader.Read())
                    {
                        switch (parameterReader.State)
                        {
                            case ODataParameterReaderState.Value:
                                odataParameters.Add(new KeyValuePair<string,object>(parameterReader.Name, parameterReader.Value));
                                break;

                            case ODataParameterReaderState.Entry:
                                ODataReader entryReader = parameterReader.CreateEntryReader();
                                entryReader.Read();
                                this.assert.AreEqual(ODataReaderState.EntryStart, entryReader.State, "Reader states don't match.");
                                odataParameters.Add(new KeyValuePair<string,object>(parameterReader.Name, this.ReadEntry(entryReader)));
                                this.assert.AreEqual(ODataReaderState.EntryEnd, entryReader.State, "Reader states don't match.");
                                this.assert.IsFalse(entryReader.Read(), "Read() should return false after EntryEnd.");
                                this.assert.AreEqual(ODataReaderState.Completed, entryReader.State, "Reader states don't match.");
                                break;

                            case ODataParameterReaderState.Feed:
                                ODataReader feedReader = parameterReader.CreateFeedReader();
                                feedReader.Read();
                                this.assert.AreEqual(ODataReaderState.FeedStart, feedReader.State, "Reader states don't match.");
                                odataParameters.Add(new KeyValuePair<string,object>(parameterReader.Name, this.ReadFeed(feedReader)));
                                this.assert.AreEqual(ODataReaderState.FeedEnd, feedReader.State, "Reader states don't match.");
                                this.assert.IsFalse(feedReader.Read(), "Read() should return false after EntryEnd.");
                                this.assert.AreEqual(ODataReaderState.Completed, feedReader.State, "Reader states don't match.");
                                break;

                            case ODataParameterReaderState.Collection:
                                ODataCollectionReader collectionReader = parameterReader.CreateCollectionReader();
                                odataParameters.Add(new KeyValuePair<string,object>(parameterReader.Name, this.ReadCollection(collectionReader)));
                                break;

                            default:
                                this.assert.Fail("Unexpected state: " + parameterReader.State);
                                break;
                        }
                    }

                    this.assert.AreEqual(ODataParameterReaderState.Completed, parameterReader.State, "Reader states don't match.");

                    return odataParameters;
                }
                catch (Exception e)
                {
                    if (ExceptionUtilities.IsCatchable(e))
                    {
                        this.assert.AreEqual(ODataParameterReaderState.Exception, parameterReader.State, "Expected the reader to be in 'Exception' state.");
                    }

                    throw;
                }
            }
Esempio n. 42
0
 private void AddOperationImport(string name, IEdmOperationImport function)
 {
     List<IEdmOperationImport> operationImport;
     if (this.operationImports.TryGetValue(name, out operationImport))
     {
         operationImport.Add(function);
     }
     else
     {
         this.operationImports.Add(name, new List<IEdmOperationImport>() { function });
     }
 }
Esempio n. 43
0
 /// <summary>
 /// Creates an ODataParameterReader with the given input.
 /// </summary>
 /// <param name="model">Model containing the function import.</param>
 /// <param name="functionImport">function import whose parameters are being read.</param>
 /// <param name="testConfiguration">test configuration.</param>
 /// <param name="payload">optional parameter payload.</param>
 /// <returns>Returns the created ODataParameterReader</returns>
 private ODataParameterReaderTestWrapper CreateParameterReaderForRequestOrResponse(IEdmModel model, IEdmOperationImport functionImport, ReaderTestConfiguration testConfiguration, string payload = null)
 {
     if (testConfiguration.IsRequest)
     {
         return CreateODataParameterReader(model, functionImport, testConfiguration, payload);
     }
     else
     {
         this.Assert.ExpectedException(
             () => CreateODataParameterReader(model, functionImport, testConfiguration, payload),
             ODataExpectedExceptions.ODataException("ODataMessageReader_ParameterPayloadInResponse"),
             this.ExceptionVerifier);
         return null;
     }
 }
        /// <summary>
        /// Get the Uri Swagger path for Edm operation import.
        /// </summary>
        /// <param name="operationImport">The Edm operation import.</param>
        /// <returns>The <see cref="System.String"/> path represents the related Edm operation import.</returns>
        public static string GetPathForOperationImport(IEdmOperationImport operationImport)
        {
            if (operationImport == null)
            {
                return String.Empty;
            }

            string swaggerOperationImportPath = "/" + operationImport.Name + "(";
            if (operationImport.IsFunctionImport())
            {
                foreach (var parameter in operationImport.Operation.Parameters)
                {
                    swaggerOperationImportPath += parameter.Name + "=" + "{" + parameter.Name + "},";
                }
            }
            if (swaggerOperationImportPath.EndsWith(",", StringComparison.Ordinal))
            {
                swaggerOperationImportPath = swaggerOperationImportPath.Substring(0,
                    swaggerOperationImportPath.Length - 1);
            }
            swaggerOperationImportPath += ")";

            return swaggerOperationImportPath;
        }
        /// <summary>
        /// Writes an <see cref="ODataProperty"/> as message payload.
        /// </summary>
        /// <param name="property">The property to write.</param>
        /// <param name="producingFunctionImport">The function import which return value is being written.</param>
        public void WriteProperty(ODataProperty property, IEdmOperationImport producingFunctionImport)
        {
            if (this.testConfiguration.Synchronous)
            {
                this.messageWriter.WriteProperty(property);
            }
            else
            {
#if SILVERLIGHT
                throw new TaupoNotSupportedException("This test is not supported in aSynchronous mode in Silverlight");
#else
                this.messageWriter.WritePropertyAsync(property).Wait();
#endif
            }
        }
Esempio n. 46
0
File: Program.cs Progetto: TomDu/lab
        static JObject CreateSwaggerPathForOperationImport(IEdmOperationImport operationImport)
        {
            JArray swaggerParameters = new JArray();
            foreach (var parameter in operationImport.Operation.Parameters)
            {
                swaggerParameters.Parameter(parameter.Name, operationImport is IEdmFunctionImport ? "path" : "body",
                    "parameter: " + parameter.Name, parameter.Type.Definition);
            }

            JObject swaggerResponses = new JObject();
            if (operationImport.Operation.ReturnType == null)
            {
                swaggerResponses.Response("204", "Empty response");
            }
            else
            {
                swaggerResponses.Response("200", "Response from " + operationImport.Name,
                    operationImport.Operation.ReturnType.Definition);
            }

            JObject swaggerOperationImport = new JObject()
                .Summary("Call operation import  " + operationImport.Name)
                .Description("Call operation import  " + operationImport.Name)
                .Tags(operationImport is IEdmFunctionImport ? "Function Import" : "Action Import");

            if (swaggerParameters.Count > 0)
            {
                swaggerOperationImport.Parameters(swaggerParameters);
            }
            swaggerOperationImport.Responses(swaggerResponses.DefaultErrorResponse());

            return new JObject()
                {
                    {operationImport is IEdmFunctionImport ? "get" : "post", swaggerOperationImport}
                };
        }
        private FunctionImport ConvertToTaupoFunctionImport(IEdmOperationImport edmFunctionImport)
        {
            var taupoFunctionImport = new FunctionImport(edmFunctionImport.Name);
            var functionImportReturnType = new FunctionImportReturnType();
            var addReturnType = false;
            if (edmFunctionImport.EntitySet != null)
            {
                IEdmEntitySet entitySet;
                if (edmFunctionImport.TryGetStaticEntitySet(out entitySet))
                {
                    functionImportReturnType.EntitySet = new EntitySetReference(entitySet.Name);
                    addReturnType = true;
                }
                else
                {
                    throw new NotSupportedException("Function import with entity set path is not supported.");
                }
            }

            if (edmFunctionImport.Operation.ReturnType != null)
            {
                functionImportReturnType.DataType = this.ConvertToTaupoDataType(edmFunctionImport.Operation.ReturnType);
                addReturnType = true;
            }

            if (addReturnType)
            {
                taupoFunctionImport.Add(functionImportReturnType);
            }

            foreach (var edmFunctionParameter in edmFunctionImport.Operation.Parameters)
            {
                FunctionParameter taupoFunctionParameter = this.ConvertToTaupoFunctionParameter(edmFunctionParameter);
                taupoFunctionImport.Parameters.Add(taupoFunctionParameter);
            }

            this.ConvertAnnotationsIntoTaupo(edmFunctionImport, taupoFunctionImport);
            return taupoFunctionImport;
        }
Esempio n. 48
0
 internal override IEdmTypeReference GetReturnType(IEdmOperationImport operationImport)
 {
     return operationImport == null ? null : operationImport.Operation.ReturnType;
 }
        /// <summary>
        /// Write payload kind to message.
        /// </summary>
        /// <param name="messageWriter">Message writer to write payload to.</param>
        /// <param name="payloadKind">The kind of payload we are writing.</param>
        /// <param name="payload">The payload to write.</param>
        /// <param name="model">The model used for writing the payloads.</param>
        /// <param name="functionImport">Function import whose parameters are to be written when the payload kind is Parameters.</param>
        public virtual void WriteMessage(
            ODataMessageWriterTestWrapper messageWriter, 
            ODataPayloadKind payloadKind, 
            object payload, 
            IEdmModel model = null,
            IEdmOperationImport functionImport = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(messageWriter, "messageReader");

            switch (payloadKind)
            {
                case ODataPayloadKind.Property:
                    messageWriter.WriteProperty((ODataProperty)payload);
                    break;

                case ODataPayloadKind.Feed:
                    this.WriteTopLevelFeed(messageWriter, (ODataFeed)payload);
                    break;

                case ODataPayloadKind.Entry:
                    this.WriteTopLevelEntry(messageWriter, (ODataEntry)payload);
                    break;

                case ODataPayloadKind.Collection:
                    this.WriteCollection(messageWriter, (ODataCollectionStart)payload);
                    break;

                case ODataPayloadKind.ServiceDocument:
                    this.WriteServiceDocument(messageWriter, (ODataServiceDocument)payload);
                    break;

                case ODataPayloadKind.MetadataDocument:
                    this.WriteMetadataDocument(messageWriter);
                    break;

                case ODataPayloadKind.Error:
                    this.WriteError(messageWriter, (ODataError)payload, true);
                    break;

                case ODataPayloadKind.EntityReferenceLink:
                    this.WriteEntityReferenceLink(messageWriter, (ODataEntityReferenceLink)payload);
                    break;

                case ODataPayloadKind.EntityReferenceLinks:
                    this.WriteEntityReferenceLinks(messageWriter, (ODataEntityReferenceLinks)payload);
                    break;

                case ODataPayloadKind.Value:
                    this.WriteValue(messageWriter, payload);
                    break;

                case ODataPayloadKind.Batch:
                    // TODO: Have to figure out product representation of batch payloads or perhaps keep it separate
                    throw new NotSupportedException("Batch not supported in ObjectModelToMessageWriter");

                case ODataPayloadKind.Parameter:
                    this.WriteParameters(messageWriter, (ODataParameters)payload, functionImport);
                    break;

                default:
                    ExceptionUtilities.Assert(false, "The payload kind '{0}' is not yet supported by MessageToObjectModelReader.", payloadKind);
                    break;
            }
        }
 /// <summary>
 /// Read a collection as the message content.
 /// </summary>
 /// <param name="messageReader">The message reader to use for reading.</param>
 /// <param name="producingFunctionImport">The function import producing the collection to be read.</param>
 /// <param name="expectedItemTypeReference">The expected item type to pass to the reader.</param>
 /// <returns>An <see cref="ODataCollectionStart"/>, possibly with annotations.</returns>
 public object ReadCollection(ODataMessageReaderTestWrapper messageReader, IEdmOperationImport producingFunctionImport, IEdmTypeReference expectedItemTypeReference)
 {
     ODataCollectionReader collectionReader = producingFunctionImport != null
         ? messageReader.CreateODataCollectionReader(producingFunctionImport)
         : messageReader.CreateODataCollectionReader(expectedItemTypeReference);
     return this.ReadCollection(collectionReader);
 }
        private void WriteParameters(ODataMessageWriterTestWrapper messageWriter, ODataParameters parameters, IEdmOperationImport functionImport)
        {
            ODataParameterWriter parameterWriter = messageWriter.CreateODataParameterWriter(functionImport);
            parameterWriter.WriteStart();
            foreach (var parameter in parameters)
            {
                ODataCollectionStart collectionStart = parameter.Value as ODataCollectionStart;
                ODataFeed feed;
                ODataEntry entry;
                if (collectionStart != null)
                {
                    ODataCollectionWriter collectionWriter = parameterWriter.CreateCollectionWriter(parameter.Key);
                    this.WriteCollection(collectionWriter, collectionStart);
                    collectionWriter.Flush();
                }
                else if ((feed = parameter.Value as ODataFeed) != null)
                {
                    this.WriteFeed(parameterWriter.CreateFeedWriter(parameter.Key), feed);
                }
                else if ((entry = parameter.Value as ODataEntry) != null)
                {
                    this.WriteEntry(parameterWriter.CreateEntryWriter(parameter.Key), entry);
                }
                else
                {
                    parameterWriter.WriteValue(parameter.Key, parameter.Value);
                }
            }

            parameterWriter.WriteEnd();
            parameterWriter.Flush();
        }
        internal static bool ResolveOperationImportFromList(string identifier, IList<string> parameterNames, IEdmModel model, out IEdmOperationImport matchingOperationImport, ODataUriResolver resolver)
        {
            IList<IEdmOperationImport> candidateMatchingOperationImports = null;
            IList<IEdmActionImport> foundActionImportsWhenLookingForFunctions = new List<IEdmActionImport>();

            try
            {
                if (parameterNames.Count > 0)
                {
                    // In this case we have to return a function so filter out actions because the number of parameters > 0.
                    candidateMatchingOperationImports = resolver.ResolveOperationImports(model, identifier).RemoveActionImports(out foundActionImportsWhenLookingForFunctions).FilterFunctionsByParameterNames(parameterNames, resolver.EnableCaseInsensitive).Cast<IEdmOperationImport>().ToList();
                }
                else
                {
                    candidateMatchingOperationImports = resolver.ResolveOperationImports(model, identifier).ToList();
                }
            }
            catch (Exception exc)
            {
                if (!ExceptionUtils.IsCatchableExceptionType(exc))
                {
                    throw;
                }

                throw new ODataException(ODataErrorStrings.FunctionOverloadResolver_FoundInvalidOperationImport(identifier), exc);
            }

            if (foundActionImportsWhenLookingForFunctions.Count > 0)
            {
                throw ExceptionUtil.CreateBadRequestError(ODataErrorStrings.RequestUriProcessor_SegmentDoesNotSupportKeyPredicates(identifier));
            }

            // If any of the things returned are an action, it better be the only thing returned, and there can't be parameters in the URL
            if (candidateMatchingOperationImports.Any(f => f.IsActionImport()))
            {
                if (candidateMatchingOperationImports.Count > 1)
                {
                    if (candidateMatchingOperationImports.Any(o => o.IsFunctionImport()))
                    {
                        throw new ODataException(ODataErrorStrings.FunctionOverloadResolver_MultipleOperationImportOverloads(identifier));
                    }
                    else
                    {
                        throw new ODataException(ODataErrorStrings.FunctionOverloadResolver_MultipleActionImportOverloads(identifier));
                    }
                }

                if (parameterNames.Count() != 0)
                {
                    throw ExceptionUtil.CreateBadRequestError(ODataErrorStrings.RequestUriProcessor_SegmentDoesNotSupportKeyPredicates(identifier));
                }

                matchingOperationImport = candidateMatchingOperationImports.Single();
                return true;
            }

            // If parameter count is zero and there is one function import whoese parameter count is zero, return this function import.
            if (candidateMatchingOperationImports.Count > 1 && parameterNames.Count == 0)
            {
                candidateMatchingOperationImports = candidateMatchingOperationImports.Where(operationImport => operationImport.Operation.Parameters.Count() == 0).ToList();
            }

            if (candidateMatchingOperationImports.Count == 0)
            {
                matchingOperationImport = null;
                return false;
            }

            if (candidateMatchingOperationImports.Count > 1)
            {
                throw new ODataException(ODataErrorStrings.FunctionOverloadResolver_MultipleOperationImportOverloads(identifier));
            }

            matchingOperationImport = candidateMatchingOperationImports.Single();

            return matchingOperationImport != null;
        }
 /// <summary>
 /// Invoke the given service operation and returns the results.
 /// </summary>
 /// <param name="serviceOperation">service operation to invoke.</param>
 /// <param name="parameters">value of parameters to pass to the service operation.</param>
 /// <returns>returns the result of the service operation. If the service operation returns void, then this should return null.</returns>
 public object InvokeServiceOperation(IEdmOperationImport serviceOperation, object[] parameters)
 {
     throw new NotSupportedException();
 }
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="model">The model used to resolve the metadata.</param>
            /// <param name="payloadElement">The payload element to get the reader metadata for.</param>
            public ReaderMetadata(IEdmModel model, ODataPayloadElement payloadElement)
            {
                var expectedTypeAnnotation = payloadElement.GetAnnotation<ExpectedTypeODataPayloadElementAnnotation>();

                // NOTE: we don't require a model for the computation of the expected type (since the expected one might be a primitive type).
                this.expectedType = GetExpectedType(expectedTypeAnnotation, model);

                // We need a model for all the other expected reader metadata
                if (model == null)
                {
                    // If the annotation specified some model dependent data (basically anything but primitive expected type)
                    // and we don't have a model, we wouldn't be able to correctly represent it here (since we need the model to resolve these)
                    // and thus we should not pass in the expected type alone, as that would be changing the intent of the annotation.
                    if (expectedTypeAnnotation != null &&
                        (expectedTypeAnnotation.EntitySet != null ||
                         expectedTypeAnnotation.EdmEntitySet != null ||
                         expectedTypeAnnotation.FunctionImport != null ||
                         expectedTypeAnnotation.ProductFunctionImport != null ||
                         expectedTypeAnnotation.MemberProperty != null ||
                         expectedTypeAnnotation.EdmProperty != null ||
                         expectedTypeAnnotation.NavigationProperty != null ||
                         expectedTypeAnnotation.EdmNavigationProperty != null ||
                         expectedTypeAnnotation.OpenMemberPropertyName != null ||
                         expectedTypeAnnotation.OwningType != null ||
                         expectedTypeAnnotation.EdmOwningType != null))
                    {
                        this.expectedType = null;
                    }

                    return;
                }

                ODataPayloadElementType elementType = payloadElement.ElementType;
                switch (elementType)
                {
                    case ODataPayloadElementType.EntityInstance:    // fall through
                    case ODataPayloadElementType.EntitySetInstance:
                        this.entitySet = GetExpectedEntitySet(expectedTypeAnnotation, model, payloadElement);
                        break;

                    case ODataPayloadElementType.DeferredLink:      // fall through
                    case ODataPayloadElementType.LinkCollection:
                        this.navigationProperty = GetExpectedNavigationProperty(expectedTypeAnnotation, model);
                        break;

                    case ODataPayloadElementType.PrimitiveMultiValueProperty:   // fall through
                    case ODataPayloadElementType.PrimitiveProperty:             // fall through
                    case ODataPayloadElementType.ComplexProperty:               // fall through
                    case ODataPayloadElementType.ComplexMultiValueProperty:     // fall through
                    case ODataPayloadElementType.EmptyCollectionProperty:
                        this.structuralProperty = GetExpectedStructuralProperty(expectedTypeAnnotation, model);
                        this.functionImport = GetExpectedFunctionImport(expectedTypeAnnotation, model);
                        break;

                    case ODataPayloadElementType.ComplexInstanceCollection:     // fall through
                    case ODataPayloadElementType.PrimitiveCollection:           // fall through
                    case ODataPayloadElementType.EmptyUntypedCollection:
                        this.functionImport = GetExpectedFunctionImport(expectedTypeAnnotation, model);
                        break;

                    case ODataPayloadElementType.ComplexInstance:
                        // NOTE: this is how we model parameter payloads
                        this.functionImport = GetExpectedFunctionImport(expectedTypeAnnotation, model);
                        break;
                }
            }
 private static bool TryParseFunctionParameters(string functionName, string parenthesisExpression, ParameterAliasValueAccessor paramAliasAccessor, IEdmOperationImport operationImport, out ICollection<OperationSegmentParameter> parsedSegementParameters)
 {
     return TryParseOperationParameters(functionName, parenthesisExpression, paramAliasAccessor, operationImport.Operation, out parsedSegementParameters);
 }
Esempio n. 56
0
 public CollectionWriterTestCase(CollectionWriterTestDescriptor.ItemDescription[] items, IEdmOperationImport functionImport)
 {
     this.items = items;
     this.functionImport = functionImport;
 }
Esempio n. 57
0
        /// <summary>
        /// Tries to find a single matching operation import for the given identifier, and parameters.
        /// </summary>
        /// <param name="identifier">The identifier from the URI.</param>
        /// <param name="parenthesisExpression">The parenthesis expression contianing parameters, if any.</param>
        /// <param name="configuration">The configuration of the parser.</param>
        /// <param name="boundParameters">The parsed parameters from the parenthesis expression.</param>
        /// <param name="matchingFunctionImport">The single matching operation import if one could be determined.</param>
        /// <returns>Whether or not a matching operation import could be found.</returns>
        private static bool TryBindingParametersAndMatchingOperationImport(string identifier, string parenthesisExpression, ODataUriParserConfiguration configuration, out ICollection<OperationSegmentParameter> boundParameters, out IEdmOperationImport matchingFunctionImport)
        {
            matchingFunctionImport = null;
            ICollection<FunctionParameterToken> splitParameters = null;
            if (!String.IsNullOrEmpty(parenthesisExpression))
            {
                if (!FunctionParameterParser.TrySplitOperationParameters(parenthesisExpression, configuration, out splitParameters))
                {
                    IEdmOperationImport possibleMatchingOperationImport = null;

                    // Look for an overload that returns an entity collection by the specified name. If so parthensis is just key parameters.
                    if (FunctionOverloadResolver.ResolveOperationImportFromList(identifier, EmptyList, configuration.Model, out possibleMatchingOperationImport, configuration.Resolver))
                    {
                        IEdmCollectionTypeReference collectionReturnType = possibleMatchingOperationImport.Operation.ReturnType as IEdmCollectionTypeReference;
                        if (collectionReturnType != null && collectionReturnType.ElementType().IsEntity())
                        {
                            matchingFunctionImport = possibleMatchingOperationImport;
                            boundParameters = null;
                            return true;
                        }
                        else
                        {
                            throw ExceptionUtil.CreateBadRequestError(ODataErrorStrings.RequestUriProcessor_SegmentDoesNotSupportKeyPredicates(identifier));
                        }
                    }

                    boundParameters = null;
                    return false;
                }
            }
            else
            {
                splitParameters = new Collection<FunctionParameterToken>();
            }

            // Resolve the specific overload.
            if (FunctionOverloadResolver.ResolveOperationImportFromList(identifier, splitParameters.Select(k => k.ParameterName).ToList(), configuration.Model, out matchingFunctionImport, configuration.Resolver))
            {
                var matchingOperation = matchingFunctionImport.Operation;
                boundParameters = FunctionCallBinder.BindSegmentParameters(configuration, matchingOperation, splitParameters);
                return true;
            }

            boundParameters = null;
            return false;
        }
Esempio n. 58
0
 /// <summary>
 /// Returns the return type of the given operation import.
 /// </summary>
 /// <param name="operationImport">The operation import to get the return type from.</param>
 /// <returns>The <see cref="IEdmType"/> representing the return type fo the <paramref name="operationImport"/>.</returns>
 internal abstract IEdmTypeReference GetReturnType(IEdmOperationImport operationImport);
Esempio n. 59
0
            private void WriteMethod(OdcmClass odcmClass, IEdmOperation operation, IEdmOperationImport operationImport = null)
            {
                var parameters = operation.IsBound
                    ? (from parameter in operation.Parameters
                       where parameter != operation.Parameters.First()
                       select parameter)
                    : (operation.Parameters);

                var isBoundToCollection = operation.IsBound && operation.Parameters.First().Type.IsCollection();

                var odcmMethod = new OdcmMethod(operation.Name, odcmClass.Namespace)
                {
                    IsComposable = operation.IsFunction() && ((IEdmFunction)operation).IsComposable,
                    IsBoundToCollection = isBoundToCollection,
                    Verbs = operation.IsAction() ? OdcmAllowedVerbs.Post : OdcmAllowedVerbs.Any,
                    Class = odcmClass
                };

                AddVocabularyAnnotations(odcmMethod, operation);

                if (operationImport != null)
                {
                    AddVocabularyAnnotations(odcmMethod, operationImport);
                }

                odcmClass.Methods.Add(odcmMethod);

                if (operation.ReturnType != null)
                {
                    odcmMethod.ReturnType = ResolveType(operation.ReturnType);
                    odcmMethod.IsCollection = operation.ReturnType.IsCollection();
                }

                var callingConvention =
                    operation.IsAction()
                        ? OdcmCallingConvention.InHttpMessageBody
                        : OdcmCallingConvention.InHttpRequestUri;

                foreach (var parameter in parameters)
                {
                    var odcmParameter = new OdcmParameter(parameter.Name)
                    {
                        CallingConvention = callingConvention,
                        Type = ResolveType(parameter.Type),
                        IsCollection = parameter.Type.IsCollection(),
                        IsNullable = parameter.Type.IsNullable
                    };

                    AddVocabularyAnnotations(odcmParameter, parameter);

                    odcmMethod.Parameters.Add(odcmParameter);
                }
            }
        /// <summary>
        /// Creates an <see cref="ODataParameterWriter" /> to write a parameter payload.
        /// </summary>
        /// <param name="functionImport">The function import whose parameters will be written.</param>
        /// <returns>The created parameter writer.</returns>
        public ODataParameterWriter CreateODataParameterWriter(IEdmOperationImport functionImport)
        {
            IEdmOperation operation = functionImport != null ? functionImport.Operation : null;
            if (this.testConfiguration.Synchronous)
            {
                return new ODataParameterWriterTestWrapper(this.messageWriter.CreateODataParameterWriter(operation), this.testConfiguration);
            }
            else
            {
#if SILVERLIGHT
                throw new TaupoNotSupportedException("This test is not supported in aSynchronous mode in Silverlight");
#else
                return this.messageWriter.CreateODataParameterWriterAsync(operation)
                    .ContinueWith(task => new ODataParameterWriterTestWrapper(task.Result, this.testConfiguration), TaskContinuationOptions.ExecuteSynchronously)
                    .WaitForResult();
#endif
            }
        }