Exemple #1
0
        private Operation CreatePostOperation(OpenApiMetadataPathsResource openApiMetadataResource)
        {
            var responses = OpenApiMetadataDocumentHelper.GetWriteOperationResponses(HttpMethod.Post);

            if (_apiSettings.IsFeatureEnabled(ApiFeature.ChangeQueries.GetConfigKeyName()))
            {
                responses.Add(
                    "405",
                    new Response
                {
                    description =
                        "Method Is Not Allowed. When the Snapshot-Identifier header is present the method is not allowed."
                });
            }

            return(new Operation
            {
                tags = new List <string>
                {
                    OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
                    .ToCamelCase()
                },
                summary = "Creates or updates resources based on the natural key values of the supplied resource.",
                description =
                    "The POST operation can be used to create or update resources. In database terms, this is often referred to as an \"upsert\" operation (insert + update). Clients should NOT include the resource \"id\" in the JSON body because it will result in an error. The web service will identify whether the resource already exists based on the natural key values provided, and update or create the resource appropriately. It is recommended to use POST for both create and update except while updating natural key of a resource in which case PUT operation must be used.",
                operationId = "post" + openApiMetadataResource.Name,
                deprecated = openApiMetadataResource.IsDeprecated,
                consumes = new[]
                {
                    _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Writable)
                },
                parameters = CreatePostParameters(openApiMetadataResource),
                responses = responses
            });
        }
        private IList <Parameter> CreateQueryParameters(bool isCompositeContext)
        {
            var parameterList = new List <Parameter>
            {
                new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("offset")
                },
                new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("limit")
                }
            };

            if (_apiSettings.IsFeatureEnabled("ChangeQueries") && !isCompositeContext)
            {
                parameterList.Add(
                    new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("MinChangeVersion")
                });

                parameterList.Add(
                    new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("MaxChangeVersion")
                });
            }

            if (_openApiMetadataPathsFactorySelectorStrategy.HasTotalCount)
            {
                parameterList.Add(
                    new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("totalCount")
                });
            }

            return(parameterList);
        }
        private Operation CreateGetOperation(OpenApiMetadataPathsResource openApiMetadataResource, bool isCompositeContext)
        {
            var operation = new Operation
            {
                tags = new List <string>
                {
                    OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
                    .ToCamelCase()
                },
                summary     = "Retrieves specific resources using the resource's property values (using the \"Get\" pattern).",
                description =
                    "This GET operation provides access to resources using the \"Get\" search pattern.  The values of any properties of the resource that are specified will be used to return all matching results (if it exists).",
                operationId = openApiMetadataResource.OperationId ?? $"get{openApiMetadataResource.Resource.PluralName}",
                deprecated  = openApiMetadataResource.IsDeprecated,
                produces    = new[]
                {
                    _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Readable)
                },
                parameters = CreateGetByExampleParameters(openApiMetadataResource, isCompositeContext),
                responses  = OpenApiMetadataDocumentHelper.GetReadOperationResponses(
                    _pathsFactoryNamingStrategy.GetResourceName(openApiMetadataResource, ContentTypeUsage.Readable),
                    true)
            };

            return(operation);
        }
 private Operation CreateDeleteByIdOperation(OpenApiMetadataPathsResource openApiMetadataResource)
 {
     return(new Operation
     {
         tags = new List <string>
         {
             OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
             .ToCamelCase()
         },
         summary = "Deletes an existing resource using the resource identifier.",
         description =
             "The DELETE operation is used to delete an existing resource by identifier. If the resource doesn't exist, an error will result (the resource will not be found).",
         operationId = $"delete{openApiMetadataResource.Name}ById",
         deprecated = openApiMetadataResource.IsDeprecated,
         consumes = new[]
         {
             _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Writable)
         },
         parameters = new[]
         {
             OpenApiMetadataDocumentHelper.CreateIdParameter(),
             CreateIfMatchParameter("DELETE from removing")
         },
         responses = OpenApiMetadataDocumentHelper.GetWriteOperationResponses(HttpMethod.Delete)
     });
 }
        private IList <Parameter> CreateGetByExampleParameters(OpenApiMetadataPathsResource openApiMetadataResource,
                                                               bool isCompositeContext)
        {
            var parameterList = CreateQueryParameters(isCompositeContext)
                                .Concat(
                openApiMetadataResource.DefaultGetByExampleParameters.Select(
                    p => new Parameter {
                @ref = OpenApiMetadataDocumentHelper.GetParameterReference(p)
            }))
                                .ToList();

            IEnumerableExtensions.ForEach(
                openApiMetadataResource.RequestProperties, x =>
            {
                parameterList.Add(
                    new Parameter
                {
                    name = StringExtensions.ToCamelCase(x.PropertyName),
                    @in  = openApiMetadataResource.IsPathParameter(x)
                                ? "path"
                                : "query",
                    description       = OpenApiMetadataDocumentHelper.PropertyDescription(x),
                    type              = OpenApiMetadataDocumentHelper.PropertyType(x),
                    format            = x.PropertyType.ToOpenApiFormat(),
                    required          = openApiMetadataResource.IsPathParameter(x),
                    isIdentity        = OpenApiMetadataDocumentHelper.GetIsIdentity(x),
                    maxLength         = OpenApiMetadataDocumentHelper.GetMaxLength(x),
                    isDeprecated      = OpenApiMetadataDocumentHelper.GetIsDeprecated(x),
                    deprecatedReasons = OpenApiMetadataDocumentHelper.GetDeprecatedReasons(x)
                });
            });

            return(parameterList);
        }
        private Schema CreateResourceChildSchema(ResourceChildItem resourceChildItem, OpenApiMetadataResource openApiMetadataResource)
        {
            var properties = resourceChildItem.Properties
                             .Select(
                p => new
            {
                IsRequired = p.IsIdentifying || !p.PropertyType.IsNullable,
                Key        = UniqueIdSpecification.GetUniqueIdPropertyName(p.JsonPropertyName).ToCamelCase(),
                Schema     = OpenApiMetadataDocumentHelper.CreatePropertySchema(p)
            }).Concat(
                resourceChildItem.References.Select(
                    r => new
            {
                r.IsRequired,
                Key    = r.PropertyName.ToCamelCase(),
                Schema = new Schema
                {
                    @ref = OpenApiMetadataDocumentHelper.GetDefinitionReference(
                        _openApiMetadataDefinitionsFactoryNamingStrategy.GetReferenceName(openApiMetadataResource.Resource, r))
                }
            })).Concat(
                resourceChildItem.Collections.Select(
                    c => new
            {
                IsRequired = c.Association.IsRequiredCollection,
                Key        = c.JsonPropertyName,
                Schema     = CreateCollectionSchema(c, openApiMetadataResource)
            })).Concat(
                resourceChildItem.EmbeddedObjects.Select(
                    e => new
            {
                IsRequired = false,
                Key        = e.JsonPropertyName,
                Schema     = CreateEmbeddedObjectSchema(e, openApiMetadataResource)
            })).ToList();

            var bridgeSchema = GetEdFiExtensionBridgeReferenceSchema(resourceChildItem, openApiMetadataResource);

            if (bridgeSchema != null)
            {
                properties.Add(
                    new
                {
                    IsRequired = false,
                    Key        = ExtensionCollectionKey,
                    Schema     = bridgeSchema
                });
            }

            var requiredProperties = properties.Where(x => x.IsRequired).Select(x => x.Key).ToList();

            return(new Schema
            {
                type = "object",
                required = requiredProperties.Any()
                    ? requiredProperties
                    : null,
                properties = properties.ToDictionary(k => k.Key, v => v.Schema)
            });
        }
Exemple #7
0
        private Operation CreatePutByIdOperation(OpenApiMetadataPathsResource openApiMetadataResource)
        {
            var responses = OpenApiMetadataDocumentHelper.GetWriteOperationResponses(HttpMethod.Put);

            if (_apiSettings.IsFeatureEnabled(ApiFeature.ChangeQueries.GetConfigKeyName()))
            {
                responses.Add(
                    "405",
                    new Response
                {
                    description =
                        "Method Is Not Allowed. When the Snapshot-Identifier header is present the method is not allowed."
                });
            }

            return(new Operation
            {
                tags = new List <string>
                {
                    OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
                    .ToCamelCase()
                },
                summary = "Updates a resource based on the resource identifier.",
                description = GetDescription(openApiMetadataResource),
                operationId = $"put{openApiMetadataResource.Name}",
                deprecated = openApiMetadataResource.IsDeprecated,
                consumes = new[]
                {
                    _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Writable)
                },
                parameters = CreatePutParameters(openApiMetadataResource),
                responses = responses,
                isUpdatable = GetIsUpdatableCustomMetadataValue(openApiMetadataResource)
            });
        }
 private Schema CreateEmbeddedObjectSchema(EmbeddedObject embeddedObject, OpenApiMetadataResource openApiMetadataResource)
 {
     return(new Schema
     {
         @ref = OpenApiMetadataDocumentHelper.GetDefinitionReference(
             _openApiMetadataDefinitionsFactoryNamingStrategy.GetEmbeddedObjectReferenceName(openApiMetadataResource, embeddedObject))
     });
 }
        private IList <Parameter> CreatePutParameters(OpenApiMetadataPathsResource openApiMetadataResource)
        {
            IList <Parameter> parameterList = new List <Parameter>();

            parameterList.Add(OpenApiMetadataDocumentHelper.CreateIdParameter());

            parameterList.Add(CreateIfMatchParameter("PUT from updating"));
            parameterList.Add(CreateBodyParameter(openApiMetadataResource));

            return(parameterList);
        }
 public IList <Tag> Create(IEnumerable <OpenApiMetadataResource> openApiMetadataResources)
 {
     return(openApiMetadataResources.Where(x => _filterStrategy.ShouldInclude(x.Resource))
            .Select(
                x => new Tag
     {
         name = OpenApiMetadataDocumentHelper.GetResourcePluralName(x.Resource).ToCamelCase(),
         description = x.Description
     })
            .GroupBy(t => t.name)
            .Select(g => g.First())
            .OrderBy(x => x.name)
            .ToList());
 }
        public IDictionary <string, PathItem> Create(IList <OpenApiMetadataResource> openApiMetadataResources,
                                                     bool isCompositeContext)
        {
            return(_openApiMetadataPathsFactorySelectorStrategy
                   .ApplyStrategy(openApiMetadataResources)
                   .Where(r => r.Readable || r.Writable)
                   .OrderBy(r => r.Name)
                   .SelectMany(
                       r =>
            {
                var resourceName = string.IsNullOrWhiteSpace(r.Path)
                            ? $"/{OpenApiMetadataDocumentHelper.GetResourcePluralName(r.Resource).ToCamelCase()}"
                            : r.Path;

                var resourcePath = $"/{r.ResourceSchema}{resourceName}";

                var paths = new[]
                {
                    r.SupportsAccessNonIdAccessOperations
                                ? new
                    {
                        Path = resourcePath,
                        PathItem = CreatePathItemForNonIdAccessedOperations(r, isCompositeContext)
                    }
                                : null,
                    r.SupportsIdAccessOperations
                                ? new
                    {
                        Path = $"{resourcePath}/{{id}}",
                        PathItem = CreatePathItemForAccessByIdsOperations(r)
                    }
                                : null,
                    _apiSettings.IsFeatureEnabled("ChangeQueries") &&
                    !r.Name.Equals(ChangeQueriesConstants.SchoolYearTypesResourceName) &&
                    !isCompositeContext
                                ? new
                    {
                        Path = $"{resourcePath}/deletes",
                        PathItem = CreatePathItemForChangeQueryOperation(r)
                    }
                                : null
                };

                return paths.Where(p => p != null);
            })
                   .GroupBy(p => p.Path)
                   .Select(p => p.First())
                   .ToDictionary(p => p.Path, p => p.PathItem));
        }
Exemple #12
0
        private Operation CreateGetByIdOperation(OpenApiMetadataPathsResource openApiMetadataResource)
        {
            var parameters = new[]
            {
                // Path parameters need to be inline in the operation, and not referenced.
                OpenApiMetadataDocumentHelper.CreateIdParameter(),
                new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("If-None-Match")
                }
            }.Concat(
                openApiMetadataResource.DefaultGetByIdParameters
                .Select(p => new Parameter {
                @ref = OpenApiMetadataDocumentHelper.GetParameterReference(p)
            }))
            .ToList();

            if (_apiSettings.IsFeatureEnabled(ApiFeature.ChangeQueries.GetConfigKeyName()))
            {
                parameters.Add(new Parameter
                {
                    name        = "Snapshot-Identifier",
                    @in         = "header",
                    description = "Indicates the Snapshot-Identifier that should be used.",
                    type        = "string",
                    required    = false
                });
            }

            return(new Operation
            {
                tags = new List <string>
                {
                    OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
                    .ToCamelCase()
                },
                summary = "Retrieves a specific resource using the resource's identifier (using the \"Get By Id\" pattern).",
                description = "This GET operation retrieves a resource by the specified resource identifier.",
                operationId = $"get{openApiMetadataResource.Resource.PluralName}ById",
                deprecated = openApiMetadataResource.IsDeprecated,
                produces = new[]
                {
                    _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Readable)
                },
                parameters = parameters,
                responses = CreateReadResponses(openApiMetadataResource, false)
            });
        }
Exemple #13
0
        private IList <Parameter> CreateGetByExampleParameters(OpenApiMetadataPathsResource openApiMetadataResource,
                                                               bool isCompositeContext)
        {
            var parameterList = CreateQueryParameters(isCompositeContext)
                                .Concat(
                openApiMetadataResource.DefaultGetByExampleParameters.Select(
                    p => new Parameter {
                @ref = OpenApiMetadataDocumentHelper.GetParameterReference(p)
            }))
                                .ToList();

            IEnumerableExtensions.ForEach(
                openApiMetadataResource.RequestProperties, x =>
            {
                parameterList.Add(
                    new Parameter
                {
                    name = StringExtensions.ToCamelCase(x.PropertyName),
                    @in  = openApiMetadataResource.IsPathParameter(x)
                                ? "path"
                                : "query",
                    description       = OpenApiMetadataDocumentHelper.PropertyDescription(x),
                    type              = OpenApiMetadataDocumentHelper.PropertyType(x),
                    format            = x.PropertyType.ToOpenApiFormat(),
                    required          = openApiMetadataResource.IsPathParameter(x),
                    isIdentity        = OpenApiMetadataDocumentHelper.GetIsIdentity(x),
                    maxLength         = OpenApiMetadataDocumentHelper.GetMaxLength(x),
                    isDeprecated      = OpenApiMetadataDocumentHelper.GetIsDeprecated(x),
                    deprecatedReasons = OpenApiMetadataDocumentHelper.GetDeprecatedReasons(x)
                });
            });

            if (_apiSettings.IsFeatureEnabled(ApiFeature.ChangeQueries.GetConfigKeyName()))
            {
                parameterList.Add(new Parameter
                {
                    name        = "Snapshot-Identifier",
                    @in         = "header",
                    description = "Indicates the Snapshot-Identifier that should be used.",
                    type        = "string",
                    required    = false
                });
            }

            return(parameterList);
        }
        public IDictionary <string, Schema> Create(IList <OpenApiMetadataResource> openApiMetadataResources)
        {
            var definitions = BoilerPlateDefinitions();

            openApiMetadataResources.Where(x => _openApiMetadataFactoryResourceFilterStrategy.ShouldInclude(x.Resource)).Select(
                r => new
            {
                key    = _openApiMetadataDefinitionsFactoryNamingStrategy.GetResourceName(r.Resource, r),
                schema = CreateResourceSchema(r)
            }).GroupBy(d => d?.key).Select(g => g.First()).ForEach(
                d =>
            {
                if (d != null)
                {
                    definitions.Add(d.key, d.schema);
                }
            });

            openApiMetadataResources.SelectMany(
                r => r.Resource.AllContainedItemTypes.Where(x => _openApiMetadataFactoryResourceFilterStrategy.ShouldInclude(x))
                .Select(
                    i => new
            {
                key    = _openApiMetadataDefinitionsFactoryNamingStrategy.GetContainedItemTypeName(r, i),
                schema = CreateResourceChildSchema(i, r)
            }).Concat(
                    openApiMetadataResources.SelectMany(s => s.Resource.AllContainedReferences).Select(
                        reference => new
            {
                key    = _openApiMetadataDefinitionsFactoryNamingStrategy.GetReferenceName(r.Resource, reference),
                schema = OpenApiMetadataDocumentHelper.CreateReferenceSchema(reference)
            }))).GroupBy(d => d?.key).Select(g => g.First()).ForEach(
                d =>
            {
                if (d != null)
                {
                    definitions.Add(d.key, d.schema);
                }
            });

            _definitionsFactoryEntityExtensionStrategy.GetEdFiExtensionBridgeDefinitions(openApiMetadataResources)
            .ForEach(pair => definitions.Add(pair.Key, pair.Value));

            return(new SortedDictionary <string, Schema>(definitions));
        }
        private Parameter CreateBodyParameter(OpenApiMetadataPathsResource openApiMetadataPathsResource)
        {
            var camelCaseName = openApiMetadataPathsResource.Resource.Name.ToCamelCase();

            var referenceName =
                _pathsFactoryNamingStrategy.GetResourceName(openApiMetadataPathsResource, ContentTypeUsage.Writable);

            return(new Parameter
            {
                name = camelCaseName,
                description =
                    $"The JSON representation of the \"{camelCaseName}\" resource to be created or updated.",
                @in = "body",
                required = true,
                schema = new Schema {
                    @ref = OpenApiMetadataDocumentHelper.GetDefinitionReference(referenceName)
                }
            });
        }
Exemple #16
0
        private Dictionary <string, Response> CreateReadResponses(OpenApiMetadataPathsResource openApiMetadataResource, bool isArray)
        {
            var responses = OpenApiMetadataDocumentHelper.GetReadOperationResponses(
                _pathsFactoryNamingStrategy.GetResourceName(openApiMetadataResource, ContentTypeUsage.Readable),
                isArray);

            if (_apiSettings.IsFeatureEnabled(ApiFeature.ChangeQueries.GetConfigKeyName()))
            {
                responses.Add(
                    "410",
                    new Response
                {
                    description =
                        "Gone. An attempt to connect to the database for the snapshot specified by the Snapshot-Identifier header was unsuccessful (indicating the snapshot may have been removed)."
                });
            }

            return(responses);
        }
 private Operation CreatePostOperation(OpenApiMetadataPathsResource openApiMetadataResource)
 {
     return(new Operation
     {
         tags = new List <string>
         {
             OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
             .ToCamelCase()
         },
         summary = "Creates or updates resources based on the natural key values of the supplied resource.",
         description =
             "The POST operation can be used to create or update resources. In database terms, this is often referred to as an \"upsert\" operation (insert + update). Clients should NOT include the resource \"id\" in the JSON body because it will result in an error (you must use a PUT operation to update a resource by \"id\"). The web service will identify whether the resource already exists based on the natural key values provided, and update or create the resource appropriately.",
         operationId = "post" + openApiMetadataResource.Name,
         deprecated = openApiMetadataResource.IsDeprecated,
         consumes = new[]
         {
             _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Writable)
         },
         parameters = CreatePostParameters(openApiMetadataResource),
         responses = OpenApiMetadataDocumentHelper.GetWriteOperationResponses(HttpMethod.Post)
     });
 }
 private Operation CreateDeletesOperation(OpenApiMetadataPathsResource openApiMetadataResource)
 {
     return(new Operation
     {
         tags = new List <string>
         {
             OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
             .ToCamelCase()
         },
         summary = "Retrieves deleted resources based on change version.",
         description = "The DELETES operation is used to retrieve deleted resources.",
         operationId = $"deletes{openApiMetadataResource.Resource.PluralName}",
         deprecated = openApiMetadataResource.IsDeprecated,
         consumes = new[]
         {
             _contentTypeStrategy.GetOperationContentType(
                 openApiMetadataResource,
                 ContentTypeUsage.Writable)
         },
         parameters = new List <Parameter>
         {
             new Parameter {
                 @ref = OpenApiMetadataDocumentHelper.GetParameterReference("offset")
             },
             new Parameter {
                 @ref = OpenApiMetadataDocumentHelper.GetParameterReference("limit")
             },
             new Parameter {
                 @ref = OpenApiMetadataDocumentHelper.GetParameterReference("MinChangeVersion")
             },
             new Parameter {
                 @ref = OpenApiMetadataDocumentHelper.GetParameterReference("MaxChangeVersion")
             }
         },
         responses = OpenApiMetadataDocumentHelper.GetReadOperationResponses(
             _pathsFactoryNamingStrategy.GetResourceName(openApiMetadataResource, ContentTypeUsage.Readable),
             true, true)
     });
 }
 private Operation CreatePutByIdOperation(OpenApiMetadataPathsResource openApiMetadataResource)
 {
     return(new Operation
     {
         tags = new List <string>
         {
             OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
             .ToCamelCase()
         },
         summary = "Updates or creates a resource based on the resource identifier.",
         description =
             "The PUT operation is used to update or create a resource by identifier. If the resource doesn't exist, the resource will be created using that identifier. Additionally, natural key values cannot be changed using this operation, and will not be modified in the database.  If the resource \"id\" is provided in the JSON body, it will be ignored as well.",
         operationId = $"put{openApiMetadataResource.Name}",
         deprecated = openApiMetadataResource.IsDeprecated,
         consumes = new[]
         {
             _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Writable)
         },
         parameters = CreatePutParameters(openApiMetadataResource),
         responses = OpenApiMetadataDocumentHelper.GetWriteOperationResponses(HttpMethod.Put)
     });
 }
Exemple #20
0
        private Operation CreateDeleteByIdOperation(OpenApiMetadataPathsResource openApiMetadataResource)
        {
            var responses = OpenApiMetadataDocumentHelper.GetWriteOperationResponses(HttpMethod.Delete);

            if (_apiSettings.IsFeatureEnabled(ApiFeature.ChangeQueries.GetConfigKeyName()))
            {
                responses.Add(
                    "405",
                    new Response
                {
                    description =
                        "Method Is Not Allowed. When the Snapshot-Identifier header is present the method is not allowed."
                });
            }

            return(new Operation
            {
                tags = new List <string>
                {
                    OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
                    .ToCamelCase()
                },
                summary = "Deletes an existing resource using the resource identifier.",
                description =
                    "The DELETE operation is used to delete an existing resource by identifier. If the resource doesn't exist, an error will result (the resource will not be found).",
                operationId = $"delete{openApiMetadataResource.Name}ById",
                deprecated = openApiMetadataResource.IsDeprecated,
                consumes = new[]
                {
                    _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Writable)
                },
                parameters = new[]
                {
                    OpenApiMetadataDocumentHelper.CreateIdParameter(),
                    CreateIfMatchParameter("DELETE from removing")
                },
                responses = responses
            });
        }
 private Operation CreateGetByIdOperation(OpenApiMetadataPathsResource openApiMetadataResource)
 {
     return(new Operation
     {
         tags = new List <string>
         {
             OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
             .ToCamelCase()
         },
         summary = "Retrieves a specific resource using the resource's identifier (using the \"Get By Id\" pattern).",
         description = "This GET operation retrieves a resource by the specified resource identifier.",
         operationId = $"get{openApiMetadataResource.Resource.PluralName}ById",
         deprecated = openApiMetadataResource.IsDeprecated,
         produces = new[]
         {
             _contentTypeStrategy.GetOperationContentType(openApiMetadataResource, ContentTypeUsage.Readable)
         },
         parameters = new[]
         {
             // Path parameters need to be inline in the operation, and not referenced.
             OpenApiMetadataDocumentHelper.CreateIdParameter(),
             new Parameter {
                 @ref = OpenApiMetadataDocumentHelper.GetParameterReference("If-None-Match")
             }
         }.Concat(
             openApiMetadataResource.DefaultGetByIdParameters
             .Select(p => new Parameter {
             @ref = OpenApiMetadataDocumentHelper.GetParameterReference(p)
         }))
         .ToList(),
         responses =
             OpenApiMetadataDocumentHelper.GetReadOperationResponses(
                 _pathsFactoryNamingStrategy.GetResourceName(openApiMetadataResource, ContentTypeUsage.Readable),
                 false)
     });
 }
Exemple #22
0
        // NOTE: This adds the deletes get request for change queries.
        private Operation CreateDeletesOperation(OpenApiMetadataPathsResource openApiMetadataResource)
        {
            var responses = OpenApiMetadataDocumentHelper.GetReadOperationResponses(
                _pathsFactoryNamingStrategy.GetResourceName(openApiMetadataResource, ContentTypeUsage.Readable),
                true, true);

            var parameters = new List <Parameter>
            {
                new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("offset")
                },
                new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("limit")
                },
                new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("MinChangeVersion")
                },
                new Parameter {
                    @ref = OpenApiMetadataDocumentHelper.GetParameterReference("MaxChangeVersion")
                }
            };

            if (_apiSettings.IsFeatureEnabled(ApiFeature.ChangeQueries.GetConfigKeyName()))
            {
                responses.Add(
                    "410",
                    new Response
                {
                    description =
                        "Gone. An attempt to connect to the database for the snapshot specified by the Snapshot-Identifier header was unsuccessful (indicating the snapshot may have been removed)."
                });

                parameters.Add(new Parameter {
                    name        = "Snapshot-Identifier",
                    @in         = "header",
                    description = "Indicates the Snapshot-Identifier that should be used.",
                    type        = "string",
                    required    = false
                });
            }

            return(new Operation
            {
                tags = new List <string>
                {
                    OpenApiMetadataDocumentHelper.GetResourcePluralName(openApiMetadataResource.Resource)
                    .ToCamelCase()
                },
                summary = "Retrieves deleted resources based on change version.",
                description = "The DELETES operation is used to retrieve deleted resources.",
                operationId = $"deletes{openApiMetadataResource.Resource.PluralName}",
                deprecated = openApiMetadataResource.IsDeprecated,
                consumes = new[]
                {
                    _contentTypeStrategy.GetOperationContentType(
                        openApiMetadataResource,
                        ContentTypeUsage.Writable)
                },
                parameters = parameters,
                responses = responses
            });
        }
        private Schema CreateResourceSchema(OpenApiMetadataResource openApiMetadataResource)
        {
            var resource = openApiMetadataResource.Resource;

            var properties = resource.UnifiedKeyAllProperties()
                             .Select(
                x => new PropertySchemaInfo
            {
                PropertyName = x.JsonPropertyName,
                IsRequired   = !x.PropertyType.IsNullable && !x.IsServerAssigned,
                Sort         = SortOrder(x.PropertyName, x.IsIdentifying),
                Schema       = OpenApiMetadataDocumentHelper.CreatePropertySchema(x)
            }).Concat(
                resource.Collections.Select(
                    x => new PropertySchemaInfo
            {
                PropertyName = CreateCollectionKey(x),
                IsRequired   = x.Association.IsRequiredCollection,
                Sort         = SortOrder(x.PropertyName, x.Association.IsRequiredCollection),
                Schema       = CreateCollectionSchema(x, openApiMetadataResource)
            })).Concat(
                resource.EmbeddedObjects.Select(
                    x => new PropertySchemaInfo
            {
                PropertyName = x.JsonPropertyName,
                Sort         = SortOrder(x.PropertyName, false),
                Schema       = CreateEmbeddedObjectSchema(x, openApiMetadataResource)
            })).Concat(
                resource.References.Select(
                    x => new PropertySchemaInfo
            {
                PropertyName = x.PropertyName,
                IsRequired   = x.IsRequired,
                IsReference  = true,
                Sort         = 3,
                Schema       = new Schema
                {
                    @ref = OpenApiMetadataDocumentHelper.GetDefinitionReference(
                        _openApiMetadataDefinitionsFactoryNamingStrategy.GetReferenceName(openApiMetadataResource.Resource, x))
                }

                // NOTE: currently there is an open issue with openApiMetadata-ui to address
                // objects showing up in the ui that have a reference and
                // other properties within the schema. The standard at this time does
                // not support this use case. (The error we get is:
                // Sibling values are not allowed along side $refs.
                // As of openApiMetadata-ui 3.11.0 this has not been resolved.
                // https://github.com/OAI/OpenAPI-Specification/issues/556
                // TODO: JSM - Once the standard is updated to accept sibling values along
                // side with $refs, uncomment the line below
                // isIdentity = x.Association.IsIdentifying ? true : (bool?) null
            })).Distinct(new PropertySchemaInfoComparer()).ToList();

            var propertyDict = properties.OrderBy(x => x.Sort).ThenBy(x => x.PropertyName)
                               .ToDictionary(x => x.PropertyName.ToCamelCase(), x => x.Schema);

            propertyDict.Add("_etag", EtagSchema);
            var bridgeSchema = GetEdFiExtensionBridgeReferenceSchema(resource, openApiMetadataResource);

            if (bridgeSchema != null)
            {
                propertyDict.Add(ExtensionCollectionKey, bridgeSchema);
            }

            var requiredProperties = properties
                                     .Where(x => x.IsRequired && !x.PropertyName.EqualsIgnoreCase("id"))
                                     .Select(x => x.PropertyName.ToCamelCase()).ToList();

            return(new Schema
            {
                type = "object",
                required = requiredProperties.Any()
                    ? requiredProperties
                    : null,
                properties = propertyDict
            });
        }
 private static Schema RefSchema(string referenceName)
 => new Schema
 {
     @ref = OpenApiMetadataDocumentHelper.GetDefinitionReference(referenceName)
 };
        public string Create(IOpenApiMetadataResourceStrategy resourceStrategy, OpenApiMetadataDocumentContext documentContext)
        {
            try
            {
                var parametersFactory = new OpenApiMetadataParametersFactory(_defaultPageSizeLimitProvider);

                var definitionsFactory =
                    OpenApiMetadataDocumentFactoryHelper.CreateOpenApiMetadataDefinitionsFactory(documentContext);

                var responsesFactory = new OpenApiMetadataResponsesFactory();

                var pathsFactory =
                    OpenApiMetadataDocumentFactoryHelper.CreateOpenApiMetadataPathsFactory(
                        documentContext, _apiSettings);

                var tagsFactory =
                    OpenApiMetadataDocumentFactoryHelper.CreateOpenApiMetadataTagsFactory(documentContext);

                var resources = resourceStrategy.GetFilteredResources(documentContext)
                                .ToList();

                var openApiMetadataDocument = new OpenApiMetadataDocument
                {
                    info = new Info
                    {
                        title       = "Ed-Fi Operational Data Store API",
                        version     = $"{ApiVersionConstants.Ods}",
                        description =
                            "The Ed-Fi ODS / API enables applications to read and write education data stored in an Ed-Fi ODS through a secure REST interface. \n***\n > *Note: Consumers of ODS / API information should sanitize all data for display and storage. The ODS / API provides reasonable safeguards against cross-site scripting attacks and other malicious content, but the platform does not and cannot guarantee that the data it contains is free of all potentially harmful content.* \n***\n"
                    },
                    host                = "%HOST%",
                    basePath            = "%BASE_PATH%",
                    securityDefinitions =
                        new Dictionary <string, SecurityScheme>
                    {
                        {
                            "oauth2_client_credentials", new SecurityScheme
                            {
                                type        = "oauth2",
                                description =
                                    "Ed-Fi ODS/API OAuth 2.0 Client Credentials Grant Type authorization",
                                flow     = "application",
                                tokenUrl = "%TOKEN_URL%",
                                scopes   = new Dictionary <string, string>()
                            }
                        }
                    },
                    security =
                        new List <IDictionary <string, IEnumerable <string> > >
                    {
                        new Dictionary <string, IEnumerable <string> > {
                            { "oauth2_client_credentials", new string[0] }
                        }
                    },
                    consumes = documentContext.IsCompositeContext
                        ? null
                        : OpenApiMetadataDocumentHelper.GetConsumes(),
                    produces    = OpenApiMetadataDocumentHelper.GetProduces(),
                    tags        = tagsFactory.Create(resources),
                    paths       = pathsFactory.Create(resources, documentContext.IsCompositeContext),
                    definitions = definitionsFactory.Create(resources),
                    parameters  = parametersFactory.Create(documentContext.IsCompositeContext),
                    responses   = responsesFactory.Create()
                };

                return(JsonConvert.SerializeObject(
                           openApiMetadataDocument,
                           new JsonSerializerSettings {
                    NullValueHandling = NullValueHandling.Ignore
                }));
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
                throw;
            }
        }