Ejemplo n.º 1
0
        /// <inheritdoc/>
        protected override void SetParameters(OpenApiOperation operation)
        {
            base.SetParameters(operation);

            operation.Parameters.Add(new OpenApiParameter
            {
                Name        = "If-Match",
                In          = ParameterLocation.Header,
                Description = "ETag",
                Schema      = new OpenApiSchema
                {
                    Type = "string"
                }
            });

            // for collection, we should have @id in query
            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                operation.Parameters.Add(new OpenApiParameter
                {
                    Name        = "@id",
                    In          = ParameterLocation.Query,
                    Description = "Delete Uri",
                    Schema      = new OpenApiSchema
                    {
                        Type = "string"
                    }
                });
            }
        }
Ejemplo n.º 2
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            IEdmEntitySet             entitySet = NavigationSource as IEdmEntitySet;
            IEdmVocabularyAnnotatable target    = entitySet;

            if (target == null)
            {
                target = NavigationSource as IEdmSingleton;
            }

            string navigationPropertyPath = String.Join("/",
                                                        Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier));

            NavigationRestrictionsType    navigation  = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions);
            NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath);

            // verify using individual first
            if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None)
            {
                return;
            }

            if (restriction == null || restriction.Navigability == null)
            {
                // if the individual has not navigability setting, use the global navigability setting
                if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None)
                {
                    // Default navigability for all navigation properties of the annotation target.
                    // Individual navigation properties can override this value via `RestrictedProperties/Navigability`.
                    return;
                }
            }

            // So far, we only consider the non-containment
            Debug.Assert(!NavigationProperty.ContainsTarget);

            // Create the ref
            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                ODataSegment penultimateSegment = Path.Segments.Reverse().Skip(1).First();
                if (penultimateSegment is ODataKeySegment)
                {
                    // Collection-valued: DELETE ~/entityset/{key}/collection-valued-Nav/{key}/$ref
                    AddDeleteOperation(item, restriction);
                }
                else
                {
                    AddReadOperation(item, restriction);
                    AddInsertOperation(item, restriction);
                }
            }
            else
            {
                AddReadOperation(item, restriction);
                AddUpdateOperation(item, restriction);
                AddDeleteOperation(item, restriction);
            }
        }
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            IEdmEntitySet             entitySet = NavigationSource as IEdmEntitySet;
            IEdmVocabularyAnnotatable target    = entitySet;

            if (target == null)
            {
                target = NavigationSource as IEdmSingleton;
            }

            NavigationRestrictionsType navSourceRestrictionType = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions);
            NavigationRestrictionsType navPropRestrictionType   = Context.Model.GetRecord <NavigationRestrictionsType>(NavigationProperty, CapabilitiesConstants.NavigationRestrictions);

            NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties?
                                                        .FirstOrDefault(r => r.NavigationProperty == Path.NavigationPropertyPath())
                                                        ?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault();

            // Check whether the navigation property should be part of the path
            if (EdmModelHelper.NavigationRestrictionsAllowsNavigability(navSourceRestrictionType, restriction) == false ||
                EdmModelHelper.NavigationRestrictionsAllowsNavigability(navPropRestrictionType, restriction) == false)
            {
                return;
            }

            // containment: Get / (Post - Collection | Patch - Single)
            // non-containment: Get
            AddGetOperation(item, restriction);

            if (NavigationProperty.ContainsTarget)
            {
                if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    if (LastSegmentIsKeySegment)
                    {
                        UpdateRestrictionsType updateEntity = Context.Model.GetRecord <UpdateRestrictionsType>(_entityType);
                        if (updateEntity?.IsUpdatable ?? true)
                        {
                            AddUpdateOperation(item, restriction);
                        }
                    }
                    else
                    {
                        InsertRestrictionsType insert = restriction?.InsertRestrictions;
                        if (insert?.IsInsertable ?? true)
                        {
                            AddOperation(item, OperationType.Post);
                        }
                    }
                }
                else
                {
                    AddUpdateOperation(item, restriction);
                }
            }

            AddDeleteOperation(item, restriction);
        }
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            IEdmEntitySet             entitySet = NavigationSource as IEdmEntitySet;
            IEdmVocabularyAnnotatable target    = entitySet;

            if (target == null)
            {
                target = NavigationSource as IEdmSingleton;
            }

            string navigationPropertyPath = String.Join("/",
                                                        Path.Segments.OfType <ODataNavigationPropertySegment>().Select(e => e.NavigationProperty.Name));

            // contaiment: Get / (Post - Collection | Patch - Single)
            // non-containment: only Get
            NavigationRestrictions navigation = Context.Model.GetNavigationRestrictions(target);

            if (navigation == null || !navigation.IsRestrictedProperty(navigationPropertyPath))
            {
                AddOperation(item, OperationType.Get);
            }

            if (NavigationProperty.ContainsTarget)
            {
                if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    if (LastSegmentIsKeySegment)
                    {
                        // Need to check this scenario is valid or not?
                        UpdateRestrictions update = Context.Model.GetUpdateRestrictions(target);
                        if (update == null || !update.IsNonUpdatableNavigationProperty(navigationPropertyPath))
                        {
                            AddOperation(item, OperationType.Patch);
                        }
                    }
                    else
                    {
                        InsertRestrictions insert = Context.Model.GetInsertRestrictions(target);
                        if (insert == null || !insert.IsNonInsertableNavigationProperty(navigationPropertyPath))
                        {
                            AddOperation(item, OperationType.Post);
                        }
                    }
                }
                else
                {
                    UpdateRestrictions update = Context.Model.GetUpdateRestrictions(target);
                    if (update == null || !update.IsNonUpdatableNavigationProperty(navigationPropertyPath))
                    {
                        AddOperation(item, OperationType.Patch);
                    }
                }
            }
        }
        private void AddGetOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
        {
            ReadRestrictionsType read = restriction?.ReadRestrictions;

            if (read == null)
            {
                AddOperation(item, OperationType.Get);
                return;
            }

            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                // TODO: $ref also supports Get ?
                if (LastSegmentIsKeySegment)
                {
                    if (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.Readable != null)
                    {
                        if (read.ReadByKeyRestrictions.Readable.Value)
                        {
                            AddOperation(item, OperationType.Get);
                        }
                    }
                    else
                    {
                        ReadRestrictionsType readEntity = Context.Model.GetRecord <ReadRestrictionsType>(_entityType);
                        if (readEntity?.IsReadable ?? true)
                        {
                            AddOperation(item, OperationType.Get);
                        }
                    }
                }
                else
                {
                    if (read.IsReadable)
                    {
                        AddOperation(item, OperationType.Get);
                    }
                }
            }
            else
            {
                Debug.Assert(LastSegmentIsKeySegment == false);
                if (read.IsReadable)
                {
                    AddOperation(item, OperationType.Get);
                }
            }
        }
        private void AddGetOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
        {
            ReadRestrictionsType read = restriction?.ReadRestrictions;

            if (read == null)
            {
                AddOperation(item, OperationType.Get);
                return;
            }

            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                if (LastSegmentIsKeySegment)
                {
                    if (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.Readable != null)
                    {
                        if (read.ReadByKeyRestrictions.Readable.Value)
                        {
                            AddOperation(item, OperationType.Get);
                        }
                    }
                    else
                    {
                        if (read.IsReadable)
                        {
                            AddOperation(item, OperationType.Get);
                        }
                    }
                }
                else
                {
                    if (read.IsReadable)
                    {
                        AddOperation(item, OperationType.Get);
                    }
                }
            }
            else
            {
                Debug.Assert(LastSegmentIsKeySegment == false);
                if (read.IsReadable)
                {
                    AddOperation(item, OperationType.Get);
                }
            }
        }
Ejemplo n.º 7
0
        /// <inheritdoc/>
        protected override void SetParameters(OpenApiOperation operation)
        {
            base.SetParameters(operation);

            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                // Need to verify that TopSupported or others should be applyed to navigaiton source.
                // So, how about for the navigation property.
                OpenApiParameter parameter = Context.CreateTop(NavigationProperty);
                if (parameter != null)
                {
                    operation.Parameters.Add(parameter);
                }

                parameter = Context.CreateSkip(NavigationProperty);
                if (parameter != null)
                {
                    operation.Parameters.Add(parameter);
                }

                parameter = Context.CreateSearch(NavigationProperty);
                if (parameter != null)
                {
                    operation.Parameters.Add(parameter);
                }

                parameter = Context.CreateFilter(NavigationProperty);
                if (parameter != null)
                {
                    operation.Parameters.Add(parameter);
                }

                parameter = Context.CreateCount(NavigationProperty);
                if (parameter != null)
                {
                    operation.Parameters.Add(parameter);
                }

                parameter = Context.CreateOrderBy(NavigationProperty);
                if (parameter != null)
                {
                    operation.Parameters.Add(parameter);
                }
            }
        }
        protected override void SetExtensions(OpenApiOperation operation)
        {
            if (Context.Settings.EnablePagination)
            {
                if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    OpenApiObject extension = new OpenApiObject
                    {
                        { "nextLinkName", new OpenApiString("@odata.nextLink") },
                        { "operationName", new OpenApiString(Context.Settings.PageableOperationName) }
                    };

                    operation.Extensions.Add(Constants.xMsPageable, extension);
                }
            }

            base.SetExtensions(operation);
        }
        /// <inheritdoc/>
        protected override void SetBasicInfo(OpenApiOperation operation)
        {
            // Summary
            operation.Summary = "Get " + NavigationProperty.Name + " from " + NavigationSource.Name;

            // OperationId
            if (Context.Settings.EnableOperationId)
            {
                string prefix = "Get";
                if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    prefix = "List";
                }

                operation.OperationId = GetOperationId(prefix);
            }

            base.SetBasicInfo(operation);
        }
        private void AddDeleteOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
        {
            Debug.Assert(!LastSegmentIsRefSegment);

            if (!NavigationProperty.ContainsTarget)
            {
                return;
            }

            DeleteRestrictionsType delete = restriction?.DeleteRestrictions;

            if (delete == null || delete.IsDeletable)
            {
                if (NavigationProperty.TargetMultiplicity() != EdmMultiplicity.Many || LastSegmentIsKeySegment)
                {
                    AddOperation(item, OperationType.Delete);
                }

                return;
            }
        }
Ejemplo n.º 11
0
        /// <inheritdoc/>
        protected override void SetBasicInfo(OpenApiOperation operation)
        {
            // Summary and Description
            ReadRestrictionsType readRestriction = Restriction?.ReadRestrictions;
            string placeHolder = "Get ref of " + NavigationProperty.Name + " from " + NavigationSource.Name;

            operation.Summary     = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.Description : readRestriction?.Description) ?? placeHolder;
            operation.Description = (LastSegmentIsKeySegment ? readRestriction?.ReadByKeyRestrictions?.LongDescription : readRestriction?.LongDescription)
                                    ?? Context.Model.GetDescriptionAnnotation(NavigationProperty);

            // OperationId
            if (Context.Settings.EnableOperationId)
            {
                string prefix = "GetRef";
                if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    prefix = "ListRef";
                }

                operation.OperationId = GetOperationId(prefix);
            }
        }
        private void AddDeleteOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
        {
            Debug.Assert(!LastSegmentIsRefSegment);

            if (!NavigationProperty.ContainsTarget)
            {
                return;
            }

            DeleteRestrictionsType delete       = restriction?.DeleteRestrictions;
            DeleteRestrictionsType deleteEntity = Context.Model.GetRecord <DeleteRestrictionsType>(_entityType);
            bool isDeletableDefault             = delete == null && deleteEntity == null;

            if (isDeletableDefault ||
                (delete?.IsDeletable ?? false) ||
                (deleteEntity?.IsDeletable ?? false))
            {
                if (NavigationProperty.TargetMultiplicity() != EdmMultiplicity.Many || LastSegmentIsKeySegment)
                {
                    AddOperation(item, OperationType.Delete);
                }
                return;
            }
        }
Ejemplo n.º 13
0
        /// <inheritdoc/>
        protected override void SetResponses(OpenApiOperation operation)
        {
            OpenApiSchema schema = new OpenApiSchema
            {
                // $ref returns string for the Uri?
                Type = "string"
            };

            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                var properties = new Dictionary <string, OpenApiSchema>
                {
                    {
                        "value",
                        new OpenApiSchema
                        {
                            Type  = "array",
                            Items = schema
                        }
                    }
                };

                if (Context.Settings.EnablePagination)
                {
                    properties.Add(
                        "@odata.nextLink",
                        new OpenApiSchema
                    {
                        Type = "string"
                    });
                }

                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property links",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = new OpenApiSchema
                                        {
                                            Title      = "Collection of links of " + NavigationProperty.ToEntityType().Name,
                                            Type       = "object",
                                            Properties = properties
                                        }
                                    }
                                }
                            },
                            Links = Context.CreateLinks(NavigationProperty.ToEntityType(), NavigationProperty.Name)
                        }
                    }
                };
            }
            else
            {
                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property link",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = schema
                                    }
                                }
                            }
                        }
                    }
                };
            }

            operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse());

            base.SetResponses(operation);
        }
Ejemplo n.º 14
0
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            IEdmEntitySet             entitySet = NavigationSource as IEdmEntitySet;
            IEdmVocabularyAnnotatable target    = entitySet;

            if (target == null)
            {
                target = NavigationSource as IEdmSingleton;
            }

            string navigationPropertyPath = String.Join("/",
                                                        Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier));

            NavigationRestrictionsType    navigation  = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions);
            NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath);

            // verify using individual first
            if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None)
            {
                return;
            }

            if (restriction == null || restriction.Navigability == null)
            {
                // if the individual has not navigability setting, use the global navigability setting
                if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None)
                {
                    // Default navigability for all navigation properties of the annotation target.
                    // Individual navigation properties can override this value via `RestrictedProperties/Navigability`.
                    return;
                }
            }

            // So far, we only consider the non-containment
            Debug.Assert(!NavigationProperty.ContainsTarget);

            // It seems OData supports to "GetRef, DeleteRef",
            // Here at this time,let's only consider the "delete"
            ReadRestrictionsType read = restriction?.ReadRestrictions;

            if (read == null || read.IsReadable)
            {
                AddOperation(item, OperationType.Get);
            }

            // Create the ref
            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                InsertRestrictionsType insert = restriction?.InsertRestrictions;
                if (insert == null || insert.IsInsertable)
                {
                    AddOperation(item, OperationType.Post);
                }
            }
            else
            {
                UpdateRestrictionsType update = restriction?.UpdateRestrictions;
                if (update == null || update.IsUpdatable)
                {
                    AddOperation(item, OperationType.Put);
                }

                // delete the link
                DeleteRestrictionsType delete = restriction?.DeleteRestrictions;
                if (delete == null || delete.IsDeletable)
                {
                    AddOperation(item, OperationType.Delete);
                }
            }
        }
Ejemplo n.º 15
0
        /// <inheritdoc/>
        protected override void SetResponses(OpenApiOperation operation)
        {
            if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                operation.Responses = new OpenApiResponses
                {
                    {
                        Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            UnresolvedReference = true,
                            Reference           = new OpenApiReference
                            {
                                Type = ReferenceType.Response,
                                Id   = $"String{Constants.CollectionSchemaSuffix}"
                            },
                        }
                    }
                };
            }
            else
            {
                OpenApiSchema schema = new()
                {
                    // $ref returns string for the Uri?
                    Type = "string"
                };
                IDictionary <string, OpenApiLink> links = null;
                if (Context.Settings.ShowLinks)
                {
                    string operationId = GetOperationId();

                    links = Context.CreateLinks(entityType: NavigationProperty.ToEntityType(), entityName: NavigationProperty.Name,
                                                entityKind: NavigationProperty.PropertyKind.ToString(), parameters: PathParameters, path: Path,
                                                navPropOperationId: operationId);
                }

                operation.Responses = new OpenApiResponses
                {
                    {
                        Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property link",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = schema
                                    }
                                }
                            },
                            Links = links
                        }
                    }
                };
            }

            operation.AddErrorResponses(Context.Settings, false);

            base.SetResponses(operation);
        }
        /// <inheritdoc/>
        protected override void SetResponses(OpenApiOperation operation)
        {
            OpenApiSchema schema = null;

            if (Context.Settings.EnableDerivedTypesReferencesForResponses)
            {
                schema = EdmModelHelper.GetDerivedTypesReferenceSchema(NavigationProperty.ToEntityType(), Context.Model);
            }

            if (schema == null)
            {
                schema = new OpenApiSchema
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.Schema,
                        Id   = NavigationProperty.ToEntityType().FullName()
                    }
                };
            }

            if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                var properties = new Dictionary <string, OpenApiSchema>
                {
                    {
                        "value",
                        new OpenApiSchema
                        {
                            Type  = "array",
                            Items = schema
                        }
                    }
                };

                if (Context.Settings.EnablePagination)
                {
                    properties.Add(
                        "@odata.nextLink",
                        new OpenApiSchema
                    {
                        Type = "string"
                    });
                }

                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = new OpenApiSchema
                                        {
                                            Title      = "Collection of " + NavigationProperty.ToEntityType().Name,
                                            Type       = "object",
                                            Properties = properties
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
            }
            else
            {
                IDictionary <string, OpenApiLink> links = null;
                if (Context.Settings.ShowLinks)
                {
                    string operationId = GetOperationId();

                    links = Context.CreateLinks(entityType: NavigationProperty.ToEntityType(), entityName: NavigationProperty.Name,
                                                entityKind: NavigationProperty.PropertyKind.ToString(), parameters: operation.Parameters,
                                                navPropOperationId: operationId);
                }

                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = schema
                                    }
                                }
                            },
                            Links = links
                        }
                    }
                };
            }

            operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse());

            base.SetResponses(operation);
        }
Ejemplo n.º 17
0
        /// <inheritdoc/>
        protected override void SetResponses(OpenApiOperation operation)
        {
            IDictionary <string, OpenApiLink> links = null;

            if (Context.Settings.ShowLinks)
            {
                string operationId = GetOperationId();

                links = Context.CreateLinks(entityType: NavigationProperty.ToEntityType(), entityName: NavigationProperty.Name,
                                            entityKind: NavigationProperty.PropertyKind.ToString(), path: Path, parameters: PathParameters,
                                            navPropOperationId: operationId);
            }

            if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                operation.Responses = new OpenApiResponses
                {
                    {
                        Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            UnresolvedReference = true,
                            Reference           = new OpenApiReference()
                            {
                                Type = ReferenceType.Response,
                                Id   = $"{NavigationProperty.ToEntityType().FullName()}{Constants.CollectionSchemaSuffix}"
                            },
                            Links = links
                        }
                    }
                };
            }
            else
            {
                OpenApiSchema schema     = null;
                var           entityType = NavigationProperty.ToEntityType();

                if (Context.Settings.EnableDerivedTypesReferencesForResponses)
                {
                    schema = EdmModelHelper.GetDerivedTypesReferenceSchema(entityType, Context.Model);
                }

                if (schema == null)
                {
                    schema = new OpenApiSchema
                    {
                        UnresolvedReference = true,
                        Reference           = new OpenApiReference
                        {
                            Type = ReferenceType.Schema,
                            Id   = entityType.FullName()
                        }
                    };
                }

                operation.Responses = new OpenApiResponses
                {
                    {
                        Context.Settings.UseSuccessStatusCodeRange?Constants.StatusCodeClass2XX : Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = schema
                                    }
                                }
                            },
                            Links = links
                        }
                    }
                };
            }

            operation.AddErrorResponses(Context.Settings, false);

            base.SetResponses(operation);
        }
        /// <inheritdoc/>
        protected override void SetOperations(OpenApiPathItem item)
        {
            IEdmEntitySet             entitySet = NavigationSource as IEdmEntitySet;
            IEdmVocabularyAnnotatable target    = entitySet;

            if (target == null)
            {
                target = NavigationSource as IEdmSingleton;
            }

            string navigationPropertyPath = String.Join("/",
                                                        Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier));

            NavigationRestrictionsType    navigation  = Context.Model.GetRecord <NavigationRestrictionsType>(target, CapabilitiesConstants.NavigationRestrictions);
            NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath);

            // verify using individual first
            if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None)
            {
                return;
            }

            if (restriction == null || restriction.Navigability == null)
            {
                // if the individual has not navigability setting, use the global navigability setting
                if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None)
                {
                    // Default navigability for all navigation properties of the annotation target.
                    // Individual navigation properties can override this value via `RestrictedProperties/Navigability`.
                    return;
                }
            }

            // how about delete?
            // contaiment: Get / (Post - Collection | Patch - Single)
            // non-containment: only Get
            AddGetOperation(item, restriction);

            if (NavigationProperty.ContainsTarget)
            {
                if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    if (LastSegmentIsKeySegment)
                    {
                        // Need to check this scenario is valid or not?
                        UpdateRestrictionsType update = restriction?.UpdateRestrictions;
                        if (update == null || update.IsUpdatable)
                        {
                            AddOperation(item, OperationType.Patch);
                        }
                    }
                    else
                    {
                        InsertRestrictionsType insert = restriction?.InsertRestrictions;
                        if (insert == null || insert.IsInsertable)
                        {
                            AddOperation(item, OperationType.Post);
                        }
                    }
                }
                else
                {
                    UpdateRestrictionsType update = restriction?.UpdateRestrictions;
                    if (update == null || update.IsUpdatable)
                    {
                        AddOperation(item, OperationType.Patch);
                    }
                }
            }
        }
        /// <inheritdoc/>
        protected override void SetResponses(OpenApiOperation operation)
        {
            if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
            {
                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = new OpenApiSchema
                                        {
                                            Title      = "Collection of " + NavigationProperty.ToEntityType().Name,
                                            Type       = "object",
                                            Properties = new Dictionary <string, OpenApiSchema>
                                            {
                                                {
                                                    "value",
                                                    new OpenApiSchema
                                                    {
                                                        Type  = "array",
                                                        Items = new OpenApiSchema
                                                        {
                                                            Reference = new OpenApiReference
                                                            {
                                                                Type = ReferenceType.Schema,
                                                                Id   = NavigationProperty.ToEntityType().FullName()
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
            }
            else
            {
                operation.Responses = new OpenApiResponses
                {
                    {
                        Constants.StatusCode200,
                        new OpenApiResponse
                        {
                            Description = "Retrieved navigation property",
                            Content     = new Dictionary <string, OpenApiMediaType>
                            {
                                {
                                    Constants.ApplicationJsonMediaType,
                                    new OpenApiMediaType
                                    {
                                        Schema = new OpenApiSchema
                                        {
                                            Reference = new OpenApiReference
                                            {
                                                Type = ReferenceType.Schema,
                                                Id   = NavigationProperty.ToEntityType().FullName()
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
            }

            operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse());

            base.SetResponses(operation);
        }