public ODataSingletonDeserializerTest()
        {
            EdmModel model = new EdmModel();
            var employeeType = new EdmEntityType("NS", "Employee");
            employeeType.AddStructuralProperty("EmployeeId", EdmPrimitiveTypeKind.Int32);
            employeeType.AddStructuralProperty("EmployeeName", EdmPrimitiveTypeKind.String);
            model.AddElement(employeeType);

            EdmEntityContainer defaultContainer = new EdmEntityContainer("NS", "Default");
            model.AddElement(defaultContainer);

            _singleton = new EdmSingleton(defaultContainer, "CEO", employeeType);
            defaultContainer.AddElement(_singleton);

            model.SetAnnotationValue<ClrTypeAnnotation>(employeeType, new ClrTypeAnnotation(typeof(EmployeeModel)));

            _edmModel = model;
            _edmContainer = defaultContainer;

            _readContext = new ODataDeserializerContext
            {
                Path = new ODataPath(new SingletonPathSegment(_singleton)),
                Model = _edmModel,
                ResourceType = typeof(EmployeeModel)
            }; 

            _deserializerProvider = new DefaultODataDeserializerProvider();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SingletonPathSegment" /> class.
        /// </summary>
        /// <param name="singleton">The singleton being accessed.</param>
        public SingletonPathSegment(IEdmSingleton singleton)
        {
            if (singleton == null)
            {
                throw Error.ArgumentNull("singleton");
            }

            Singleton = singleton;
            SingletonName = singleton.Name;
        }
 private HttpRequestMessage GetRequest(IEdmModel model, IEdmSingleton singleton)
 {
     HttpConfiguration config = new HttpConfiguration();
     config.Routes.MapODataServiceRoute("odata", "odata", model);
     HttpRequestMessage request = new HttpRequestMessage();
     request.SetConfiguration(config);
     request.ODataProperties().PathHandler = new DefaultODataPathHandler();
     request.ODataProperties().RouteName = "odata";
     request.ODataProperties().Model = model;
     request.ODataProperties().Path = new ODataPath(new[] { new SingletonPathSegment(singleton) });
     request.RequestUri = new Uri("http://localhost/odata/Boss");
     return request;
 }
        public void TestInitialize()
        {
            this.testModel = Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            this.defaultContainer = this.testModel.EntityContainer;

            this.personSet = this.defaultContainer.FindEntitySet("Persons");
            this.personType = (IEdmEntityType)this.testModel.FindType("TestModel.Person");
            this.employeeType = (IEdmEntityType)this.testModel.FindType("TestModel.Employee");
            this.officeType = (IEdmEntityType)this.testModel.FindType("TestModel.OfficeType");
            this.addressType = (IEdmComplexType)this.testModel.FindType("TestModel.Address");
            this.metropolitanCitySet = this.defaultContainer.FindEntitySet("MetropolitanCities");
            this.metropolitanCityType = (IEdmEntityType)this.testModel.FindType("TestModel.MetropolitanCityType");
            this.boss = this.defaultContainer.FindSingleton("Boss");
            this.containedOfficeNavigationProperty = (IEdmNavigationProperty)this.metropolitanCityType.FindProperty("ContainedOffice");
            this.containedOfficeSet = (IEdmContainedEntitySet)metropolitanCitySet.FindNavigationTarget(this.containedOfficeNavigationProperty);
            this.containedMetropolitanCityNavigationProperty = (IEdmNavigationProperty)this.officeType.FindProperty("ContainedCity");
            this.containedMetropolitanCitySet = (IEdmContainedEntitySet)containedOfficeSet.FindNavigationTarget(this.containedMetropolitanCityNavigationProperty);
        }
 internal void WriteSingletonElementHeader(IEdmSingleton singleton)
 {
     this.xmlWriter.WriteStartElement(CsdlConstants.Element_Singleton);
     this.WriteRequiredAttribute(CsdlConstants.Attribute_Name, singleton.Name, EdmValueWriter.StringAsXml);
     this.WriteRequiredAttribute(CsdlConstants.Attribute_Type, singleton.EntityType().FullName(), EdmValueWriter.StringAsXml);
 }
Example #6
0
        public void CreateParametersWorks()
        {
            // Arrange
            IEdmModel     model      = EdmModelHelper.GraphBetaModel;
            ODataContext  context    = new(model);
            IEdmSingleton deviceMgmt = model.EntityContainer.FindSingleton("deviceManagement");

            Assert.NotNull(deviceMgmt);

            IEdmFunction function1 = model.SchemaElements.OfType <IEdmFunction>().First(f => f.Name == "getRoleScopeTagsByIds");

            Assert.NotNull(function1);

            IEdmFunction function2 = model.SchemaElements.OfType <IEdmFunction>().First(f => f.Name == "getRoleScopeTagsByResource");

            Assert.NotNull(function2);

            IEdmFunction function3 = model.SchemaElements.OfType <IEdmFunction>().First(f => f.Name == "roleScheduleInstances");

            Assert.NotNull(function3);

            // Act
            IList <OpenApiParameter> parameters1 = context.CreateParameters(function1);
            IList <OpenApiParameter> parameters2 = context.CreateParameters(function2);
            IList <OpenApiParameter> parameters3 = context.CreateParameters(function3);

            // Assert
            Assert.NotNull(parameters1);
            OpenApiParameter parameter1 = Assert.Single(parameters1);

            Assert.NotNull(parameters2);
            OpenApiParameter parameter2 = Assert.Single(parameters2);

            Assert.NotNull(parameters3);
            Assert.Equal(4, parameters3.Count);
            OpenApiParameter parameter3 = parameters3.First();

            string json1            = parameter1.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            string expectedPayload1 = $@"{{
  ""name"": ""ids"",
  ""in"": ""path"",
  ""description"": ""The URL-encoded JSON object"",
  ""required"": true,
  ""content"": {{
    ""application/json"": {{
      ""schema"": {{
        ""type"": ""array"",
        ""items"": {{
          ""type"": ""string""
        }}
      }}
    }}
  }}
}}";

            string json2            = parameter2.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            string expectedPayload2 = $@"{{
  ""name"": ""resource"",
  ""in"": ""path"",
  ""required"": true,
  ""schema"": {{
    ""type"": ""string"",
    ""nullable"": true
  }}
}}";

            string json3            = parameter3.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
            string expectedPayload3 = $@"{{
  ""name"": ""directoryScopeId"",
  ""in"": ""query"",
  ""schema"": {{
    ""type"": ""string"",
    ""nullable"": true
  }}
}}";

            Assert.Equal(expectedPayload1.ChangeLineBreaks(), json1);
            Assert.Equal(expectedPayload2.ChangeLineBreaks(), json2);
            Assert.Equal(expectedPayload3.ChangeLineBreaks(), json3);
        }
Example #7
0
 protected virtual void ProcessSingleton(IEdmSingleton singleton)
 {
     this.ProcessEntityContainerElement(singleton);
 }
 internal abstract void WriteSingletonElementHeader(IEdmSingleton singleton);
 /// <summary>
 ///  Initializes a new instance of the <see cref="ODataControllerActionContext" /> class.
 /// </summary>
 /// <param name="prefix">The prefix.</param>
 /// <param name="model">The Edm model.</param>
 /// <param name="controller">The controller model.</param>
 /// <param name="singleton">The associated singleton for this controller.</param>
 public ODataControllerActionContext(string prefix, IEdmModel model, ControllerModel controller, IEdmSingleton singleton)
     : this(prefix, model, controller)
 {
     Singleton  = singleton ?? throw Error.ArgumentNull(nameof(singleton));
     EntityType = singleton.EntityType();
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        public virtual bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            ActionModel action = context.Action;

            if (context.EntitySet == null && context.Singleton == null)
            {
                return(false);
            }
            IEdmNavigationSource navigationSource = context.EntitySet == null ?
                                                    (IEdmNavigationSource)context.Singleton :
                                                    (IEdmNavigationSource)context.EntitySet;

            string actionName = action.ActionMethod.Name;

            string method = Split(actionName, out string property, out string cast, out string declared);

            if (method == null || string.IsNullOrEmpty(property))
            {
                return(false);
            }

            IEdmEntityType entityType         = navigationSource.EntityType();
            IEdmModel      model              = context.Model;
            string         prefix             = context.Prefix;
            IEdmEntityType declaredEntityType = null;

            if (declared != null)
            {
                declaredEntityType = entityType.FindTypeInInheritance(model, declared) as IEdmEntityType;
                if (declaredEntityType == null)
                {
                    return(false);
                }

                if (declaredEntityType == entityType)
                {
                    declaredEntityType = null;
                }
            }

            bool          hasKeyParameter = HasKeyParameter(entityType, action);
            IEdmSingleton singleton       = navigationSource as IEdmSingleton;

            if (singleton != null && hasKeyParameter)
            {
                // Singleton, doesn't allow to query property with key
                return(false);
            }

            if (singleton == null && !hasKeyParameter)
            {
                // in entityset, doesn't allow for non-key to query property
                return(false);
            }

            IEdmProperty edmProperty = entityType.FindProperty(property);

            if (edmProperty != null && edmProperty.PropertyKind == EdmPropertyKind.Structural)
            {
                // only process structural property
                IEdmStructuredType castComplexType = null;
                if (cast != null)
                {
                    IEdmTypeReference propertyType = edmProperty.Type;
                    if (propertyType.IsCollection())
                    {
                        propertyType = propertyType.AsCollection().ElementType();
                    }
                    if (!propertyType.IsComplex())
                    {
                        return(false);
                    }

                    castComplexType = propertyType.ToStructuredType().FindTypeInInheritance(model, cast);
                    if (castComplexType == null)
                    {
                        return(false);
                    }
                }

                IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

                if (context.EntitySet != null)
                {
                    segments.Add(new EntitySetSegmentTemplate(context.EntitySet));
                }
                else
                {
                    segments.Add(new SingletonSegmentTemplate(context.Singleton));
                }

                if (hasKeyParameter)
                {
                    segments.Add(new KeySegmentTemplate(entityType));
                }
                if (declaredEntityType != null && declaredEntityType != entityType)
                {
                    segments.Add(new CastSegmentTemplate(declaredEntityType));
                }

                segments.Add(new PropertySegmentTemplate((IEdmStructuralProperty)edmProperty));

                ODataPathTemplate template = new ODataPathTemplate(segments);
                action.AddSelector(prefix, model, template);
                return(true);
            }
            else
            {
                // map to a static action like:  <method>Property(int key, string property)From<...>
                if (property == "Property" && cast == null)
                {
                    if (action.Parameters.Any(p => p.ParameterInfo.Name == "property" && p.ParameterType == typeof(string)))
                    {
                        // we find a static method mapping for all property
                        // we find a action route
                        IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

                        if (context.EntitySet != null)
                        {
                            segments.Add(new EntitySetSegmentTemplate(context.EntitySet));
                        }
                        else
                        {
                            segments.Add(new SingletonSegmentTemplate(context.Singleton));
                        }

                        if (hasKeyParameter)
                        {
                            segments.Add(new KeySegmentTemplate(entityType));
                        }
                        if (declaredEntityType != null)
                        {
                            segments.Add(new CastSegmentTemplate(declaredEntityType));
                        }

                        segments.Add(new PropertySegmentTemplate((string)null /*entityType*/));

                        ODataPathTemplate template = new ODataPathTemplate(segments);
                        action.AddSelector(prefix, model, template);
                        return(true);
                    }
                }
            }

            return(false);
        }
        private void VerifyOperation(string annotation, bool hasRestriction)
        {
            // Arrange
            IEdmModel     model   = CapabilitiesModelHelper.GetEdmModelOutline(hasRestriction ? annotation : "");
            ODataContext  context = new ODataContext(model);
            IEdmSingleton me      = model.EntityContainer.FindSingleton("Me");

            Assert.NotNull(me); // guard
            ODataPath path = new ODataPath(new ODataNavigationSourceSegment(me));

            // Act
            var patch = _operationHandler.CreateOperation(context, path);

            // Assert
            Assert.NotNull(patch);

            Assert.NotNull(patch.Parameters);
            if (hasRestriction)
            {
                // Parameters
                Assert.Equal(3, patch.Parameters.Count);

                Assert.Equal(ParameterLocation.Header, patch.Parameters[0].In);
                Assert.Equal("HeadName1", patch.Parameters[0].Name);

                Assert.Equal(ParameterLocation.Header, patch.Parameters[1].In);
                Assert.Equal("HeadName2", patch.Parameters[1].Name);

                Assert.Equal(ParameterLocation.Query, patch.Parameters[2].In);
                Assert.Equal("QueryName1", patch.Parameters[2].Name);

                // security
                Assert.NotNull(patch.Security);
                var securityRequirements = Assert.Single(patch.Security);
                var securityRequirement  = Assert.Single(securityRequirements);
                Assert.Equal("authorizationName", securityRequirement.Key.Reference.Id);
                Assert.Equal(new[] { "scopeName1", "scopeName2" }, securityRequirement.Value);

                string json = patch.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
                Assert.Contains(@"
  ""security"": [
    {
      ""authorizationName"": [
        ""scopeName1"",
        ""scopeName2""
      ]
    }
  ],".ChangeLineBreaks(), json);

                // with custom header
                Assert.Contains(@"
  ""parameters"": [
    {
      ""name"": ""HeadName1"",
      ""in"": ""header"",
      ""description"": ""Description1"",
      ""required"": true,
      ""schema"": {
        ""type"": ""string""
      },
      ""examples"": {
        ""example-1"": {
          ""description"": ""Description11"",
          ""value"": ""value1""
        }
      }
    },
    {
      ""name"": ""HeadName2"",
      ""in"": ""header"",
      ""description"": ""Description2"",
      ""schema"": {
        ""type"": ""string""
      },
      ""examples"": {
        ""example-1"": {
          ""description"": ""Description22"",
          ""value"": ""value2""
        }
      }
    },
    {
      ""name"": ""QueryName1"",
      ""in"": ""query"",
      ""description"": ""Description3"",
      ""required"": true,
      ""schema"": {
        ""type"": ""string""
      },
      ""examples"": {
        ""example-1"": {
          ""description"": ""Description33"",
          ""value"": ""value3""
        }
      }
    }".ChangeLineBreaks(), json);
            }
            else
            {
                Assert.Empty(patch.Parameters);
                Assert.Empty(patch.Security);
            }
        }
        internal static IEdmSingleton CreateAmbiguousSingletonBinding(IEdmSingleton first, IEdmSingleton second)
        {
            var ambiguous = first as AmbiguousSingletonBinding;

            if (ambiguous != null)
            {
                ambiguous.AddBinding(second);
                return(ambiguous);
            }

            return(new AmbiguousSingletonBinding(first, second));
        }
Example #13
0
 /// <summary>
 /// Initializes a new instance of <see cref="SingletonSegment"/> class.
 /// </summary>
 /// <param name="singleton">The wrapped singleton.</param>
 public SingletonSegment(IEdmSingleton singleton)
     : this(singleton, singleton?.Name)
 {
 }
Example #14
0
        public static SingletonSegment ShouldBeSingletonSegment(this ODataPathSegment segment, IEdmSingleton singleton)
        {
            Assert.NotNull(segment);
            SingletonSegment singletonSegment = Assert.IsType <SingletonSegment>(segment);

            Assert.Same(singleton, singletonSegment.Singleton);
            return(singletonSegment);
        }
Example #15
0
        static ExtensionTestBase()
        {
            var model = new EdmModel();

            Model = model;

            var person   = new EdmEntityType("TestNS", "Person");
            var personId = person.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32);

            PersonNameProp = person.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            PersonPen      = person.AddStructuralProperty("pen", EdmPrimitiveTypeKind.Binary);
            person.AddKeys(personId);
            PersonType = person;

            var address = new EdmComplexType("TestNS", "Address");

            AddrType        = address;
            ZipCodeProperty = address.AddStructuralProperty("ZipCode", EdmPrimitiveTypeKind.String);
            AddrProperty    = person.AddStructuralProperty("Addr", new EdmComplexTypeReference(address, false));

            var pencil   = new EdmEntityType("TestNS", "Pencil");
            var pencilId = pencil.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            PencilId = pencilId;
            var pid = pencil.AddStructuralProperty("Pid", EdmPrimitiveTypeKind.Int32);

            pencil.AddKeys(pencilId);

            var starPencil = new EdmEntityType("TestNS", "StarPencil", pencil);

            model.AddElement(starPencil);
            var starPencilUpper = new EdmEntityType("TestNS", "STARPENCIL");

            model.AddElement(starPencilUpper);
            StarPencil = starPencil;

            var navInfo = new EdmNavigationPropertyInfo()
            {
                Name               = "Pen",
                ContainsTarget     = false,
                Target             = pencil,
                TargetMultiplicity = EdmMultiplicity.One
            };

            PersonNavPen = person.AddUnidirectionalNavigation(navInfo);

            var navInfo2 = new EdmNavigationPropertyInfo()
            {
                Name               = "Pen2",
                ContainsTarget     = true,
                Target             = pencil,
                TargetMultiplicity = EdmMultiplicity.One
            };

            PersonNavPen2 = person.AddUnidirectionalNavigation(navInfo2);

            var container = new EdmEntityContainer("Default", "Con1");
            var personSet = container.AddEntitySet("People", person);

            PencilSet  = container.AddEntitySet("PencilSet", pencil);
            Boss       = container.AddSingleton("Boss", person);
            Bajie      = container.AddSingleton("Bajie", pencil);
            BajieUpper = container.AddSingleton("BAJIE", pencil);
            personSet.AddNavigationTarget(PersonNavPen, PencilSet);
            PeopleSet = personSet;

            var pencilSetUpper = container.AddEntitySet("PENCILSET", pencil);

            PencilSetUpper = pencilSetUpper;

            var         pencilRef   = new EdmEntityTypeReference(pencil, false);
            EdmFunction findPencil1 = new EdmFunction("TestNS", "FindPencil", pencilRef, true, null, false);

            findPencil1.AddParameter("qid", new EdmEntityTypeReference(PersonType, false));
            model.AddElement(findPencil1);
            FindPencil1P = findPencil1;

            EdmFunction findPencil = new EdmFunction("TestNS", "FindPencil", pencilRef, true, null, false);

            findPencil.AddParameter("qid", new EdmEntityTypeReference(PersonType, false));
            findPencil.AddParameter("pid", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(findPencil);
            FindPencil2P = findPencil;

            EdmFunction findPencils = new EdmFunction("TestNS", "FindPencils", new EdmCollectionTypeReference(new EdmCollectionType(pencilRef)), true, null, false);

            findPencils.AddParameter("qid", new EdmEntityTypeReference(PersonType, false));
            model.AddElement(findPencils);
            FindPencils = findPencils;

            EdmFunction findPencilsCon = new EdmFunction("TestNS", "FindPencilsCon", new EdmCollectionTypeReference(new EdmCollectionType(pencilRef)), true, null, false);

            FindPencilsCon = findPencilsCon;
            findPencilsCon.AddParameter("qid", new EdmEntityTypeReference(PersonType, false));
            model.AddElement(findPencilsCon);

            EdmFunction findPencilsConUpper = new EdmFunction("TestNS", "FindPencilsCON", new EdmCollectionTypeReference(new EdmCollectionType(pencilRef)), true, null, false);

            FindPencilsConUpper = findPencilsConUpper;
            findPencilsConUpper.AddParameter("qid", new EdmEntityTypeReference(PersonType, false));
            model.AddElement(findPencilsConUpper);

            EdmFunction findPencilsConNT = new EdmFunction("TestNT", "FindPencilsCon", new EdmCollectionTypeReference(new EdmCollectionType(pencilRef)), true, null, false);

            FindPencilsConNT = findPencilsConNT;
            findPencilsConNT.AddParameter("qid", new EdmEntityTypeReference(PersonType, false));
            model.AddElement(findPencilsConNT);

            ChangeZip = new EdmAction("TestNS", "ChangeZip", null, true, null);
            ChangeZip.AddParameter("address", new EdmComplexTypeReference(address, false));
            ChangeZip.AddParameter("newZip", EdmCoreModel.Instance.GetString(false));
            model.AddElement(ChangeZip);

            GetZip = new EdmFunction("TestNS", "GetZip", EdmCoreModel.Instance.GetString(false), true, null, true);
            GetZip.AddParameter("address", new EdmComplexTypeReference(address, false));
            model.AddElement(GetZip);

            model.AddElement(person);
            model.AddElement(address);
            model.AddElement(pencil);
            model.AddElement(container);

            var feed = new EdmAction("TestNS", "Feed", null);

            Feed = feed;
            feed.AddParameter("pid", EdmCoreModel.Instance.GetInt32(false));

            FeedImport         = container.AddActionImport("Feed", feed);
            FeedConImport      = container.AddActionImport("FeedCon", feed);
            FeedConUpperImport = container.AddActionImport("FeedCON", feed);

            var pet = new EdmEntityType("TestNS", "Pet");

            PetType = pet;
            model.AddElement(pet);
            var key1 = pet.AddStructuralProperty("key1", EdmCoreModel.Instance.GetInt32(false));
            var key2 = pet.AddStructuralProperty("key2", EdmCoreModel.Instance.GetString(false));

            pet.AddKeys(key1, key2);
            var petSet = container.AddEntitySet("PetSet", pet);

            var petCon = new EdmEntityType("TestNS", "PetCon");

            model.AddElement(petCon);
            var key1Con = pet.AddStructuralProperty("key", EdmCoreModel.Instance.GetInt32(false));
            var key2Con = pet.AddStructuralProperty("KEY", EdmCoreModel.Instance.GetString(false));

            petCon.AddKeys(key1Con, key2Con);
            var petSetCon = container.AddEntitySet("PetSetCon", petCon);

            EdmEnumType colorType = new EdmEnumType("TestNS", "Color");

            Color = colorType;
            colorType.AddMember("Red", new EdmIntegerConstant(1L));
            colorType.AddMember("Blue", new EdmIntegerConstant(2L));
            model.AddElement(colorType);
            var moonType = new EdmEntityType("TestNS", "Moon");

            MoonType = moonType;
            var color = moonType.AddStructuralProperty("color", new EdmEnumTypeReference(colorType, false));

            moonType.AddKeys(color);
            model.AddElement(moonType);
            container.AddEntitySet("MoonSet", moonType);

            var moonType2 = new EdmEntityType("TestNS", "Moon2");

            MoonType2 = moonType2;
            var color2 = moonType2.AddStructuralProperty("color", new EdmEnumTypeReference(colorType, false));
            var id     = moonType2.AddStructuralProperty("id", EdmCoreModel.Instance.GetInt32(false));

            moonType2.AddKeys(color2, id);
            model.AddElement(moonType2);
            container.AddEntitySet("MoonSet2", moonType2);

            EdmFunction findPencilCon = new EdmFunction("TestNS", "FindPencilCon", pencilRef, true, null, false);

            FindPencilCon = findPencilCon;
            findPencilCon.AddParameter("qid", new EdmEntityTypeReference(PersonType, false));
            findPencilCon.AddParameter("pid", EdmCoreModel.Instance.GetInt32(false));
            findPencilCon.AddParameter("PID", EdmCoreModel.Instance.GetInt32(false));
            model.AddElement(findPencilCon);

            EdmFunction getColorCmyk = new EdmFunction("TestNS", "GetColorCmyk", EdmCoreModel.Instance.GetString(false));

            getColorCmyk.AddParameter("co", new EdmEnumTypeReference(colorType, true));
            GetColorCmyk = getColorCmyk;
            model.AddElement(getColorCmyk);
            GetColorCmykImport = container.AddFunctionImport("GetColorCmykImport", getColorCmyk);

            EdmFunction getMixedColor = new EdmFunction("TestNS", "GetMixedColor", EdmCoreModel.Instance.GetString(false));

            getMixedColor.AddParameter("co", new EdmCollectionTypeReference(new EdmCollectionType(new EdmEnumTypeReference(colorType, true))));
            model.AddElement(getMixedColor);
            GetMixedColor = container.AddFunctionImport("GetMixedColorImport", getMixedColor);
        }
Example #16
0
        public void OperationRestrictionsTermWorksToCreateOperationForEdmAction(bool enableAnnotation)
        {
            string template = @"<?xml version=""1.0"" encoding=""utf-8""?>
<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
  <edmx:DataServices>
    <Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
      <EntityType Name=""user"" />
      <Action Name=""getMemberGroups"" IsBound=""true"">
        <Parameter Name=""bindingParameter"" Type=""NS.user"" Nullable=""false"" />
          {0}
      </Action>
      <EntityContainer Name=""GraphService"">
        <Singleton Name=""me"" Type=""NS.user"" />
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>
";

            string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.OperationRestrictions"">
  <Record>
    <PropertyValue Property=""Permissions"">
      <Collection>
        <Record>
          <PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
          <PropertyValue Property=""Scopes"">
            <Collection>
              <Record>
                <PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
              </Record>
              <Record>
                <PropertyValue Property=""Scope"" String=""User.Read.All"" />
              </Record>
              <Record>
                <PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
              </Record>
            </Collection>
          </PropertyValue>
        </Record>
        <Record>
          <PropertyValue Property=""SchemeName"" String=""Application"" />
          <PropertyValue Property=""Scopes"">
            <Collection>
              <Record>
                <PropertyValue Property=""Scope"" String=""User.Read.All"" />
              </Record>
              <Record>
                <PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
              </Record>
            </Collection>
          </PropertyValue>
        </Record>
      </Collection>
    </PropertyValue>
  </Record>
</Annotation>";

            // Arrange
            string csdl = string.Format(template, enableAnnotation ? annotation : "");

            var edmModel = CsdlReader.Parse(XElement.Parse(csdl).CreateReader());

            Assert.NotNull(edmModel);
            IEdmSingleton me = edmModel.EntityContainer.FindSingleton("me");

            Assert.NotNull(me);
            IEdmAction action = edmModel.SchemaElements.OfType <IEdmAction>().SingleOrDefault();

            Assert.NotNull(action);
            Assert.Equal("getMemberGroups", action.Name);

            ODataContext context = new ODataContext(edmModel);

            ODataPath path = new ODataPath(new ODataNavigationSourceSegment(me),
                                           new ODataOperationSegment(action));

            // Act
            var operation = _operationHandler.CreateOperation(context, path);

            // Assert
            Assert.NotNull(operation);
            Assert.NotNull(operation.Security);

            if (enableAnnotation)
            {
                Assert.Equal(2, operation.Security.Count);

                string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
                Assert.Contains(@"
  ""security"": [
    {
      ""Delegated (work or school account)"": [
        ""User.ReadBasic.All"",
        ""User.Read.All"",
        ""Directory.Read.All""
      ]
    },
    {
      ""Application"": [
        ""User.Read.All"",
        ""Directory.Read.All""
      ]
    }
  ],".ChangeLineBreaks(), json);
            }
            else
            {
                Assert.Empty(operation.Security);
            }
        }
        public void ReadRestrictionsTermWorksToCreateOperationForSingletonGetOperation(bool enableAnnotation)
        {
            string annotation = @"<Annotation Term=""Org.OData.Capabilities.V1.ReadRestrictions"">
  <Record>
    <PropertyValue Property=""Permissions"">
      <Collection>
        <Record>
          <PropertyValue Property=""SchemeName"" String=""Delegated (work or school account)"" />
          <PropertyValue Property=""Scopes"">
            <Collection>
              <Record>
                <PropertyValue Property=""Scope"" String=""User.ReadBasic.All"" />
              </Record>
              <Record>
                <PropertyValue Property=""Scope"" String=""User.Read.All"" />
              </Record>
            </Collection>
          </PropertyValue>
        </Record>
        <Record>
          <PropertyValue Property=""SchemeName"" String=""Application"" />
          <PropertyValue Property=""Scopes"">
            <Collection>
              <Record>
                <PropertyValue Property=""Scope"" String=""User.Read.All"" />
              </Record>
              <Record>
                <PropertyValue Property=""Scope"" String=""Directory.Read.All"" />
              </Record>
            </Collection>
          </PropertyValue>
        </Record>
      </Collection>
    </PropertyValue>
    <PropertyValue Property=""Description"" String=""A brief description of GET '/me' request."" />
    <PropertyValue Property=""CustomHeaders"">
      <Collection>
        <Record>
          <PropertyValue Property=""Name"" String=""odata-debug"" />
          <PropertyValue Property=""Description"" String=""Debug support for OData services"" />
          <PropertyValue Property=""Required"" Bool=""false"" />
          <PropertyValue Property=""ExampleValues"">
            <Collection>
              <Record>
                <PropertyValue Property=""Value"" String=""html"" />
                <PropertyValue Property=""Description"" String=""Service responds with self-contained..."" />
              </Record>
              <Record>
                <PropertyValue Property=""Value"" String=""json"" />
                <PropertyValue Property=""Description"" String=""Service responds with JSON document..."" />
              </Record>
            </Collection>
          </PropertyValue>
        </Record>
      </Collection>
    </PropertyValue>
  </Record>
</Annotation>";

            // Arrange
            var edmModel = GetEdmModel(enableAnnotation ? annotation : "");

            Assert.NotNull(edmModel);
            IEdmSingleton me = edmModel.EntityContainer.FindSingleton("Me");

            Assert.NotNull(me);

            ODataContext context = new ODataContext(edmModel);

            ODataPath path = new ODataPath(new ODataNavigationSourceSegment(me));

            // Act
            var operation = _operationHandler.CreateOperation(context, path);

            // Assert
            Assert.NotNull(operation);
            Assert.NotNull(operation.Security);

            if (enableAnnotation)
            {
                Assert.Equal(2, operation.Security.Count);

                string json = operation.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
                Assert.Contains(@"
  ""security"": [
    {
      ""Delegated (work or school account)"": [
        ""User.ReadBasic.All"",
        ""User.Read.All""
      ]
    },
    {
      ""Application"": [
        ""User.Read.All"",
        ""Directory.Read.All""
      ]
    }
  ],".ChangeLineBreaks(), json);

                // with custom header
                Assert.Contains(@"
  ""parameters"": [
    {
      ""name"": ""odata-debug"",
      ""in"": ""header"",
      ""description"": ""Debug support for OData services"",
      ""schema"": {
        ""type"": ""string""
      },
      ""examples"": {
        ""example-1"": {
          ""description"": ""Service responds with self-contained..."",
          ""value"": ""html""
        },
        ""example-2"": {
          ""description"": ""Service responds with JSON document..."",
          ""value"": ""json""
        }
      }
    },
    {".ChangeLineBreaks(), json);
            }
            else
            {
                Assert.Empty(operation.Security);
            }
        }
        /// <summary>
        /// Create the collection of <see cref="OpenApiTag"/> object.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <returns>The created collection of <see cref="OpenApiTag"/> object.</returns>
        public static IList <OpenApiTag> CreateTags(this ODataContext context)
        {
            Utils.CheckArgumentNull(context, nameof(context));

            // The value of tags is an array of Tag Objects.
            // For an OData service the natural groups are entity sets and singletons,
            // so the tags array contains one Tag Object per entity set and singleton in the entity container.

            // A Tag Object has to contain the field name, whose value is the name of the entity set or singleton,
            // and it optionally can contain the field description, whose value is the value of the unqualified annotation
            // Core.Description of the entity set or singleton.
            if (context.Tags != null)
            {
                return(context.Tags);
            }

            IList <OpenApiTag> tags = new List <OpenApiTag>();

            if (context.EntityContainer != null)
            {
                foreach (IEdmEntityContainerElement element in context.Model.EntityContainer.Elements)
                {
                    switch (element.ContainerElementKind)
                    {
                    case EdmContainerElementKind.EntitySet:     // entity set
                        IEdmEntitySet entitySet = (IEdmEntitySet)element;
                        tags.Add(new OpenApiTag
                        {
                            Name        = entitySet.Name,
                            Description = context.Model.GetDescriptionAnnotation(entitySet)
                        });
                        break;

                    case EdmContainerElementKind.Singleton:     // singleton
                        IEdmSingleton singleton = (IEdmSingleton)element;
                        tags.Add(new OpenApiTag
                        {
                            Name        = singleton.Name,
                            Description = context.Model.GetDescriptionAnnotation(singleton)
                        });
                        break;

                    // The tags array can contain additional Tag Objects for other logical groups,
                    // e.g. for action imports or function imports that are not associated with an entity set.
                    case EdmContainerElementKind.ActionImport:     // Action Import
                        OpenApiTag actionImportTag = context.CreateOperationImportTag((IEdmActionImport)element);
                        if (actionImportTag != null)
                        {
                            tags.Add(actionImportTag);
                        }
                        break;

                    case EdmContainerElementKind.FunctionImport:     // Function Import
                        OpenApiTag functionImportTag = context.CreateOperationImportTag((IEdmFunctionImport)element);
                        if (functionImportTag != null)
                        {
                            tags.Add(functionImportTag);
                        }
                        break;
                    }
                }
            }

            return(tags);
        }
Example #19
0
        public void CreateLinksForCollectionValuedNavigationProperties()
        {
            // Arrange
            IEdmModel model = EdmModelHelper.GraphBetaModel;
            OpenApiConvertSettings settings = new()
            {
                ShowLinks = true,
                ExpandDerivedTypesNavigationProperties = false
            };
            ODataContext  context   = new(model, settings);
            IEdmSingleton singleton = model.EntityContainer.FindSingleton("admin");

            Assert.NotNull(singleton);

            IEdmEntityType         singletonEntityType = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "admin");
            IEdmNavigationProperty navProperty         = singletonEntityType.DeclaredNavigationProperties().First(c => c.Name == "serviceAnnouncement");
            IEdmNavigationProperty navProperty2        = navProperty.ToEntityType().DeclaredNavigationProperties().First(c => c.Name == "messages");
            ODataPath path = new(
                new ODataNavigationSourceSegment(singleton),
                new ODataNavigationPropertySegment(navProperty),
                new ODataNavigationPropertySegment(navProperty2));

            // Act
            IDictionary <string, OpenApiLink> links = context.CreateLinks(
                entityType: navProperty2.ToEntityType(),
                entityName: singletonEntityType.Name,
                entityKind: navProperty2.PropertyKind.ToString(),
                path: path);

            // Assert
            Assert.NotNull(links);
            Assert.Equal(6, links.Count);

            // Links will reference Operations and OperationImports
            Assert.Collection(links,
                              item =>
            {
                Assert.Equal("archive", item.Key);
                Assert.Equal("admin.serviceAnnouncement.messages.archive", item.Value.OperationId);
            },
                              item =>
            {
                Assert.Equal("favorite", item.Key);
                Assert.Equal("admin.serviceAnnouncement.messages.favorite", item.Value.OperationId);
            },
                              item =>
            {
                Assert.Equal("markRead", item.Key);
                Assert.Equal("admin.serviceAnnouncement.messages.markRead", item.Value.OperationId);
            },
                              item =>
            {
                Assert.Equal("markUnread", item.Key);
                Assert.Equal("admin.serviceAnnouncement.messages.markUnread", item.Value.OperationId);
            },
                              item =>
            {
                Assert.Equal("unarchive", item.Key);
                Assert.Equal("admin.serviceAnnouncement.messages.unarchive", item.Value.OperationId);
            },
                              item =>
            {
                Assert.Equal("unfavorite", item.Key);
                Assert.Equal("admin.serviceAnnouncement.messages.unfavorite", item.Value.OperationId);
            });
        }
        private void VerifyMediaEntityPutOperation(string annotation, bool enableOperationId)
        {
            // Arrange
            IEdmModel model = MediaEntityGetOperationHandlerTests.GetEdmModel(annotation);
            OpenApiConvertSettings settings = new OpenApiConvertSettings
            {
                EnableOperationId = enableOperationId
            };

            ODataContext  context = new ODataContext(model, settings);
            IEdmEntitySet todos   = model.EntityContainer.FindEntitySet("Todos");
            IEdmSingleton me      = model.EntityContainer.FindSingleton("me");

            Assert.NotNull(todos);

            IEdmEntityType         todo = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "Todo");
            IEdmStructuralProperty sp   = todo.StructuralProperties().First(c => c.Name == "Logo");
            ODataPath path = new ODataPath(new ODataNavigationSourceSegment(todos),
                                           new ODataKeySegment(todos.EntityType()),
                                           new ODataStreamPropertySegment(sp.Name));

            IEdmEntityType         user        = model.SchemaElements.OfType <IEdmEntityType>().First(c => c.Name == "user");
            IEdmNavigationProperty navProperty = user.NavigationProperties().First(c => c.Name == "photo");
            ODataPath path2 = new ODataPath(new ODataNavigationSourceSegment(me),
                                            new ODataNavigationPropertySegment(navProperty),
                                            new ODataStreamContentSegment());

            // Act
            var putOperation  = _operationalHandler.CreateOperation(context, path);
            var putOperation2 = _operationalHandler.CreateOperation(context, path2);

            // Assert
            Assert.NotNull(putOperation);
            Assert.NotNull(putOperation2);
            Assert.Equal("Update Logo for Todo in Todos", putOperation.Summary);
            Assert.Equal("Update media content for the navigation property photo in me", putOperation2.Summary);
            Assert.NotNull(putOperation.Tags);
            Assert.NotNull(putOperation2.Tags);

            var tag  = Assert.Single(putOperation.Tags);
            var tag2 = Assert.Single(putOperation2.Tags);

            Assert.Equal("Todos.Todo", tag.Name);
            Assert.Equal("me.profilePhoto", tag2.Name);

            Assert.NotNull(putOperation.Responses);
            Assert.NotNull(putOperation2.Responses);
            Assert.Equal(2, putOperation.Responses.Count);
            Assert.Equal(2, putOperation2.Responses.Count);
            Assert.Equal(new[] { "204", "default" }, putOperation.Responses.Select(r => r.Key));
            Assert.Equal(new[] { "204", "default" }, putOperation2.Responses.Select(r => r.Key));

            if (!string.IsNullOrEmpty(annotation))
            {
                Assert.Equal(2, putOperation.RequestBody.Content.Keys.Count);
                Assert.True(putOperation.RequestBody.Content.ContainsKey("image/png"));
                Assert.True(putOperation.RequestBody.Content.ContainsKey("image/jpeg"));
                Assert.Equal("The logo image.", putOperation.Description);

                Assert.Equal(1, putOperation2.RequestBody.Content.Keys.Count);
                Assert.True(putOperation2.RequestBody.Content.ContainsKey(Constants.ApplicationOctetStreamMediaType));
            }
            else
            {
                Assert.Equal(1, putOperation.RequestBody.Content.Keys.Count);
                Assert.Equal(1, putOperation2.RequestBody.Content.Keys.Count);
                Assert.True(putOperation.RequestBody.Content.ContainsKey(Constants.ApplicationOctetStreamMediaType));
                Assert.True(putOperation2.RequestBody.Content.ContainsKey(Constants.ApplicationOctetStreamMediaType));
            }

            if (enableOperationId)
            {
                Assert.Equal("Todos.Todo.UpdateLogo", putOperation.OperationId);
                Assert.Equal("me.UpdatePhotoContent", putOperation2.OperationId);
            }
            else
            {
                Assert.Null(putOperation.OperationId);
                Assert.Null(putOperation2.OperationId);
            }
        }
 internal ODataControllerActionContext(string prefix, IEdmModel model, IEdmSingleton singleton)
     : this(prefix, model)
 {
     Singleton = singleton;
 }
Example #22
0
            private void WriteProperty(OdcmClass odcmClass, IEdmSingleton singleton)
            {
                var odcmProperty = new OdcmProperty(singleton.Name)
                {
                    Class = odcmClass,
                    Type = ResolveType(singleton.EntityType().Name, singleton.EntityType().Namespace),
                    IsLink = true
                };

                AddVocabularyAnnotations(odcmProperty, singleton);

                odcmClass.Properties.Add(odcmProperty);
            }
Example #23
0
 private HttpRequest GetRequest(IEdmModel model, IEdmSingleton singleton)
 /// <summary>
 /// Initializes a new instance of the <see cref="SingletonSegmentTemplate" /> class.
 /// </summary>
 /// <param name="singleton">The Edm singleton.</param>
 public SingletonSegmentTemplate(IEdmSingleton singleton)
     : this(new SingletonSegment(singleton))
 {
 }
Example #25
0
        public static AndConstraint <SingletonSegment> ShouldBeSingletonSegment(this ODataPathSegment segment, IEdmSingleton singleton)
        {
            segment.Should().BeOfType <SingletonSegment>();
            SingletonSegment singletonSegment = segment.As <SingletonSegment>();

            singletonSegment.Singleton.Should().BeSameAs(singleton);
            return(new AndConstraint <SingletonSegment>(singletonSegment));
        }
        private bool TryGetSingleton(string singletonName, out IEdmSingleton singleton)
        {
            if (singletonName.Contains("/"))
                singletonName = singletonName.Split('/').First();

            singleton = _model.SchemaElements
                .Where(x => x.SchemaElementKind == EdmSchemaElementKind.EntityContainer)
                .SelectMany(x => (x as IEdmEntityContainer).Singletons())
                .BestMatch(x => x.Name, singletonName, _session.Pluralizer);

            return singleton != null;
        }
Example #27
0
 public static string CreatePathNameForSingleton(this IEdmSingleton singleton)
 {
     return("/" + singleton.Name);
 }