/// <summary>
        /// Create the collection of <see cref="OpenApiLink"/> object.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="entitySet">The Entity Set.</param>
        /// <returns>The created dictionary of <see cref="OpenApiLink"/> object.</returns>
        public static IDictionary <string, OpenApiLink> CreateLinks(this ODataContext context, IEdmEntitySet entitySet)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(entitySet, nameof(entitySet));

            IDictionary <string, OpenApiLink> links = new Dictionary <string, OpenApiLink>();
            IEdmEntityType entityType = entitySet.EntityType();

            foreach (var np in entityType.DeclaredNavigationProperties())
            {
                OpenApiLink link     = new OpenApiLink();
                string      typeName = entitySet.EntityType().Name;
                link.OperationId = entitySet.Name + "." + typeName + ".Get" + Utils.UpperFirstChar(typeName);
                link.Parameters  = new Dictionary <string, RuntimeExpressionAnyWrapper>();
                foreach (var key in entityType.Key())
                {
                    link.Parameters[key.Name] = new RuntimeExpressionAnyWrapper
                    {
                        Any = new OpenApiString("$request.path." + key.Name)
                    };
                }

                links[np.Name] = link;
            }

            return(links);
        }
        /// <summary>
        /// Create the collection of <see cref="OpenApiLink"/> object.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="entityType">The Entity type.</param>
        /// <param name ="sourceElementName">The name of the source of the <see cref="IEdmEntityType" />.</param>
        /// <returns>The created dictionary of <see cref="OpenApiLink"/> object.</returns>
        public static IDictionary <string, OpenApiLink> CreateLinks(this ODataContext context, IEdmEntityType entityType, string sourceElementName)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(entityType, nameof(entityType));
            Utils.CheckArgumentNullOrEmpty(sourceElementName, nameof(sourceElementName));

            IDictionary <string, OpenApiLink> links = new Dictionary <string, OpenApiLink>();

            foreach (IEdmNavigationProperty np in entityType.DeclaredNavigationProperties())
            {
                OpenApiLink link = new OpenApiLink
                {
                    OperationId = sourceElementName + "." + entityType.Name + ".Get" + Utils.UpperFirstChar(entityType.Name),
                    Parameters  = new Dictionary <string, RuntimeExpressionAnyWrapper>()
                };

                foreach (IEdmStructuralProperty key in entityType.Key())
                {
                    link.Parameters[key.Name] = new RuntimeExpressionAnyWrapper
                    {
                        Any = new OpenApiString("$request.path." + key.Name)
                    };
                }

                links[np.Name] = link;
            }

            return(links);
        }
示例#3
0
 public override void Visit(OpenApiLink link)
 {
     if (link.UnresolvedReference)
     {
         throw new ArgumentException("Single pass reference resolution expects this element to already be resolved");
     }
 }
示例#4
0
 public void Traverse(OpenApiLink link)
 {
     if (link != null)
     {
         return;
     }
     Visitor.Visit(link);
     Traverse(link.Server);
 }
示例#5
0
        /// <summary>
        /// Visits <see cref="OpenApiLink"/> and child objects
        /// </summary>
        internal void Walk(OpenApiLink link, bool isComponent = false)
        {
            if (link == null || ProcessAsReference(link, isComponent))
            {
                return;
            }

            _visitor.Visit(link);
            Walk(OpenApiConstants.Server, () => Walk(link.Server));
            Walk(link as IOpenApiExtensible);
        }
示例#6
0
        /// <summary>
        /// Visits <see cref="OpenApiLink"/> and child objects
        /// </summary>
        internal void Walk(OpenApiLink link)
        {
            if (link == null)
            {
                return;
            }

            _visitor.Visit(link);
            Walk(OpenApiConstants.Server, () => Walk(link.Server));
            Walk(link as IOpenApiExtensible);
        }
        public static OpenApiLink LoadLink(ParseNode node)
        {
            var mapNode = node.CheckMapNode("link");
            var link    = new OpenApiLink();

            var pointer = mapNode.GetReferencePointer();

            if (pointer != null)
            {
                return(mapNode.GetReferencedObject <OpenApiLink>(ReferenceType.Link, pointer));
            }

            ParseMap(mapNode, link, _linkFixedFields, _linkPatternFields);

            return(link);
        }
        private void AddGetByIdLink(OpenApiOperation operation, KeyValuePair <string, OpenApiResponse> response)
        {
            /*
             # See: https://swagger.io/docs/specification/links/
             #
             # -----------------------------------------------------
             # Links
             # -----------------------------------------------------
             #  links:
             #    GetUserByUserId:   # <---- arbitrary name for the link
             #      operationId: getUser
             # or
             # operationRef: '#/paths/~1users~1{userId}/get'
             #      parameters:
             #        userId: '$response.body#/id'
             #      description: >
             #        The `id` value returned in the response can be used as the `userId` parameter in `GET /users/{userId}`.
             # -----------------------------------------------------
             */

            var modelName   = operation.OperationId.Replace(Constants.Create, string.Empty);
            var operationId = _localizer.GetString($"Get{modelName}ById");

            var getById = new OpenApiLink
            {
                OperationId = operationId,
                Description = _localizer.GetString($"The `id` value returned in the response can be used as the `id` parameter in `GET /{modelName}/{{id}}`"),
            };

            // parameters:
            //    id: '$response.body#/id'
            getById.Parameters.Add("id",
                                   new RuntimeExpressionAnyWrapper
            {
                Expression = new ResponseExpression(new BodyExpression(new JsonPointer("/id")))
            });

            response.Value.Links.Add(operationId.Value, getById);
        }
 /// <summary>
 /// Resolves the <see cref="OpenApiSchema.Reference"/> in the <paramref name="link"/>, if present, using <paramref name="components"/>.
 /// </summary>
 public static OpenApiLink Resolve([NotNull] this OpenApiLink link, [NotNull] OpenApiComponents components)
 => link.Resolve(components.Links);
示例#10
0
 /// <summary>
 /// Visits <see cref="OpenApiLink"/>
 /// </summary>
 public virtual void Visit(OpenApiLink link)
 {
 }
示例#11
0
 /// <summary>
 /// Visits <see cref="OpenApiLink"/> and child objects
 /// </summary>
 /// <param name="link"></param>
 internal void Walk(OpenApiLink link)
 {
     _visitor.Visit(link);
     Walk(link.Server);
     Walk(link as IOpenApiExtensible);
 }
示例#12
0
 public override void Visit(OpenApiLink link)
 {
     EncodeCall();
     base.Visit(link);
 }
        /// <summary>
        /// Create the collection of <see cref="OpenApiLink"/> object.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="entityType">The Entity type.</param>
        /// <param name ="entityName">The name of the source of the <see cref="IEdmEntityType"/> object.</param>
        /// <param name="entityKind">"The kind of the source of the <see cref="IEdmEntityType"/> object.</param>
        /// <param name="parameters">"The list of parameters of the incoming operation.</param>
        /// <param name="navPropOperationId">Optional parameter: The operation id of the source of the NavigationProperty object.</param>
        /// <returns>The created dictionary of <see cref="OpenApiLink"/> object.</returns>
        public static IDictionary <string, OpenApiLink> CreateLinks(this ODataContext context,
                                                                    IEdmEntityType entityType, string entityName, string entityKind,
                                                                    IList <OpenApiParameter> parameters, string navPropOperationId = null)
        {
            IDictionary <string, OpenApiLink> links = new Dictionary <string, OpenApiLink>();

            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(entityType, nameof(entityType));
            Utils.CheckArgumentNullOrEmpty(entityName, nameof(entityName));
            Utils.CheckArgumentNullOrEmpty(entityKind, nameof(entityKind));
            Utils.CheckArgumentNull(parameters, nameof(parameters));

            List <string> pathKeyNames = new List <string>();

            // Fetch defined Id(s) from incoming parameters (if any)
            foreach (var parameter in parameters)
            {
                if (!string.IsNullOrEmpty(parameter.Description) &&
                    parameter.Description.ToLower().Contains("key"))
                {
                    pathKeyNames.Add(parameter.Name);
                }
            }

            foreach (IEdmNavigationProperty navProp in entityType.NavigationProperties())
            {
                string navPropName = navProp.Name;
                string operationId;
                string operationPrefix;

                switch (entityKind)
                {
                case "Navigation":     // just for contained navigations
                    operationPrefix = navPropOperationId;
                    break;

                default:     // EntitySet, Entity, Singleton
                    operationPrefix = entityName;
                    break;
                }

                if (navProp.TargetMultiplicity() == EdmMultiplicity.Many)
                {
                    operationId = operationPrefix + ".List" + Utils.UpperFirstChar(navPropName);
                }
                else
                {
                    operationId = operationPrefix + ".Get" + Utils.UpperFirstChar(navPropName);
                }

                OpenApiLink link = new OpenApiLink
                {
                    OperationId = operationId,
                    Parameters  = new Dictionary <string, RuntimeExpressionAnyWrapper>()
                };

                if (pathKeyNames.Any())
                {
                    foreach (var pathKeyName in pathKeyNames)
                    {
                        link.Parameters[pathKeyName] = new RuntimeExpressionAnyWrapper
                        {
                            Any = new OpenApiString("$request.path." + pathKeyName)
                        };
                    }
                }

                links[navProp.Name] = link;
            }

            return(links);
        }
        /// <summary>
        /// Create the collection of <see cref="OpenApiLink"/> object for an entity or collection of entities.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="entityType">The Entity type.</param>
        /// <param name ="entityName">The name of the source of the <see cref="IEdmEntityType"/> object.</param>
        /// <param name="entityKind">"The kind of the source of the <see cref="IEdmEntityType"/> object.</param>
        /// <param name="path">The OData path of the operation the links are to be generated for.</param>
        /// <param name="parameters">"Optional: The list of parameters of the incoming operation.</param>
        /// <param name="navPropOperationId">Optional: The operation id of the source of the NavigationProperty object.</param>
        /// <returns>The created dictionary of <see cref="OpenApiLink"/> object.</returns>
        public static IDictionary <string, OpenApiLink> CreateLinks(this ODataContext context,
                                                                    IEdmEntityType entityType, string entityName, string entityKind, ODataPath path,
                                                                    IList <OpenApiParameter> parameters = null, string navPropOperationId = null)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(entityType, nameof(entityType));
            Utils.CheckArgumentNullOrEmpty(entityName, nameof(entityName));
            Utils.CheckArgumentNullOrEmpty(entityKind, nameof(entityKind));
            Utils.CheckArgumentNull(path, nameof(path));

            List <string> pathKeyNames = new();

            // Fetch defined Id(s) from incoming parameters (if any)
            if (parameters != null)
            {
                foreach (var parameter in parameters)
                {
                    if (!string.IsNullOrEmpty(parameter.Description) &&
                        parameter.Description.ToLower().Contains("key"))
                    {
                        pathKeyNames.Add(parameter.Name);
                    }
                }
            }

            Dictionary <string, OpenApiLink> links = new();
            bool lastSegmentIsColNavProp           = (path.LastSegment as ODataNavigationPropertySegment)?.NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many;

            // Valid only for non collection-valued navigation properties
            if (!lastSegmentIsColNavProp)
            {
                foreach (IEdmNavigationProperty navProp in entityType.NavigationProperties())
                {
                    string navPropName = navProp.Name;
                    string operationId;
                    string operationPrefix;

                    switch (entityKind)
                    {
                    case "Navigation":     // just for contained navigations
                        operationPrefix = navPropOperationId;
                        break;

                    default:     // EntitySet, Entity, Singleton
                        operationPrefix = entityName;
                        break;
                    }

                    if (navProp.TargetMultiplicity() == EdmMultiplicity.Many)
                    {
                        operationId = operationPrefix + ".List" + Utils.UpperFirstChar(navPropName);
                    }
                    else
                    {
                        operationId = operationPrefix + ".Get" + Utils.UpperFirstChar(navPropName);
                    }

                    OpenApiLink link = new OpenApiLink
                    {
                        OperationId = operationId,
                        Parameters  = new Dictionary <string, RuntimeExpressionAnyWrapper>()
                    };

                    if (pathKeyNames.Any())
                    {
                        foreach (var pathKeyName in pathKeyNames)
                        {
                            link.Parameters[pathKeyName] = new RuntimeExpressionAnyWrapper
                            {
                                Any = new OpenApiString("$request.path." + pathKeyName)
                            };
                        }
                    }

                    links[navProp.Name] = link;
                }
            }

            // Get the Operations and OperationImport paths bound to this (collection of) entity.
            IEnumerable <ODataPath> operationPaths = context.AllPaths.Where(p => (p.Kind.Equals(ODataPathKind.Operation) || p.Kind.Equals(ODataPathKind.OperationImport)) &&
                                                                            path.GetPathItemName().Equals(p.Clone().Pop().GetPathItemName()));

            // Generate links to the Operations and OperationImport operations.
            if (operationPaths.Any())
            {
                foreach (var operationPath in operationPaths)
                {
                    OpenApiLink link = new()
                    {
                        OperationId = string.Join(".", operationPath.Segments.Select(x =>
                        {
                            return(x.Kind.Equals(ODataSegmentKind.Key) ? x.EntityType.Name : x.Identifier);
                        }))
                    };

                    links[operationPath.LastSegment.Identifier] = link;
                }
            }

            return(links);
        }
    }
示例#15
0
 public override void Visit(OpenApiLink operation)
 {
     LinkCount++;
 }