change to name generator and make the build pass
This commit is contained in:
parent
cfd65654d8
commit
a39c8bf6b5
|
@ -7,6 +7,7 @@
|
|||
using System;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Generators;
|
||||
|
||||
namespace Microsoft.OpenApi.OData
|
||||
{
|
||||
|
@ -16,16 +17,6 @@ namespace Microsoft.OpenApi.OData
|
|||
/// </summary>
|
||||
public static class EdmModelOpenApiMappingExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert <see cref="IEdmModel"/> to <see cref="OpenApiDocument"/>.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The converted Open API document object.</returns>
|
||||
public static OpenApiDocument Convert(this IEdmModel model)
|
||||
{
|
||||
return new OpenApiDocumentGenerator(model).Generate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert <see cref="IEdmModel"/> to <see cref="OpenApiDocument"/> using a configure action.
|
||||
/// </summary>
|
||||
|
@ -34,7 +25,36 @@ namespace Microsoft.OpenApi.OData
|
|||
/// <returns>The converted Open API document object.</returns>
|
||||
public static OpenApiDocument Convert(this IEdmModel model, Action<OpenApiDocument> configure)
|
||||
{
|
||||
return new OpenApiDocumentGenerator(model, configure).Generate();
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
if (configure == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(configure));
|
||||
}
|
||||
|
||||
OpenApiDocument document = model.CreateDocument();
|
||||
|
||||
configure(document);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert <see cref="IEdmModel"/> to <see cref="OpenApiDocument"/>.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The converted Open API document object.</returns>
|
||||
public static OpenApiDocument Convert(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
return model.CreateDocument();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiComponents"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiComponentsGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate the <see cref="OpenApiComponents"/>.
|
||||
/// The value of components is a Components Object.
|
||||
/// It holds maps of reusable schemas describing message bodies, operation parameters, and responses.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The components object.</returns>
|
||||
public static OpenApiComponents CreateComponents(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
// "components": {
|
||||
// "schemas": …,
|
||||
// "parameters": …,
|
||||
// "responses": …
|
||||
// }
|
||||
return new OpenApiComponents
|
||||
{
|
||||
// The value of schemas is a map of Schema Objects.
|
||||
// Each entity type, complex type, enumeration type, and type definition directly
|
||||
// or indirectly used in the paths field is represented as a name/value pair of the schemas map.
|
||||
Schemas = model.CreateSchemas(),
|
||||
|
||||
// The value of parameters is a map of Parameter Objects.
|
||||
// It allows defining query options and headers that can be reused across operations of the service.
|
||||
Parameters = model.CreateParameters(),
|
||||
|
||||
// The value of responses is a map of Response Objects.
|
||||
// It allows defining responses that can be reused across operations of the service.
|
||||
Responses = model.CreateResponses()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiDocument"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiDocumentGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a <see cref="OpenApiDocument"/>.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The <see cref="OpenApiDocument"/> object.</returns>
|
||||
public static OpenApiDocument CreateDocument(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
// An OAS document consists of a single OpenAPI Object represented as OpenApiDocument object.
|
||||
// {
|
||||
// "openapi":"3.0.0",
|
||||
// "info": …,
|
||||
// "servers": …,
|
||||
// "tags": …,
|
||||
// "paths": …,
|
||||
// "components": …
|
||||
// }
|
||||
return new OpenApiDocument
|
||||
{
|
||||
SpecVersion = new Version(3, 0, 0),
|
||||
|
||||
Info = model.CreateInfo(),
|
||||
|
||||
Servers = model.CreateServers(),
|
||||
|
||||
Paths = model.CreatePaths(),
|
||||
|
||||
Components = model.CreateComponents(),
|
||||
|
||||
Tags = model.CreateTags()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiInfo"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiInfoGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create <see cref="OpenApiInfo"/> object.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The info object.</returns>
|
||||
public static OpenApiInfo CreateInfo(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
// The value of info is an Info Object,
|
||||
// It contains the fields title and version, and optionally the field description.
|
||||
return new OpenApiInfo
|
||||
{
|
||||
// The value of title is the value of the unqualified annotation Core.Description
|
||||
// of the main schema or the entity container of the OData service.
|
||||
// If no Core.Description is present, a default title has to be provided as this is a required OpenAPI field.
|
||||
Title = "OData Service for namespace " + model.DeclaredNamespaces.FirstOrDefault(),
|
||||
|
||||
// The value of version is the value of the annotation Core.SchemaVersion(see[OData - VocCore]) of the main schema.
|
||||
// If no Core.SchemaVersion is present, a default version has to be provided as this is a required OpenAPI field.
|
||||
Version = "0.1.0",
|
||||
|
||||
// The value of description is the value of the annotation Core.LongDescription
|
||||
// of the main schema or the entity container.
|
||||
// While this field is optional, it prominently appears in OpenAPI exploration tools,
|
||||
// so a default description should be provided if no Core.LongDescription annotation is present.
|
||||
// Description = "This OData service is located at " + Settings.BaseUri?.OriginalString
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +1,34 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmNavigationSourceExtensions.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Entension methods for navigation source
|
||||
/// Extension methods to create <see cref="OpenApiOperation"/> by Edm elements.
|
||||
/// </summary>
|
||||
internal static class EdmNavigationSourceExtensions
|
||||
internal static class OpenApiOperationGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// The Path Item Object for the entity set contains the keyword get with an Operation Object as value
|
||||
/// that describes the capabilities for querying the entity set.
|
||||
/// </summary>
|
||||
/// <param name="entitySet">The entity set.</param>
|
||||
/// <returns>The created <see cref="OpenApiOperation"/>.</returns>
|
||||
public static OpenApiOperation CreateGetOperationForEntitySet(this IEdmEntitySet entitySet)
|
||||
{
|
||||
if (entitySet == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(entitySet));
|
||||
}
|
||||
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Get entities from " + entitySet.Name,
|
||||
|
@ -32,36 +41,45 @@ namespace Microsoft.OpenApi.OData
|
|||
}
|
||||
};
|
||||
|
||||
// The parameters array contains Parameter Objects for system query options allowed for this entity set,
|
||||
// and it does not list system query options not allowed for this entity set.
|
||||
operation.Parameters = new List<OpenApiParameter>
|
||||
{
|
||||
new OpenApiParameter
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/parameters/top")
|
||||
Pointer = new OpenApiReference(ReferenceType.Parameter, "top")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/parameters/skip")
|
||||
Pointer = new OpenApiReference(ReferenceType.Parameter, "skip")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/parameters/search")
|
||||
Pointer = new OpenApiReference(ReferenceType.Parameter, "search")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/parameters/filter")
|
||||
Pointer = new OpenApiReference(ReferenceType.Parameter, "filter")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/parameters/count")
|
||||
Pointer = new OpenApiReference(ReferenceType.Parameter, "count")
|
||||
},
|
||||
|
||||
CreateOrderByParameter(entitySet),
|
||||
// the syntax of the system query options $expand, $select, and $orderby is too flexible
|
||||
// to be formally described with OpenAPI Specification means, yet the typical use cases
|
||||
// of just providing a comma-separated list of properties can be expressed via an array-valued
|
||||
// parameter with an enum constraint
|
||||
entitySet.CreateOrderByParameter(),
|
||||
|
||||
CreateSelectParameter(entitySet),
|
||||
entitySet.CreateSelectParameter(),
|
||||
|
||||
CreateExpandParameter(entitySet),
|
||||
entitySet.CreateExpandParameter(),
|
||||
};
|
||||
|
||||
// The value of responses is a Responses Object.
|
||||
// It contains a name/value pair for the success case (HTTP response code 200)
|
||||
// describing the structure of a successful response referencing the schema of the entity set’s entity type in the global schemas
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
{
|
||||
|
@ -88,7 +106,7 @@ namespace Microsoft.OpenApi.OData
|
|||
Type = "array",
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,11 +223,11 @@ namespace Microsoft.OpenApi.OData
|
|||
}
|
||||
};
|
||||
|
||||
operation.Parameters = CreateKeyParameters(entitySet.EntityType());
|
||||
operation.Parameters = entitySet.EntityType().CreateKeyParameters();
|
||||
|
||||
operation.Parameters.Add(CreateSelectParameter(entitySet));
|
||||
operation.Parameters.Add(entitySet.CreateSelectParameter());
|
||||
|
||||
operation.Parameters.Add(CreateExpandParameter(entitySet));
|
||||
operation.Parameters.Add(entitySet.CreateExpandParameter());
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
|
@ -226,7 +244,7 @@ namespace Microsoft.OpenApi.OData
|
|||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -254,9 +272,9 @@ namespace Microsoft.OpenApi.OData
|
|||
};
|
||||
|
||||
operation.Parameters = new List<OpenApiParameter>();
|
||||
operation.Parameters.Add(CreateSelectParameter(singleton));
|
||||
operation.Parameters.Add(singleton.CreateSelectParameter());
|
||||
|
||||
operation.Parameters.Add(CreateExpandParameter(singleton));
|
||||
operation.Parameters.Add(singleton.CreateExpandParameter());
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
|
@ -273,7 +291,7 @@ namespace Microsoft.OpenApi.OData
|
|||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/" + singleton.EntityType().FullName())
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, singleton.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +318,7 @@ namespace Microsoft.OpenApi.OData
|
|||
}
|
||||
};
|
||||
|
||||
operation.Parameters = CreateKeyParameters(entitySet.EntityType());
|
||||
operation.Parameters = entitySet.EntityType().CreateKeyParameters();
|
||||
|
||||
operation.RequestBody = new OpenApiRequestBody
|
||||
{
|
||||
|
@ -313,7 +331,7 @@ namespace Microsoft.OpenApi.OData
|
|||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +371,7 @@ namespace Microsoft.OpenApi.OData
|
|||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/" + singleton.EntityType().FullName())
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, singleton.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +399,7 @@ namespace Microsoft.OpenApi.OData
|
|||
}
|
||||
}
|
||||
};
|
||||
operation.Parameters = CreateKeyParameters(entitySet.EntityType());
|
||||
operation.Parameters = entitySet.EntityType().CreateKeyParameters();
|
||||
operation.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = "If-Match",
|
||||
|
@ -400,135 +418,5 @@ namespace Microsoft.OpenApi.OData
|
|||
};
|
||||
return operation;
|
||||
}
|
||||
|
||||
public static OpenApiParameter CreateOrderByParameter(this IEdmEntitySet entitySet)
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = "$orderby",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Order items by property values",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
UniqueItems = true,
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Enum = CreateOrderbyItems(entitySet)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public static IList<IOpenApiAny> CreateOrderbyItems(this IEdmEntitySet entitySet)
|
||||
{
|
||||
IList<IOpenApiAny> orderByItems = new List<IOpenApiAny>();
|
||||
|
||||
IEdmEntityType entityType = entitySet.EntityType();
|
||||
|
||||
foreach (var property in entityType.StructuralProperties())
|
||||
{
|
||||
orderByItems.Add(new OpenApiString(property.Name));
|
||||
orderByItems.Add(new OpenApiString(property.Name + " desc"));
|
||||
}
|
||||
|
||||
return orderByItems;
|
||||
}
|
||||
|
||||
public static OpenApiParameter CreateSelectParameter(this IEdmNavigationSource navigationSource)
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = "$select",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Select properties to be returned",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
UniqueItems = true,
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Enum = CreateSelectItems(navigationSource.EntityType())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public static IList<IOpenApiAny> CreateSelectItems(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<IOpenApiAny> selectItems = new List<IOpenApiAny>();
|
||||
|
||||
foreach (var property in entityType.StructuralProperties())
|
||||
{
|
||||
selectItems.Add(new OpenApiString(property.Name));
|
||||
}
|
||||
|
||||
return selectItems;
|
||||
}
|
||||
|
||||
public static OpenApiParameter CreateExpandParameter(this IEdmNavigationSource navigationSource)
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = "$expand",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Expand related entities",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
UniqueItems = true,
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Enum = CreateExpandItems(navigationSource.EntityType())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public static IList<IOpenApiAny> CreateExpandItems(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<IOpenApiAny> expandItems = new List<IOpenApiAny>
|
||||
{
|
||||
new OpenApiString("*")
|
||||
};
|
||||
|
||||
foreach (var property in entityType.NavigationProperties())
|
||||
{
|
||||
expandItems.Add(new OpenApiString(property.Name));
|
||||
}
|
||||
|
||||
return expandItems;
|
||||
}
|
||||
|
||||
public static IList<OpenApiParameter> CreateKeyParameters(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<OpenApiParameter> parameters = new List<OpenApiParameter>();
|
||||
|
||||
// append key parameter
|
||||
foreach (var keyProperty in entityType.Key())
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = keyProperty.Name,
|
||||
In = ParameterLocation.Path,
|
||||
Required = true,
|
||||
Description = "key: " + keyProperty.Name,
|
||||
Schema = keyProperty.Type.CreateSchema()
|
||||
};
|
||||
|
||||
parameters.Add(parameter);
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,284 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiParameter"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiParameterGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create key parameters for the <see cref="IEdmEntityType"/>.
|
||||
/// </summary>
|
||||
/// <param name="entityType">The entity type.</param>
|
||||
/// <returns>The created the list of <see cref="OpenApiParameter"/>.</returns>
|
||||
public static IList<OpenApiParameter> CreateKeyParameters(this IEdmEntityType entityType)
|
||||
{
|
||||
if (entityType == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(entityType));
|
||||
}
|
||||
|
||||
IList<OpenApiParameter> parameters = new List<OpenApiParameter>();
|
||||
|
||||
// append key parameter
|
||||
foreach (var keyProperty in entityType.Key())
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = keyProperty.Name,
|
||||
In = ParameterLocation.Path,
|
||||
Required = true,
|
||||
Description = "key: " + keyProperty.Name,
|
||||
Schema = keyProperty.Type.CreateSchema()
|
||||
};
|
||||
|
||||
parameters.Add(parameter);
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create $orderby parameter for the <see cref="IEdmEntitySet"/>.
|
||||
/// </summary>
|
||||
/// <param name="entitySet">The entity set.</param>
|
||||
/// <returns>The created <see cref="OpenApiParameter"/>.</returns>
|
||||
public static OpenApiParameter CreateOrderByParameter(this IEdmEntitySet entitySet)
|
||||
{
|
||||
if (entitySet == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(entitySet));
|
||||
}
|
||||
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = "$orderby",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Order items by property values",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
UniqueItems = true,
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Enum = VisitOrderbyItems(entitySet.EntityType())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create $select parameter for the <see cref="IEdmNavigationSource"/>.
|
||||
/// </summary>
|
||||
/// <param name="navigationSource">The navigation source.</param>
|
||||
/// <returns>The created <see cref="OpenApiParameter"/>.</returns>
|
||||
public static OpenApiParameter CreateSelectParameter(this IEdmNavigationSource navigationSource)
|
||||
{
|
||||
if (navigationSource == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(navigationSource));
|
||||
}
|
||||
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = "$select",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Select properties to be returned",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
UniqueItems = true,
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Enum = VisitSelectItems(navigationSource.EntityType())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create $expand parameter for the <see cref="IEdmNavigationSource"/>.
|
||||
/// </summary>
|
||||
/// <param name="navigationSource">The navigation source.</param>
|
||||
/// <returns>The created <see cref="OpenApiParameter"/>.</returns>
|
||||
public static OpenApiParameter CreateExpandParameter(this IEdmNavigationSource navigationSource)
|
||||
{
|
||||
if (navigationSource == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(navigationSource));
|
||||
}
|
||||
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = "$expand",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Expand related entities",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
UniqueItems = true,
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Enum = VisitExpandItems(navigationSource.EntityType())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return parameter;
|
||||
}
|
||||
|
||||
// 4.6.2 Field parameters in components
|
||||
public static IDictionary<string, OpenApiParameter> CreateParameters(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
// It allows defining query options and headers that can be reused across operations of the service.
|
||||
// The value of parameters is a map of Parameter Objects
|
||||
return new Dictionary<string, OpenApiParameter>
|
||||
{
|
||||
{ "top", CreateTop() },
|
||||
{ "skip", CreateSkip() },
|
||||
{ "count", CreateCount() },
|
||||
{ "filter", CreateFilter() },
|
||||
{ "search", CreateSearch() },
|
||||
};
|
||||
}
|
||||
|
||||
// #top
|
||||
private static OpenApiParameter CreateTop()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$top",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Show only the first n items",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "integer",
|
||||
Minimum = 0,
|
||||
},
|
||||
Example = new OpenApiInteger(50)
|
||||
};
|
||||
}
|
||||
|
||||
// $skip
|
||||
private static OpenApiParameter CreateSkip()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$skip",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Skip the first n items",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "integer",
|
||||
Minimum = 0,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// $count
|
||||
private static OpenApiParameter CreateCount()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$count",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Include count of items",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "boolean"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// $filter
|
||||
private static OpenApiParameter CreateFilter()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$filter",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Filter items by property values",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// $search
|
||||
private static OpenApiParameter CreateSearch()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$search",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Search items by search phrases",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static IList<IOpenApiAny> VisitOrderbyItems(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<IOpenApiAny> orderByItems = new List<IOpenApiAny>();
|
||||
|
||||
foreach (var property in entityType.StructuralProperties())
|
||||
{
|
||||
orderByItems.Add(new OpenApiString(property.Name));
|
||||
orderByItems.Add(new OpenApiString(property.Name + " desc"));
|
||||
}
|
||||
|
||||
return orderByItems;
|
||||
}
|
||||
|
||||
private static IList<IOpenApiAny> VisitSelectItems(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<IOpenApiAny> selectItems = new List<IOpenApiAny>();
|
||||
|
||||
foreach (var property in entityType.StructuralProperties())
|
||||
{
|
||||
selectItems.Add(new OpenApiString(property.Name));
|
||||
}
|
||||
|
||||
return selectItems;
|
||||
}
|
||||
|
||||
private static IList<IOpenApiAny> VisitExpandItems(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<IOpenApiAny> expandItems = new List<IOpenApiAny>
|
||||
{
|
||||
new OpenApiString("*")
|
||||
};
|
||||
|
||||
foreach (var property in entityType.NavigationProperties())
|
||||
{
|
||||
expandItems.Add(new OpenApiString(property.Name));
|
||||
}
|
||||
|
||||
return expandItems;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,38 +1,137 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmElementOpenApiElementExtensions.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for Edm Elements to Open Api Elements.
|
||||
/// Extension methods to create <see cref="OpenApiPathItem"/> by Edm elements.
|
||||
/// </summary>
|
||||
internal static class EdmElementOpenApiElementExtensions
|
||||
internal static class OpenApiPathItemGenerator
|
||||
{
|
||||
private static IDictionary<string, OpenApiResponse> Responses =
|
||||
new Dictionary<string, OpenApiResponse>
|
||||
{
|
||||
{ "default",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/responses/error")
|
||||
}
|
||||
},
|
||||
{ "204", new OpenApiResponse { Description = "Success"} },
|
||||
};
|
||||
|
||||
public static KeyValuePair<string, OpenApiResponse> GetResponse(this string statusCode)
|
||||
/// <summary>
|
||||
/// Path items for Entity Sets.
|
||||
/// Each entity set is represented as a name/value pair
|
||||
/// whose name is the service-relative resource path of the entity set prepended with a forward slash,
|
||||
/// and whose value is a Path Item Object.
|
||||
/// </summary>
|
||||
/// <param name="entitySet">The Edm entity set.</param>
|
||||
/// <returns>The path items.</returns>
|
||||
public static IDictionary<string, OpenApiPathItem> CreatePathItems(this IEdmEntitySet entitySet)
|
||||
{
|
||||
return new KeyValuePair<string, OpenApiResponse>(statusCode, Responses[statusCode]);
|
||||
if (entitySet == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(entitySet));
|
||||
}
|
||||
|
||||
IDictionary<string, OpenApiPathItem> paths = new Dictionary<string, OpenApiPathItem>();
|
||||
|
||||
// entity set
|
||||
OpenApiPathItem pathItem = new OpenApiPathItem();
|
||||
|
||||
pathItem.AddOperation(OperationType.Get, entitySet.CreateGetOperationForEntitySet());
|
||||
|
||||
pathItem.AddOperation(OperationType.Post, entitySet.CreatePostOperationForEntitySet());
|
||||
|
||||
paths.Add("/" + entitySet.Name, pathItem);
|
||||
|
||||
// entity
|
||||
string entityPathName = entitySet.CreatePathNameForEntity();
|
||||
pathItem = new OpenApiPathItem();
|
||||
|
||||
pathItem.AddOperation(OperationType.Get, entitySet.CreateGetOperationForEntity());
|
||||
|
||||
pathItem.AddOperation(OperationType.Patch, entitySet.CreatePatchOperationForEntity());
|
||||
|
||||
pathItem.AddOperation(OperationType.Delete, entitySet.CreateDeleteOperationForEntity());
|
||||
|
||||
paths.Add(entityPathName, pathItem);
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
public static IDictionary<string, OpenApiPathItem> CreatePathItems(this IEdmSingleton singleton)
|
||||
{
|
||||
if (singleton == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(singleton));
|
||||
}
|
||||
|
||||
IDictionary<string, OpenApiPathItem> paths = new Dictionary<string, OpenApiPathItem>();
|
||||
|
||||
// Singleton
|
||||
string entityPathName = singleton.CreatePathNameForSingleton();
|
||||
OpenApiPathItem pathItem = new OpenApiPathItem();
|
||||
pathItem.AddOperation(OperationType.Get, singleton.CreateGetOperationForSingleton());
|
||||
pathItem.AddOperation(OperationType.Patch, singleton.CreatePatchOperationForSingleton());
|
||||
paths.Add(entityPathName, pathItem);
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
public static IDictionary<string, OpenApiPathItem> CreateOperationPathItems(this IEdmNavigationSource navigationSource,
|
||||
IDictionary<IEdmTypeReference, IEdmOperation> boundOperations)
|
||||
{
|
||||
IDictionary<string, OpenApiPathItem> operationPathItems = new Dictionary<string, OpenApiPathItem>();
|
||||
|
||||
IEnumerable<IEdmOperation> operations;
|
||||
IEdmEntitySet entitySet = navigationSource as IEdmEntitySet;
|
||||
// collection bound
|
||||
if (entitySet != null)
|
||||
{
|
||||
operations = FindOperations(navigationSource.EntityType(), boundOperations, collection: true);
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
OpenApiPathItem openApiOperation = operation.CreatePathItem();
|
||||
string operationPathName = operation.CreatePathItemName();
|
||||
operationPathItems.Add("/" + navigationSource.Name + operationPathName, openApiOperation);
|
||||
}
|
||||
}
|
||||
|
||||
// non-collection bound
|
||||
operations = FindOperations(navigationSource.EntityType(), boundOperations, collection: false);
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
OpenApiPathItem openApiOperation = operation.CreatePathItem();
|
||||
string operationPathName = operation.CreatePathItemName();
|
||||
|
||||
string temp;
|
||||
if (entitySet != null)
|
||||
{
|
||||
temp = entitySet.CreatePathNameForEntity();
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = "/" + navigationSource.Name;
|
||||
}
|
||||
operationPathItems.Add(temp + operationPathName, openApiOperation);
|
||||
}
|
||||
|
||||
return operationPathItems;
|
||||
}
|
||||
|
||||
private static IEnumerable<IEdmOperation> FindOperations(IEdmEntityType entityType,
|
||||
IDictionary<IEdmTypeReference, IEdmOperation> boundOperations,
|
||||
bool collection)
|
||||
{
|
||||
string fullTypeName = collection ? "Collection(" + entityType.FullName() + ")" :
|
||||
entityType.FullName();
|
||||
|
||||
foreach (var item in boundOperations)
|
||||
{
|
||||
if (item.Key.FullName() == fullTypeName)
|
||||
{
|
||||
yield return item.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static OpenApiPathItem CreatePathItem(this IEdmOperationImport operationImport)
|
||||
|
@ -68,8 +167,8 @@ namespace Microsoft.OpenApi.OData
|
|||
{
|
||||
Summary = "Invoke action " + action.Name,
|
||||
Tags = CreateTags(action),
|
||||
Parameters = CreateParameters(action),
|
||||
Responses = CreateResponses(action)
|
||||
Parameters = action.CreateParameters(),
|
||||
Responses = action.CreateResponses()
|
||||
};
|
||||
|
||||
pathItem.AddOperation(OperationType.Post, post);
|
||||
|
@ -88,8 +187,8 @@ namespace Microsoft.OpenApi.OData
|
|||
{
|
||||
Summary = "Invoke function " + function.Name,
|
||||
Tags = CreateTags(function),
|
||||
Parameters = CreateParameters(function),
|
||||
Responses = CreateResponses(function)
|
||||
Parameters = function.CreateParameters(),
|
||||
Responses = function.CreateResponses()
|
||||
};
|
||||
|
||||
pathItem.AddOperation(OperationType.Get, get);
|
||||
|
@ -142,38 +241,6 @@ namespace Microsoft.OpenApi.OData
|
|||
return ((IEdmFunction)operation).CreatePathItemName();
|
||||
}
|
||||
|
||||
private static OpenApiResponses CreateResponses(this IEdmAction actionImport)
|
||||
{
|
||||
return new OpenApiResponses
|
||||
{
|
||||
"204".GetResponse(),
|
||||
"default".GetResponse()
|
||||
};
|
||||
}
|
||||
|
||||
private static OpenApiResponses CreateResponses(this IEdmFunction function)
|
||||
{
|
||||
OpenApiResponses responses = new OpenApiResponses();
|
||||
|
||||
OpenApiResponse response = new OpenApiResponse
|
||||
{
|
||||
Description = "Success",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = function.ReturnType.CreateSchema()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
responses.Add("200", response);
|
||||
responses.Add("default".GetResponse());
|
||||
return responses;
|
||||
}
|
||||
|
||||
private static IList<string> CreateTags(this IEdmOperationImport operationImport)
|
||||
{
|
||||
if (operationImport.EntitySet != null)
|
|
@ -0,0 +1,108 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiPaths"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiPathsGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create the <see cref="OpenApiPaths"/>
|
||||
/// The value of paths is a Paths Object.
|
||||
/// It is the main source of information on how to use the described API.
|
||||
/// It consists of name/value pairs whose name is a path template relative to the service root URL,
|
||||
/// and whose value is a Path Item Object.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>the paths object.</returns>
|
||||
public static OpenApiPaths CreatePaths(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
// Due to the power and flexibility of OData a full representation of all service capabilities
|
||||
// in the Paths Object is typically not feasible, so this mapping only describes the minimum
|
||||
// information desired in the Paths Object.
|
||||
OpenApiPaths paths = new OpenApiPaths();
|
||||
if (model.EntityContainer != null)
|
||||
{
|
||||
IDictionary<IEdmTypeReference, IEdmOperation> boundOperations = new Dictionary<IEdmTypeReference, IEdmOperation>();
|
||||
foreach (var edmOperation in model.SchemaElements.OfType<IEdmOperation>().Where(e => e.IsBound))
|
||||
{
|
||||
IEdmOperationParameter bindingParameter = edmOperation.Parameters.First();
|
||||
boundOperations.Add(bindingParameter.Type, edmOperation);
|
||||
}
|
||||
|
||||
foreach (var element in model.EntityContainer.Elements)
|
||||
{
|
||||
switch (element.ContainerElementKind)
|
||||
{
|
||||
case EdmContainerElementKind.EntitySet: // entity set
|
||||
IEdmEntitySet entitySet = element as IEdmEntitySet;
|
||||
if (entitySet != null)
|
||||
{
|
||||
foreach (var item in entitySet.CreatePathItems())
|
||||
{
|
||||
paths.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
foreach(var item in entitySet.CreateOperationPathItems(boundOperations))
|
||||
{
|
||||
paths.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.Singleton: // singleton
|
||||
IEdmSingleton singleton = element as IEdmSingleton;
|
||||
if (singleton != null)
|
||||
{
|
||||
foreach (var item in singleton.CreatePathItems())
|
||||
{
|
||||
paths.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
foreach (var item in singleton.CreateOperationPathItems(boundOperations))
|
||||
{
|
||||
paths.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.FunctionImport: // function import
|
||||
IEdmFunctionImport functionImport = element as IEdmFunctionImport;
|
||||
if (functionImport != null)
|
||||
{
|
||||
var functionImportPathItem = functionImport.CreatePathItem();
|
||||
|
||||
paths.Add(functionImport.CreatePathItemName(), functionImportPathItem);
|
||||
}
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.ActionImport: // action import
|
||||
IEdmActionImport actionImport = element as IEdmActionImport;
|
||||
if (actionImport != null)
|
||||
{
|
||||
var functionImportPathItem = actionImport.CreatePathItem();
|
||||
paths.Add(actionImport.CreatePathItemName(), functionImportPathItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiResponse"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiResponseGenerator
|
||||
{
|
||||
private static IDictionary<string, OpenApiResponse> Responses =
|
||||
new Dictionary<string, OpenApiResponse>
|
||||
{
|
||||
{ "default",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Pointer = new OpenApiReference(ReferenceType.Response, "error")
|
||||
}
|
||||
},
|
||||
{ "204", new OpenApiResponse { Description = "Success"} },
|
||||
};
|
||||
|
||||
public static KeyValuePair<string, OpenApiResponse> GetResponse(this string statusCode)
|
||||
{
|
||||
return new KeyValuePair<string, OpenApiResponse>(statusCode, Responses[statusCode]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create <see cref="OpenApiInfo"/> object.
|
||||
/// It contains one name/value pair for the standard OData error response
|
||||
/// that is referenced from all operations of the service.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The name/value pairs for the standard OData error response.</returns>
|
||||
public static IDictionary<string, OpenApiResponse> CreateResponses(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
return new Dictionary<string, OpenApiResponse>
|
||||
{
|
||||
{ "error", CreateError() }
|
||||
};
|
||||
}
|
||||
|
||||
public static OpenApiResponses CreateResponses(this IEdmAction actionImport)
|
||||
{
|
||||
return new OpenApiResponses
|
||||
{
|
||||
"204".GetResponse(),
|
||||
"default".GetResponse()
|
||||
};
|
||||
}
|
||||
|
||||
public static OpenApiResponses CreateResponses(this IEdmFunction function)
|
||||
{
|
||||
OpenApiResponses responses = new OpenApiResponses();
|
||||
|
||||
OpenApiResponse response = new OpenApiResponse
|
||||
{
|
||||
Description = "Success",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = function.ReturnType.CreateSchema()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
responses.Add("200", response);
|
||||
responses.Add("default".GetResponse());
|
||||
return responses;
|
||||
}
|
||||
|
||||
private static OpenApiResponse CreateError()
|
||||
{
|
||||
return new OpenApiResponse
|
||||
{
|
||||
Description = "error",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, "odata.error")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiSchema"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiSchemaGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create the dictionary of <see cref="OpenApiSchema"/> object.
|
||||
/// The name of each pair is the namespace-qualified name of the type. It uses the namespace instead of the alias.
|
||||
/// The value of each pair is a <see cref="OpenApiSchema"/>.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The info object.</returns>
|
||||
public static IDictionary<string, OpenApiSchema> CreateSchemas(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
IDictionary<string, OpenApiSchema> schemas = new Dictionary<string, OpenApiSchema>();
|
||||
|
||||
// Each entity type, complex type, enumeration type, and type definition directly
|
||||
// or indirectly used in the paths field is represented as a name / value pair of the schemas map.
|
||||
foreach (var element in model.SchemaElements)
|
||||
{
|
||||
switch (element.SchemaElementKind)
|
||||
{
|
||||
case EdmSchemaElementKind.TypeDefinition: // Type definition
|
||||
{
|
||||
IEdmType reference = (IEdmType)element;
|
||||
schemas.Add(reference.FullTypeName(), VisitSchemaType(model, reference));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
schemas.AppendODataErrors();
|
||||
return schemas;
|
||||
}
|
||||
|
||||
private static OpenApiSchema VisitSchemaType(IEdmModel model, IEdmType definition)
|
||||
{
|
||||
switch (definition.TypeKind)
|
||||
{
|
||||
case EdmTypeKind.Complex: // complex type
|
||||
case EdmTypeKind.Entity: // entity type
|
||||
return VisitStructuredType((IEdmStructuredType)definition, true);
|
||||
|
||||
case EdmTypeKind.Enum: // enum type
|
||||
return VisitEnumType(model, (IEdmEnumType)definition);
|
||||
|
||||
case EdmTypeKind.TypeDefinition: // type definition
|
||||
return VisitTypeDefinitions((IEdmTypeDefinition)definition);
|
||||
|
||||
case EdmTypeKind.None:
|
||||
default:
|
||||
throw Error.NotSupported(String.Format("Not supported {0} type kind.", definition.TypeKind));
|
||||
}
|
||||
}
|
||||
|
||||
// 4.6.1.2 Schemas for Enumeration Types
|
||||
private static OpenApiSchema VisitEnumType(IEdmModel model, IEdmEnumType enumType)
|
||||
{
|
||||
OpenApiSchema schema = new OpenApiSchema
|
||||
{
|
||||
// An enumeration type is represented as a Schema Object of type string
|
||||
Type = "string",
|
||||
|
||||
// containing the OpenAPI Specification enum keyword.
|
||||
Enum = new List<IOpenApiAny>(),
|
||||
|
||||
// It optionally can contain the field description,
|
||||
// whose value is the value of the unqualified annotation Core.Description of the enumeration type.
|
||||
Description = model.GetDescription(enumType)
|
||||
};
|
||||
|
||||
// Enum value is an array that contains a string with the member name for each enumeration member.
|
||||
foreach (IEdmEnumMember member in enumType.Members)
|
||||
{
|
||||
schema.Enum.Add(new OpenApiString(member.Name));
|
||||
}
|
||||
|
||||
schema.Title = (enumType as IEdmSchemaElement)?.Name;
|
||||
return schema;
|
||||
}
|
||||
|
||||
// 4.6.1.3 Schemas for Type Definitions
|
||||
private static OpenApiSchema VisitTypeDefinitions(IEdmTypeDefinition typeDefinition)
|
||||
{
|
||||
return typeDefinition?.UnderlyingType?.CreateSchema();
|
||||
}
|
||||
|
||||
// 4.6.1.1 Schemas for Entity Types and Complex Types
|
||||
private static OpenApiSchema VisitStructuredType(IEdmStructuredType structuredType, bool processBase)
|
||||
{
|
||||
if (processBase && structuredType.BaseType != null)
|
||||
{
|
||||
// A structured type with a base type is represented as a Schema Object
|
||||
// that contains the keyword allOf whose value is an array with two items:
|
||||
return new OpenApiSchema
|
||||
{
|
||||
AllOf = new List<OpenApiSchema>
|
||||
{
|
||||
// 1. a JSON Reference to the Schema Object of the base type
|
||||
new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, structuredType.BaseType.FullTypeName())
|
||||
},
|
||||
|
||||
// 2. a Schema Object describing the derived type
|
||||
VisitStructuredType(structuredType, false)
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// A structured type without a base type is represented as a Schema Object of type object
|
||||
return new OpenApiSchema
|
||||
{
|
||||
Title = (structuredType as IEdmSchemaElement).Name,
|
||||
|
||||
Type = "object",
|
||||
|
||||
// Each structural property and navigation property is represented
|
||||
// as a name/value pair of the standard OpenAPI properties object.
|
||||
Properties = VisitStructuredTypeProperties(structuredType),
|
||||
|
||||
// It optionally can contain the field description,
|
||||
// whose value is the value of the unqualified annotation Core.Description of the structured type.
|
||||
// However, ODL doesn't support the Core.Description on structure type.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 4.6.1.1 Properties
|
||||
private static IDictionary<string, OpenApiSchema> VisitStructuredTypeProperties(IEdmStructuredType structuredType)
|
||||
{
|
||||
// The name is the property name, the value is a Schema Object describing the allowed values of the property.
|
||||
IDictionary<string, OpenApiSchema> properties = new Dictionary<string, OpenApiSchema>();
|
||||
|
||||
// structure properties
|
||||
foreach (var property in structuredType.DeclaredStructuralProperties())
|
||||
{
|
||||
OpenApiSchema propertySchema = property.Type.CreateSchema();
|
||||
propertySchema.Default = property.DefaultValueString != null ? new OpenApiString(property.DefaultValueString) : null;
|
||||
properties.Add(property.Name, propertySchema);
|
||||
}
|
||||
|
||||
// navigation properties
|
||||
foreach (var property in structuredType.DeclaredNavigationProperties())
|
||||
{
|
||||
OpenApiSchema propertySchema = property.Type.CreateSchema();
|
||||
properties.Add(property.Name, propertySchema);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiServer"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiServersGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create the collection of <see cref="OpenApiServer"/> object.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The servers object.</returns>
|
||||
public static IList<OpenApiServer> CreateServers(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
// The value of servers is an array of Server Objects.
|
||||
// It contains one object with a field url.
|
||||
// The value of url is a string cotaining the service root URL without the trailing forward slash.
|
||||
return new List<OpenApiServer>
|
||||
{
|
||||
new OpenApiServer
|
||||
{
|
||||
Url = "http://localhost"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to create <see cref="OpenApiTag"/> by <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
internal static class OpenApiTagsGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Create the collection of <see cref="OpenApiTag"/> object.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <returns>The collection of <see cref="OpenApiTag"/> object.</returns>
|
||||
public static IList<OpenApiTag> CreateTags(this IEdmModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
// The value of tags is an array of Tag Objects.
|
||||
// For an OData service the natural groups are entity sets and singletons,
|
||||
// so the tags array contains one Tag Object per entity set and singleton in the entity container.
|
||||
IList<OpenApiTag> tags = new List<OpenApiTag>();
|
||||
if (model.EntityContainer != null)
|
||||
{
|
||||
foreach (IEdmEntityContainerElement element in model.EntityContainer.Elements)
|
||||
{
|
||||
switch (element.ContainerElementKind)
|
||||
{
|
||||
case EdmContainerElementKind.EntitySet: // entity set
|
||||
IEdmEntitySet entitySet = (IEdmEntitySet)element;
|
||||
tags.Add(new OpenApiTag
|
||||
{
|
||||
Name = entitySet.Name,
|
||||
Description = model.GetDescription(entitySet)
|
||||
});
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.Singleton: // singleton
|
||||
IEdmSingleton singleton = (IEdmSingleton)element;
|
||||
tags.Add(new OpenApiTag
|
||||
{
|
||||
Name = singleton.Name,
|
||||
Description = model.GetDescription(singleton)
|
||||
});
|
||||
break;
|
||||
|
||||
// The tags array can contain additional Tag Objects for other logical groups,
|
||||
// e.g. for action imports or function imports that are not associated with an entity set.
|
||||
case EdmContainerElementKind.ActionImport: // Action Import
|
||||
break;
|
||||
case EdmContainerElementKind.FunctionImport: // Function Import
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tags is optional.
|
||||
return tags.Any() ? tags : null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ using Microsoft.OpenApi.Any;
|
|||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Schema
|
||||
namespace Microsoft.OpenApi.OData.Generators
|
||||
{
|
||||
/// <summary>
|
||||
/// See https://github.com/oasis-tcs/odata-openapi/blob/master/examples/odata-definitions.json
|
||||
|
@ -285,13 +285,21 @@ namespace Microsoft.OpenApi.OData.Schema
|
|||
return schema;
|
||||
}
|
||||
|
||||
private static void InitErrors()
|
||||
public static void AppendODataErrors(this IDictionary<string, OpenApiSchema> schemas)
|
||||
{
|
||||
_errors = new Dictionary<string, OpenApiSchema>();
|
||||
if (schemas == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_errors.Add("odata.error", new OpenApiSchema
|
||||
// odata.error
|
||||
schemas.Add("odata.error", new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Required = new List<string>
|
||||
{
|
||||
"error"
|
||||
},
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
|
@ -304,31 +312,24 @@ namespace Microsoft.OpenApi.OData.Schema
|
|||
}
|
||||
});
|
||||
|
||||
_errors.Add("odata.error.main", new OpenApiSchema
|
||||
// odata.error.main
|
||||
schemas.Add("odata.error.main", new OpenApiSchema
|
||||
{
|
||||
Type = SchemaType.Object.GetMetadataName(),
|
||||
Type = "object",
|
||||
Required = new List<string>
|
||||
{
|
||||
"code", "message"
|
||||
},
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"code",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
"code", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"message",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
"message", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"target",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
"target", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"details",
|
||||
|
@ -352,31 +353,20 @@ namespace Microsoft.OpenApi.OData.Schema
|
|||
}
|
||||
});
|
||||
|
||||
_errors.Add("odata.error.detail", new OpenApiSchema
|
||||
// odata.error.detail
|
||||
schemas.Add("odata.error.detail", new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"code",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
"code", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"message",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
"message", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"target",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
"target", new OpenApiSchema { Type = "string" }
|
||||
}
|
||||
}
|
||||
});
|
|
@ -20,7 +20,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Schema\SchemaExtensions.cs" />
|
||||
<Compile Remove="EdmElementOpenApiElementExtensions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,406 +0,0 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmOpenApiComponentsGenerator.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Schema;
|
||||
|
||||
namespace Microsoft.OpenApi.OData
|
||||
{
|
||||
/// <summary>
|
||||
/// Visit Edm model to generate <see cref="OpenApiComponents"/>
|
||||
/// </summary>
|
||||
internal class OpenApiComponentsGenerator
|
||||
{
|
||||
private IEdmModel _model;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiComponentsGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
public OpenApiComponentsGenerator(IEdmModel model)
|
||||
{
|
||||
_model = model ?? throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate the <see cref="OpenApiComponents"/>
|
||||
/// </summary>
|
||||
/// <returns>the components object.</returns>
|
||||
public OpenApiComponents Generate()
|
||||
{
|
||||
// The value of components is a Components Object.
|
||||
// It holds maps of reusable schemas describing message bodies, operation parameters, and responses.
|
||||
return new OpenApiComponents
|
||||
{
|
||||
// The value of schemas is a map of Schema Objects.
|
||||
// Each entity type, complex type, enumeration type, and type definition directly
|
||||
// or indirectly used in the paths field is represented as a name/value pair of the schemas map.
|
||||
Schemas = VisitSchemas(),
|
||||
|
||||
// The value of parameters is a map of Parameter Objects.
|
||||
// It allows defining query options and headers that can be reused across operations of the service.
|
||||
Parameters = VisitParameters(),
|
||||
|
||||
// The value of responses is a map of Response Objects.
|
||||
// It allows defining responses that can be reused across operations of the service.
|
||||
Responses = VisitResponses()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Visit the Edm schema and generate the <see cref="OpenApiSchema"/>.
|
||||
/// The name of each pair is the namespace-qualified name of the type. It uses the namespace instead of the alias.
|
||||
/// The value of each pair is a <see cref="OpenApiSchema"/>.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private IDictionary<string, OpenApiSchema> VisitSchemas()
|
||||
{
|
||||
IDictionary<string, OpenApiSchema> schemas = new Dictionary<string, OpenApiSchema>();
|
||||
|
||||
foreach (var element in _model.SchemaElements)
|
||||
{
|
||||
switch (element.SchemaElementKind)
|
||||
{
|
||||
case EdmSchemaElementKind.TypeDefinition:
|
||||
{
|
||||
IEdmType reference = (IEdmType)element;
|
||||
schemas.Add(reference.FullTypeName(), VisitSchemaType(reference));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AppendODataErrors(schemas);
|
||||
|
||||
return schemas;
|
||||
}
|
||||
|
||||
private OpenApiSchema VisitSchemaType(IEdmType definition)
|
||||
{
|
||||
switch (definition.TypeKind)
|
||||
{
|
||||
case EdmTypeKind.Complex:
|
||||
case EdmTypeKind.Entity:
|
||||
return VisitStructuredType((IEdmStructuredType)definition, true);
|
||||
|
||||
case EdmTypeKind.Enum: // enum type
|
||||
return VisitEnumType((IEdmEnumType)definition);
|
||||
|
||||
case EdmTypeKind.TypeDefinition:
|
||||
return VisitTypeDefinitions((IEdmTypeDefinition)definition);
|
||||
|
||||
case EdmTypeKind.None:
|
||||
default:
|
||||
throw Error.NotSupported(String.Format("Not supported {0} type kind.", definition.TypeKind));
|
||||
}
|
||||
}
|
||||
|
||||
// 4.6.1.2 Schemas for Enumeration Types
|
||||
private OpenApiSchema VisitEnumType(IEdmEnumType enumType)
|
||||
{
|
||||
OpenApiSchema schema = new OpenApiSchema
|
||||
{
|
||||
// An enumeration type is represented as a Schema Object of type string
|
||||
Type = "string",
|
||||
|
||||
// containing the OpenAPI Specification enum keyword.
|
||||
Enum = new List<IOpenApiAny>(),
|
||||
|
||||
// It optionally can contain the field description,
|
||||
// whose value is the value of the unqualified annotation Core.Description of the enumeration type.
|
||||
Description = _model.GetDescription(enumType)
|
||||
};
|
||||
|
||||
// Enum value is an array that contains a string with the member name for each enumeration member.
|
||||
foreach (IEdmEnumMember member in enumType.Members)
|
||||
{
|
||||
schema.Enum.Add(new OpenApiString(member.Name));
|
||||
}
|
||||
|
||||
schema.Title = (enumType as IEdmSchemaElement)?.Name;
|
||||
return schema;
|
||||
}
|
||||
|
||||
// 4.6.1.3 Schemas for Type Definitions
|
||||
private OpenApiSchema VisitTypeDefinitions(IEdmTypeDefinition typeDefinition)
|
||||
{
|
||||
return typeDefinition?.UnderlyingType?.CreateSchema();
|
||||
}
|
||||
|
||||
// 4.6.1.1 Schemas for Entity Types and Complex Types
|
||||
private OpenApiSchema VisitStructuredType(IEdmStructuredType structuredType, bool processBase)
|
||||
{
|
||||
if (processBase && structuredType.BaseType != null)
|
||||
{
|
||||
// A structured type with a base type is represented as a Schema Object
|
||||
// that contains the keyword allOf whose value is an array with two items:
|
||||
return new OpenApiSchema
|
||||
{
|
||||
AllOf = new List<OpenApiSchema>
|
||||
{
|
||||
// 1. a JSON Reference to the Schema Object of the base type
|
||||
new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference(ReferenceType.Schema, structuredType.BaseType.FullTypeName())
|
||||
},
|
||||
|
||||
// 2. a Schema Object describing the derived type
|
||||
VisitStructuredType(structuredType, false)
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// A structured type without a base type is represented as a Schema Object of type object
|
||||
return new OpenApiSchema
|
||||
{
|
||||
Title = (structuredType as IEdmSchemaElement).Name,
|
||||
|
||||
Type = "object",
|
||||
|
||||
// Each structural property and navigation property is represented
|
||||
// as a name/value pair of the standard OpenAPI properties object.
|
||||
Properties = VisitStructuredTypeProperties(structuredType),
|
||||
|
||||
// It optionally can contain the field description,
|
||||
// whose value is the value of the unqualified annotation Core.Description of the structured type.
|
||||
// However, ODL doesn't support the Core.Description on structure type.
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 4.6.1.1 Properties
|
||||
private IDictionary<string, OpenApiSchema> VisitStructuredTypeProperties(IEdmStructuredType structuredType)
|
||||
{
|
||||
// The name is the property name, the value is a Schema Object describing the allowed values of the property.
|
||||
IDictionary<string, OpenApiSchema> properties = new Dictionary<string, OpenApiSchema>();
|
||||
|
||||
// structure properties
|
||||
foreach (var property in structuredType.DeclaredStructuralProperties())
|
||||
{
|
||||
OpenApiSchema propertySchema = property.Type.CreateSchema();
|
||||
propertySchema.Default = property.DefaultValueString != null ? new OpenApiString(property.DefaultValueString) : null;
|
||||
properties.Add(property.Name, propertySchema);
|
||||
}
|
||||
|
||||
// navigation properties
|
||||
foreach (var property in structuredType.DeclaredNavigationProperties())
|
||||
{
|
||||
OpenApiSchema propertySchema = property.Type.CreateSchema();
|
||||
properties.Add(property.Name, propertySchema);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private IDictionary<string, OpenApiParameter> VisitParameters()
|
||||
{
|
||||
return new Dictionary<string, OpenApiParameter>
|
||||
{
|
||||
{ "top", VisitTop() },
|
||||
{ "skip", VisitSkip() },
|
||||
{ "count", VisitCount() },
|
||||
{ "filter", VisitFilter() },
|
||||
{ "search", VisitSearch() },
|
||||
};
|
||||
}
|
||||
|
||||
private OpenApiParameter VisitTop()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$top",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Show only the first n items",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "integer",
|
||||
Minimum = 0,
|
||||
},
|
||||
Example = new OpenApiInteger(50)
|
||||
};
|
||||
}
|
||||
|
||||
private OpenApiParameter VisitSkip()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$skip",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Skip only the first n items",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "integer",
|
||||
Minimum = 0,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private OpenApiParameter VisitCount()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$count",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Include count of items",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "boolean"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private OpenApiParameter VisitFilter()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$filter",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Filter items by property values",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private OpenApiParameter VisitSearch()
|
||||
{
|
||||
return new OpenApiParameter
|
||||
{
|
||||
Name = "$search",
|
||||
In = ParameterLocation.Query,
|
||||
Description = "Search items by search phrases",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void AppendODataErrors(IDictionary<string, OpenApiSchema> schemas)
|
||||
{
|
||||
schemas.Add("odata.error", new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Required = new List<string>
|
||||
{
|
||||
"error"
|
||||
},
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"error",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/odata.error.main")
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
schemas.Add("odata.error.main", new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Required = new List<string>
|
||||
{
|
||||
"code", "message"
|
||||
},
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"code", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"message", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"target", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"details",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/odata.error.detail")
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"innererror",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Description = "The structure of this object is service-specific"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
schemas.Add("odata.error.detail", new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Required = new List<string>
|
||||
{
|
||||
"code", "message"
|
||||
},
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"code", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"message", new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
{
|
||||
"target", new OpenApiSchema { Type = "string" }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// It contains one name/value pair for the standard OData error response
|
||||
/// that is referenced from all operations of the service.
|
||||
/// </summary>
|
||||
/// <returns>Teh name/value pairs for the standard OData error response</returns>
|
||||
private IDictionary<string, OpenApiResponse> VisitResponses()
|
||||
{
|
||||
return new Dictionary<string, OpenApiResponse>
|
||||
{
|
||||
{ "error", VisitError() }
|
||||
};
|
||||
}
|
||||
|
||||
private OpenApiResponse VisitError()
|
||||
{
|
||||
return new OpenApiResponse
|
||||
{
|
||||
Description = "error",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Pointer = new OpenApiReference("#/components/schemas/odata.error")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmOpenApiDocumentGenerator.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData
|
||||
{
|
||||
/// <summary>
|
||||
/// A class used to covert Edm model to <see cref="OpenApiDocument"/>
|
||||
/// </summary>
|
||||
internal class OpenApiDocumentGenerator
|
||||
{
|
||||
private OpenApiComponentsGenerator _componentsGenerator;
|
||||
private OpenApiPathsGenerator _pathsGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// The Edm model.
|
||||
/// </summary>
|
||||
protected IEdmModel Model { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Open Api document external configuration action.
|
||||
/// </summary>
|
||||
private Action<OpenApiDocument> _configure;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
public OpenApiDocumentGenerator(IEdmModel model)
|
||||
: this(model, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EdmOpenApiDocumentGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
public OpenApiDocumentGenerator(IEdmModel model, Action<OpenApiDocument> configure)
|
||||
{
|
||||
Model = model ?? throw Error.ArgumentNull(nameof(model));
|
||||
_configure = configure;
|
||||
_componentsGenerator = new OpenApiComponentsGenerator(model);
|
||||
_pathsGenerator = new OpenApiPathsGenerator(model);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate Open Api document.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="OpenApiDocument"/> object.</returns>
|
||||
public OpenApiDocument Generate()
|
||||
{
|
||||
OpenApiDocument document = new OpenApiDocument
|
||||
{
|
||||
SpecVersion = new Version(3, 0, 0),
|
||||
|
||||
Info = CreateInfo(),
|
||||
|
||||
Servers = CreateServers(),
|
||||
|
||||
Paths = CreatePaths(),
|
||||
|
||||
Components = CreateComponents(),
|
||||
|
||||
Tags = CreateTags()
|
||||
};
|
||||
|
||||
_configure?.Invoke(document);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create <see cref="OpenApiInfo"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The info object.</returns>
|
||||
private OpenApiInfo CreateInfo()
|
||||
{
|
||||
// The value of info is an Info Object,
|
||||
// It contains the fields title and version, and optionally the field description.
|
||||
return new OpenApiInfo
|
||||
{
|
||||
// The value of title is the value of the unqualified annotation Core.Description
|
||||
// of the main schema or the entity container of the OData service.
|
||||
// If no Core.Description is present, a default title has to be provided as this is a required OpenAPI field.
|
||||
Title = "OData Service for namespace " + Model.DeclaredNamespaces.FirstOrDefault(),
|
||||
|
||||
// The value of version is the value of the annotation Core.SchemaVersion(see[OData - VocCore]) of the main schema.
|
||||
// If no Core.SchemaVersion is present, a default version has to be provided as this is a required OpenAPI field.
|
||||
Version = "1.0.0",
|
||||
|
||||
// The value of description is the value of the annotation Core.LongDescription
|
||||
// of the main schema or the entity container.
|
||||
// While this field is optional, it prominently appears in OpenAPI exploration tools,
|
||||
// so a default description should be provided if no Core.LongDescription annotation is present.
|
||||
// Description = "This OData service is located at " + Settings.BaseUri?.OriginalString
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the collection of <see cref="OpenApiServer"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The servers object.</returns>
|
||||
private IList<OpenApiServer> CreateServers()
|
||||
{
|
||||
// The value of servers is an array of Server Objects.
|
||||
// It contains one object with a field url.
|
||||
// The value of url is a string cotaining the service root URL without the trailing forward slash.
|
||||
return new List<OpenApiServer>
|
||||
{
|
||||
new OpenApiServer
|
||||
{
|
||||
Url = string.Empty
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the <see cref="OpenApiPaths"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The paths object.</returns>
|
||||
private OpenApiPaths CreatePaths()
|
||||
{
|
||||
return _pathsGenerator.Generate();
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// Create the <see cref="OpenApiComponents"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The components object.</returns>
|
||||
private OpenApiComponents CreateComponents()
|
||||
{
|
||||
return _componentsGenerator.Generate();
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// Create the collection of <see cref="OpenApiTag"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The tag object.</returns>
|
||||
private IList<OpenApiTag> CreateTags()
|
||||
{
|
||||
// The value of tags is an array of Tag Objects.
|
||||
// For an OData service the natural groups are entity sets and singletons,
|
||||
// so the tags array contains one Tag Object per entity set and singleton in the entity container.
|
||||
IList<OpenApiTag> tags = new List<OpenApiTag>();
|
||||
if (Model.EntityContainer != null)
|
||||
{
|
||||
foreach (IEdmEntityContainerElement element in Model.EntityContainer.Elements)
|
||||
{
|
||||
switch(element.ContainerElementKind)
|
||||
{
|
||||
case EdmContainerElementKind.EntitySet: // entity set
|
||||
IEdmEntitySet entitySet = (IEdmEntitySet)element;
|
||||
tags.Add(new OpenApiTag
|
||||
{
|
||||
Name = entitySet.Name,
|
||||
Description = Model.GetDescription(entitySet)
|
||||
});
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.Singleton: // singleton
|
||||
IEdmSingleton singleton = (IEdmSingleton)element;
|
||||
tags.Add(new OpenApiTag
|
||||
{
|
||||
Name = singleton.Name,
|
||||
Description = Model.GetDescription(singleton)
|
||||
});
|
||||
break;
|
||||
|
||||
// The tags array can contain additional Tag Objects for other logical groups,
|
||||
// e.g. for action imports or function imports that are not associated with an entity set.
|
||||
case EdmContainerElementKind.ActionImport: // Action Import
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.FunctionImport: // Function Import
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tags is optional.
|
||||
return tags.Any() ? tags : null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmEntitySetOpenApiElementGenerator.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData
|
||||
{
|
||||
internal class OpenApiPathItemGenerator
|
||||
{
|
||||
private IDictionary<IEdmTypeReference, IEdmOperation> _boundOperations;
|
||||
private IEdmModel _model;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiPathItemGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
public OpenApiPathItemGenerator(IEdmModel model)
|
||||
{
|
||||
_model = model;
|
||||
|
||||
_boundOperations = new Dictionary<IEdmTypeReference, IEdmOperation>();
|
||||
foreach (var edmOperation in model.SchemaElements.OfType<IEdmOperation>().Where(e => e.IsBound))
|
||||
{
|
||||
IEdmOperationParameter bindingParameter = edmOperation.Parameters.First();
|
||||
_boundOperations.Add(bindingParameter.Type, edmOperation);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Path items for Entity Sets.
|
||||
/// Each entity set is represented as a name/value pair
|
||||
/// whose name is the service-relative resource path of the entity set prepended with a forward slash,
|
||||
/// and whose value is a Path Item Object, see [OpenAPI].
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="entitySet">The Edm entity set.</param>
|
||||
/// <returns>The path items.</returns>
|
||||
public IDictionary<string, OpenApiPathItem> CreatePaths(IEdmEntitySet entitySet)
|
||||
{
|
||||
if (entitySet == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IDictionary<string, OpenApiPathItem> paths = new Dictionary<string, OpenApiPathItem>();
|
||||
|
||||
// entity set
|
||||
OpenApiPathItem pathItem = new OpenApiPathItem();
|
||||
|
||||
pathItem.AddOperation(OperationType.Get, entitySet.CreateGetOperationForEntitySet());
|
||||
|
||||
pathItem.AddOperation(OperationType.Post, entitySet.CreatePostOperationForEntitySet());
|
||||
|
||||
paths.Add("/" + entitySet.Name, pathItem);
|
||||
|
||||
// entity
|
||||
string entityPathName = entitySet.CreatePathNameForEntity();
|
||||
pathItem = new OpenApiPathItem();
|
||||
|
||||
pathItem.AddOperation(OperationType.Get, entitySet.CreateGetOperationForEntity());
|
||||
|
||||
pathItem.AddOperation(OperationType.Patch, entitySet.CreatePatchOperationForEntity());
|
||||
|
||||
pathItem.AddOperation(OperationType.Delete, entitySet.CreateDeleteOperationForEntity());
|
||||
|
||||
paths.Add(entityPathName, pathItem);
|
||||
|
||||
// bound operations
|
||||
IDictionary<string, OpenApiPathItem> operations = CreatePathItemsWithOperations(entitySet);
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
paths.Add(operation);
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
public IDictionary<string, OpenApiPathItem> CreatePaths(IEdmSingleton singleton)
|
||||
{
|
||||
IDictionary<string, OpenApiPathItem> paths = new Dictionary<string, OpenApiPathItem>();
|
||||
|
||||
// Singleton
|
||||
string entityPathName = singleton.CreatePathNameForSingleton();
|
||||
OpenApiPathItem pathItem = new OpenApiPathItem();
|
||||
pathItem.AddOperation(OperationType.Get, singleton.CreateGetOperationForSingleton());
|
||||
pathItem.AddOperation(OperationType.Patch, singleton.CreatePatchOperationForSingleton());
|
||||
paths.Add(entityPathName, pathItem);
|
||||
|
||||
IDictionary<string, OpenApiPathItem> operations = CreatePathItemsWithOperations(singleton);
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
paths.Add(operation);
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
private IDictionary<string, OpenApiPathItem> CreatePathItemsWithOperations(IEdmNavigationSource navigationSource)
|
||||
{
|
||||
IDictionary<string, OpenApiPathItem> operationPathItems = new Dictionary<string, OpenApiPathItem>();
|
||||
|
||||
IEnumerable<IEdmOperation> operations;
|
||||
IEdmEntitySet entitySet = navigationSource as IEdmEntitySet;
|
||||
// collection bound
|
||||
if (entitySet != null)
|
||||
{
|
||||
operations = FindOperations(navigationSource.EntityType(), collection: true);
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
OpenApiPathItem openApiOperation = operation.CreatePathItem();
|
||||
string operationPathName = operation.CreatePathItemName();
|
||||
operationPathItems.Add("/" + navigationSource.Name + operationPathName, openApiOperation);
|
||||
}
|
||||
}
|
||||
|
||||
// non-collection bound
|
||||
operations = FindOperations(navigationSource.EntityType(), collection: false);
|
||||
foreach (var operation in operations)
|
||||
{
|
||||
OpenApiPathItem openApiOperation = operation.CreatePathItem();
|
||||
string operationPathName = operation.CreatePathItemName();
|
||||
|
||||
string temp;
|
||||
if (entitySet != null)
|
||||
{
|
||||
temp = entitySet.CreatePathNameForEntity();
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = "/" + navigationSource.Name;
|
||||
}
|
||||
operationPathItems.Add(temp + operationPathName, openApiOperation);
|
||||
}
|
||||
|
||||
return operationPathItems;
|
||||
}
|
||||
|
||||
private IEnumerable<IEdmOperation> FindOperations(IEdmEntityType entityType, bool collection)
|
||||
{
|
||||
string fullTypeName = collection ? "Collection(" + entityType.FullName() + ")" :
|
||||
entityType.FullName();
|
||||
|
||||
foreach (var item in _boundOperations)
|
||||
{
|
||||
if (item.Key.FullName() == fullTypeName)
|
||||
{
|
||||
yield return item.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmOpenApiPathsGenerator.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
namespace Microsoft.OpenApi.OData
|
||||
{
|
||||
/// <summary>
|
||||
/// Visit Edm model to generate <see cref="OpenApiPaths"/>
|
||||
/// </summary>
|
||||
internal class OpenApiPathsGenerator
|
||||
{
|
||||
private OpenApiPathItemGenerator _nsGenerator;
|
||||
private IEdmModel _model;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiPathsGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
public OpenApiPathsGenerator(IEdmModel model)
|
||||
{
|
||||
_model = model;
|
||||
_nsGenerator = new OpenApiPathItemGenerator(model);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the <see cref="OpenApiPaths"/>
|
||||
/// </summary>
|
||||
/// <returns>the paths object.</returns>
|
||||
public OpenApiPaths Generate()
|
||||
{
|
||||
OpenApiPaths paths = new OpenApiPaths();
|
||||
if (_model.EntityContainer != null)
|
||||
{
|
||||
foreach (var element in _model.EntityContainer.Elements)
|
||||
{
|
||||
switch (element.ContainerElementKind)
|
||||
{
|
||||
case EdmContainerElementKind.EntitySet:
|
||||
IEdmEntitySet entitySet = element as IEdmEntitySet;
|
||||
if (entitySet != null)
|
||||
{
|
||||
foreach (var item in _nsGenerator.CreatePaths(entitySet))
|
||||
{
|
||||
paths.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.Singleton:
|
||||
IEdmSingleton singleton = element as IEdmSingleton;
|
||||
if (singleton != null)
|
||||
{
|
||||
foreach (var item in _nsGenerator.CreatePaths(singleton))
|
||||
{
|
||||
paths.Add(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.FunctionImport:
|
||||
IEdmFunctionImport functionImport = element as IEdmFunctionImport;
|
||||
if (functionImport != null)
|
||||
{
|
||||
var functionImportPathItem = functionImport.CreatePathItem();
|
||||
|
||||
paths.Add(functionImport.CreatePathItemName(), functionImportPathItem);
|
||||
}
|
||||
break;
|
||||
|
||||
case EdmContainerElementKind.ActionImport:
|
||||
IEdmActionImport actionImport = element as IEdmActionImport;
|
||||
if (actionImport != null)
|
||||
{
|
||||
var functionImportPathItem = actionImport.CreatePathItem();
|
||||
paths.Add(actionImport.CreatePathItemName(), functionImportPathItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue