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); }
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); }
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)); }
/// <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) { }
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); }
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); }
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); }
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; }
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); }
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)) { }
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; }
public static string CreatePathNameForSingleton(this IEdmSingleton singleton) { return("/" + singleton.Name); }