add the initial Open API OData project and test
This commit is contained in:
parent
82f1d13fa4
commit
f8fecbd428
31
Microsoft.OpenApi.OData.sln
Normal file
31
Microsoft.OpenApi.OData.sln
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.OData.Reader", "src\Microsoft.OpenApi.OData.Reader\Microsoft.OpenApi.OData.Reader.csproj", "{FF3ACD93-19E0-486C-9C0F-FA1C2E7FC8C2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.OData.Reader.Tests", "test\Microsoft.OpenApi.OData.Reader.Tests\Microsoft.OpenApi.OData.Reader.Tests.csproj", "{90A98718-75EB-4E2B-A51E-66ACF66F15B4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{FF3ACD93-19E0-486C-9C0F-FA1C2E7FC8C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FF3ACD93-19E0-486C-9C0F-FA1C2E7FC8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FF3ACD93-19E0-486C-9C0F-FA1C2E7FC8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FF3ACD93-19E0-486C-9C0F-FA1C2E7FC8C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{90A98718-75EB-4E2B-A51E-66ACF66F15B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{90A98718-75EB-4E2B-A51E-66ACF66F15B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{90A98718-75EB-4E2B-A51E-66ACF66F15B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{90A98718-75EB-4E2B-A51E-66ACF66F15B4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9AE22713-F94E-45CA-81F4-0806CA195B69}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,15 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="IOpenApiElement.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an Open API document element.
|
||||
/// </summary>
|
||||
internal interface IOpenApiElement
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="IOpenApiExtensible.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an Extensible Open API element.
|
||||
/// </summary>
|
||||
internal interface IOpenApiExtensible : IOpenApiElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Specification extensions.
|
||||
/// </summary>
|
||||
IList<OpenApiExtension> Extensions { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="IOpenApiReferencable.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an Open API element is referencable.
|
||||
/// </summary>
|
||||
internal interface IOpenApiReferencable : IOpenApiElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference object.
|
||||
/// </summary>
|
||||
OpenApiReference Reference { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="IOpenApiWritable.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an Open API element is writable.
|
||||
/// </summary>
|
||||
internal interface IOpenApiWritable : IOpenApiElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Write Open API element.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
void Write(IOpenApiWriter writer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EnumerationExtensions.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 System.Reflection;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration type extension methods.
|
||||
/// </summary>
|
||||
public static class EnumerationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an attribute on an enum field value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the attribute to retrieve.</typeparam>
|
||||
/// <param name="enumVal">The enum value.</param>
|
||||
/// <returns>The attribute of type <typeparam name="T"> or null.</returns>
|
||||
public static T GetAttributeOfType<T>(this Enum enumVal) where T : Attribute
|
||||
{
|
||||
Type type = enumVal.GetType();
|
||||
MemberInfo memInfo = type.GetMember(enumVal.ToString()).First();
|
||||
IEnumerable<T> attributes = memInfo.GetCustomAttributes<T>(false);
|
||||
return attributes.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,301 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmElementOpenApiElementExtensions.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.Text;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for Edm Elements to Open Api Elements.
|
||||
/// </summary>
|
||||
internal static class EdmElementOpenApiElementExtensions
|
||||
{
|
||||
private static IDictionary<string, OpenApiResponse> Responses =
|
||||
new Dictionary<string, OpenApiResponse>
|
||||
{
|
||||
{ "default",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/responses/error")
|
||||
}
|
||||
},
|
||||
{ "204", new OpenApiResponse { Description = "Success"} },
|
||||
};
|
||||
|
||||
public static KeyValuePair<string, OpenApiResponse> GetResponse(this string statusCode)
|
||||
{
|
||||
return new KeyValuePair<string, OpenApiResponse>(statusCode, Responses[statusCode]);
|
||||
}
|
||||
|
||||
public static OpenApiSchema CreateSchema(this IEdmTypeReference reference)
|
||||
{
|
||||
if (reference == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (reference.TypeKind())
|
||||
{
|
||||
case EdmTypeKind.Collection:
|
||||
return new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
Items = CreateSchema(reference.AsCollection().ElementType())
|
||||
};
|
||||
|
||||
case EdmTypeKind.Complex:
|
||||
case EdmTypeKind.Entity:
|
||||
case EdmTypeKind.EntityReference:
|
||||
case EdmTypeKind.Enum:
|
||||
return new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + reference.Definition.FullTypeName())
|
||||
};
|
||||
|
||||
case EdmTypeKind.Primitive:
|
||||
OpenApiSchema schema;
|
||||
if (reference.IsInt64())
|
||||
{
|
||||
schema = new OpenApiSchema
|
||||
{
|
||||
OneOf = new List<OpenApiSchema>
|
||||
{
|
||||
new OpenApiSchema { Type = "integer" },
|
||||
new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
Format = "int64",
|
||||
Nullable = reference.IsNullable ? (bool?)true : null
|
||||
};
|
||||
}
|
||||
else if (reference.IsDouble())
|
||||
{
|
||||
schema = new OpenApiSchema
|
||||
{
|
||||
OneOf = new List<OpenApiSchema>
|
||||
{
|
||||
new OpenApiSchema { Type = "number" },
|
||||
new OpenApiSchema { Type = "string" }
|
||||
},
|
||||
Format = "double",
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
schema = new OpenApiSchema
|
||||
{
|
||||
Type = reference.AsPrimitive().GetOpenApiDataType().GetCommonName()
|
||||
};
|
||||
}
|
||||
schema.Nullable = reference.IsNullable ? (bool?)true : null;
|
||||
break;
|
||||
|
||||
case EdmTypeKind.TypeDefinition:
|
||||
case EdmTypeKind.None:
|
||||
default:
|
||||
throw Error.NotSupported("Not supported!");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static OpenApiPathItem CreatePathItem(this IEdmOperationImport operationImport)
|
||||
{
|
||||
if (operationImport.Operation.IsAction())
|
||||
{
|
||||
return ((IEdmActionImport)operationImport).CreatePathItem();
|
||||
}
|
||||
|
||||
return ((IEdmFunctionImport)operationImport).CreatePathItem();
|
||||
}
|
||||
|
||||
public static OpenApiPathItem CreatePathItem(this IEdmOperation operation)
|
||||
{
|
||||
if (operation.IsAction())
|
||||
{
|
||||
return ((IEdmAction)operation).CreatePathItem();
|
||||
}
|
||||
|
||||
return ((IEdmFunction)operation).CreatePathItem();
|
||||
}
|
||||
|
||||
public static OpenApiPathItem CreatePathItem(this IEdmActionImport actionImport)
|
||||
{
|
||||
return CreatePathItem(actionImport.Action);
|
||||
}
|
||||
|
||||
public static OpenApiPathItem CreatePathItem(this IEdmAction action)
|
||||
{
|
||||
return new OpenApiPathItem
|
||||
{
|
||||
Post = new OpenApiOperation
|
||||
{
|
||||
Summary = "Invoke action " + action.Name,
|
||||
Tags = CreateTags(action),
|
||||
Parameters = CreateParameters(action),
|
||||
Responses = CreateResponses(action)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static OpenApiPathItem CreatePathItem(this IEdmFunctionImport functionImport)
|
||||
{
|
||||
return CreatePathItem(functionImport.Function);
|
||||
}
|
||||
|
||||
public static OpenApiPathItem CreatePathItem(this IEdmFunction function)
|
||||
{
|
||||
return new OpenApiPathItem
|
||||
{
|
||||
Get = new OpenApiOperation
|
||||
{
|
||||
Summary = "Invoke function " + function.Name,
|
||||
Tags = CreateTags(function),
|
||||
Parameters = CreateParameters(function),
|
||||
Responses = CreateResponses(function)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static string CreatePathItemName(this IEdmActionImport actionImport)
|
||||
{
|
||||
return CreatePathItemName(actionImport.Action);
|
||||
}
|
||||
|
||||
public static string CreatePathItemName(this IEdmAction action)
|
||||
{
|
||||
return "/" + action.Name;
|
||||
}
|
||||
|
||||
public static string CreatePathItemName(this IEdmFunctionImport functionImport)
|
||||
{
|
||||
return CreatePathItemName(functionImport.Function);
|
||||
}
|
||||
|
||||
public static string CreatePathItemName(this IEdmFunction function)
|
||||
{
|
||||
StringBuilder functionName = new StringBuilder("/" + function.Name + "(");
|
||||
|
||||
functionName.Append(String.Join(",",
|
||||
function.Parameters.Select(p => p.Name + "=" + "{" + p.Name + "}")));
|
||||
functionName.Append(")");
|
||||
|
||||
return functionName.ToString();
|
||||
}
|
||||
|
||||
public static string CreatePathItemName(this IEdmOperationImport operationImport)
|
||||
{
|
||||
if (operationImport.Operation.IsAction())
|
||||
{
|
||||
return ((IEdmActionImport)operationImport).CreatePathItemName();
|
||||
}
|
||||
|
||||
return ((IEdmFunctionImport)operationImport).CreatePathItemName();
|
||||
}
|
||||
|
||||
public static string CreatePathItemName(this IEdmOperation operation)
|
||||
{
|
||||
if (operation.IsAction())
|
||||
{
|
||||
return ((IEdmAction)operation).CreatePathItemName();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
var pathExpression = operationImport.EntitySet as IEdmPathExpression;
|
||||
if (pathExpression != null)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
PathAsString(pathExpression.PathSegments)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IList<string> CreateTags(this IEdmOperation operation)
|
||||
{
|
||||
if (operation.EntitySetPath != null)
|
||||
{
|
||||
var pathExpression = operation.EntitySetPath as IEdmPathExpression;
|
||||
if (pathExpression != null)
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
PathAsString(pathExpression.PathSegments)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IList<OpenApiParameter> CreateParameters(this IEdmOperation operation)
|
||||
{
|
||||
IList<OpenApiParameter> parameters = new List<OpenApiParameter>();
|
||||
|
||||
foreach (IEdmOperationParameter edmParameter in operation.Parameters)
|
||||
{
|
||||
parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = edmParameter.Name,
|
||||
In = ParameterLocation.path,
|
||||
Required = true,
|
||||
Schema = edmParameter.Type.CreateSchema()
|
||||
});
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
internal static string PathAsString(IEnumerable<string> path)
|
||||
{
|
||||
return String.Join("/", path);
|
||||
}
|
||||
}
|
||||
}
|
46
src/Microsoft.OpenApi.OData.Reader/Edm/EdmHelper.cs
Normal file
46
src/Microsoft.OpenApi.OData.Reader/Edm/EdmHelper.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmHelper.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 System.Diagnostics;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal static class EdmHelper
|
||||
{
|
||||
public static string GetOpenApiTypeName(this IEdmTypeReference edmType)
|
||||
{
|
||||
Debug.Assert(edmType != null);
|
||||
|
||||
return edmType.Definition.GetOpenApiTypeName();
|
||||
}
|
||||
|
||||
public static string GetOpenApiTypeName(this IEdmType edmType)
|
||||
{
|
||||
Debug.Assert(edmType != null);
|
||||
|
||||
switch (edmType.TypeKind)
|
||||
{
|
||||
case EdmTypeKind.Collection:
|
||||
return OpenApiTypeKind.Array.GetDisplayName();
|
||||
|
||||
case EdmTypeKind.Complex:
|
||||
case EdmTypeKind.Entity:
|
||||
case EdmTypeKind.EntityReference:
|
||||
return OpenApiTypeKind.Object.GetDisplayName();
|
||||
|
||||
case EdmTypeKind.Enum:
|
||||
return OpenApiTypeKind.String.GetDisplayName();
|
||||
|
||||
case EdmTypeKind.Primitive:
|
||||
return ((IEdmPrimitiveType)(edmType)).GetOpenApiDataType().GetCommonName();
|
||||
|
||||
default:
|
||||
return OpenApiTypeKind.None.GetDisplayName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,511 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmNavigationSourceExtensions.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Entension methods for navigation source
|
||||
/// </summary>
|
||||
internal static class EdmNavigationSourceExtensions
|
||||
{
|
||||
public static OpenApiOperation CreateGetOperationForEntitySet(this IEdmEntitySet entitySet)
|
||||
{
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Get entities from " + entitySet.Name,
|
||||
Tags = new List<string>
|
||||
{
|
||||
entitySet.Name
|
||||
}
|
||||
};
|
||||
|
||||
operation.Parameters = new List<OpenApiParameter>
|
||||
{
|
||||
new OpenApiParameter
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/parameters/top")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/parameters/skip")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/parameters/search")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/parameters/filter")
|
||||
},
|
||||
new OpenApiParameter
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/parameters/count")
|
||||
},
|
||||
|
||||
CreateOrderByParameter(entitySet),
|
||||
|
||||
CreateSelectParameter(entitySet),
|
||||
|
||||
CreateExpandParameter(entitySet),
|
||||
};
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
{
|
||||
"200",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Description = "Retrieved entities",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Title = "Collection of " + entitySet.Name,
|
||||
Type = "object",
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"value",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
operation.Responses.Add("default".GetResponse());
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
public static OpenApiOperation CreatePostOperationForEntitySet(this IEdmEntitySet entitySet)
|
||||
{
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Add new entity to " + entitySet.Name,
|
||||
Tags = new List<string>
|
||||
{
|
||||
entitySet.Name
|
||||
},
|
||||
RequestBody = new OpenApiRequestBody
|
||||
{
|
||||
Required = true,
|
||||
Description = "New entity",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json", new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
{
|
||||
"201",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Description = "Created entity",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
operation.Responses.Add("default".GetResponse());
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
public static string CreatePathNameForEntity(this IEdmEntitySet entitySet)
|
||||
{
|
||||
string keyString;
|
||||
IList<IEdmStructuralProperty> keys = entitySet.EntityType().Key().ToList();
|
||||
if (keys.Count() == 1)
|
||||
{
|
||||
keyString = "{" + keys.First().Name + "}";
|
||||
}
|
||||
else
|
||||
{
|
||||
IList<string> temps = new List<string>();
|
||||
foreach (var keyProperty in entitySet.EntityType().Key())
|
||||
{
|
||||
temps.Add(keyProperty.Name + "={" + keyProperty.Name + "}");
|
||||
}
|
||||
keyString = String.Join(",", temps);
|
||||
}
|
||||
|
||||
return "/" + entitySet.Name + "('" + keyString + "')";
|
||||
}
|
||||
|
||||
public static string CreatePathNameForSingleton(this IEdmSingleton singleton)
|
||||
{
|
||||
return "/" + singleton.Name;
|
||||
}
|
||||
|
||||
public static OpenApiOperation CreateGetOperationForEntity(this IEdmEntitySet entitySet)
|
||||
{
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Get entity from " + entitySet.Name + " by key",
|
||||
Tags = new List<string>
|
||||
{
|
||||
entitySet.Name
|
||||
}
|
||||
};
|
||||
|
||||
operation.Parameters = CreateKeyParameters(entitySet.EntityType());
|
||||
|
||||
operation.Parameters.Add(CreateSelectParameter(entitySet));
|
||||
|
||||
operation.Parameters.Add(CreateExpandParameter(entitySet));
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
{
|
||||
"200",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Description = "Retrieved entity",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
operation.Responses.Add("default".GetResponse());
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
public static OpenApiOperation CreateGetOperationForSingleton(this IEdmSingleton singleton)
|
||||
{
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Get " + singleton.Name,
|
||||
Tags = new List<string>
|
||||
{
|
||||
singleton.Name
|
||||
}
|
||||
};
|
||||
|
||||
operation.Parameters = new List<OpenApiParameter>();
|
||||
operation.Parameters.Add(CreateSelectParameter(singleton));
|
||||
|
||||
operation.Parameters.Add(CreateExpandParameter(singleton));
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
{
|
||||
"200",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Description = "Retrieved entity",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + singleton.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
operation.Responses.Add("default".GetResponse());
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
public static OpenApiOperation CreatePatchOperationForEntity(this IEdmEntitySet entitySet)
|
||||
{
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Update entity in " + entitySet.Name,
|
||||
Tags = new List<string>
|
||||
{
|
||||
entitySet.Name
|
||||
}
|
||||
};
|
||||
|
||||
operation.Parameters = CreateKeyParameters(entitySet.EntityType());
|
||||
|
||||
operation.RequestBody = new OpenApiRequestBody
|
||||
{
|
||||
Required = true,
|
||||
Description = "New property values",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json", new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + entitySet.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
"204".GetResponse(),
|
||||
"default".GetResponse()
|
||||
};
|
||||
return operation;
|
||||
}
|
||||
|
||||
public static OpenApiOperation CreatePatchOperationForSingleton(this IEdmSingleton singleton)
|
||||
{
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Update " + singleton.Name,
|
||||
Tags = new List<string>
|
||||
{
|
||||
singleton.Name
|
||||
}
|
||||
};
|
||||
|
||||
operation.RequestBody = new OpenApiRequestBody
|
||||
{
|
||||
Required = true,
|
||||
Description = "New property values",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json", new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + singleton.EntityType().FullName())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
"204".GetResponse(),
|
||||
"default".GetResponse()
|
||||
};
|
||||
return operation;
|
||||
}
|
||||
|
||||
public static OpenApiOperation CreateDeleteOperationForEntity(this IEdmEntitySet entitySet)
|
||||
{
|
||||
OpenApiOperation operation = new OpenApiOperation
|
||||
{
|
||||
Summary = "Delete entity from " + entitySet.Name,
|
||||
Tags = new List<string>
|
||||
{
|
||||
entitySet.Name
|
||||
}
|
||||
};
|
||||
operation.Parameters = CreateKeyParameters(entitySet.EntityType());
|
||||
operation.Parameters.Add(new OpenApiParameter
|
||||
{
|
||||
Name = "If-Match",
|
||||
In = ParameterLocation.header,
|
||||
Description = "ETag",
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
});
|
||||
|
||||
operation.Responses = new OpenApiResponses
|
||||
{
|
||||
"204".GetResponse(),
|
||||
"default".GetResponse()
|
||||
};
|
||||
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<string> CreateOrderbyItems(this IEdmEntitySet entitySet)
|
||||
{
|
||||
IList<string> orderByItems = new List<string>();
|
||||
|
||||
IEdmEntityType entityType = entitySet.EntityType();
|
||||
|
||||
foreach (var property in entityType.StructuralProperties())
|
||||
{
|
||||
orderByItems.Add(property.Name);
|
||||
orderByItems.Add(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<string> CreateSelectItems(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<string> selectItems = new List<string>();
|
||||
|
||||
foreach (var property in entityType.StructuralProperties())
|
||||
{
|
||||
selectItems.Add(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<string> CreateExpandItems(this IEdmEntityType entityType)
|
||||
{
|
||||
IList<string> expandItems = new List<string>
|
||||
{
|
||||
"*"
|
||||
};
|
||||
|
||||
foreach (var property in entityType.NavigationProperties())
|
||||
{
|
||||
expandItems.Add(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,146 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal class EdmNavigationSourceGenerator : EdmOpenApiGenerator
|
||||
{
|
||||
public IDictionary<IEdmTypeReference, IEdmOperation> _boundOperations;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EdmNavigationSourceGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
public EdmNavigationSourceGenerator(IEdmModel model, OpenApiWriterSettings settings)
|
||||
: base(model, settings)
|
||||
{
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, OpenApiPathItem> CreatePaths(IEdmEntitySet entitySet)
|
||||
{
|
||||
IDictionary<string, OpenApiPathItem> paths = new Dictionary<string, OpenApiPathItem>();
|
||||
|
||||
// itself
|
||||
OpenApiPathItem pathItem = new OpenApiPathItem
|
||||
{
|
||||
Get = entitySet.CreateGetOperationForEntitySet(),
|
||||
|
||||
Post = entitySet.CreatePostOperationForEntitySet()
|
||||
};
|
||||
paths.Add("/" + entitySet.Name, pathItem);
|
||||
|
||||
// entity
|
||||
string entityPathName = entitySet.CreatePathNameForEntity();
|
||||
pathItem = new OpenApiPathItem
|
||||
{
|
||||
Get = entitySet.CreateGetOperationForEntity(),
|
||||
|
||||
Patch = entitySet.CreatePatchOperationForEntity(),
|
||||
|
||||
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
|
||||
{
|
||||
Get = singleton.CreateGetOperationForSingleton(),
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,375 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <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.Collections.Generic;
|
||||
using Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Visit Edm model to generate <see cref="OpenApiComponents"/>
|
||||
/// </summary>
|
||||
internal class EdmOpenApiComponentsGenerator : EdmOpenApiGenerator
|
||||
{
|
||||
private OpenApiComponents _components;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EdmOpenApiComponentsGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
public EdmOpenApiComponentsGenerator(IEdmModel model, OpenApiWriterSettings settings)
|
||||
: base(model, settings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the <see cref="OpenApiComponents"/>
|
||||
/// </summary>
|
||||
/// <returns>the components object.</returns>
|
||||
public OpenApiComponents Generate()
|
||||
{
|
||||
if (_components == null)
|
||||
{
|
||||
_components = new OpenApiComponents
|
||||
{
|
||||
Schemas = VisitSchemas(),
|
||||
Parameters = VisitParameters()
|
||||
};
|
||||
}
|
||||
|
||||
return _components;
|
||||
}
|
||||
|
||||
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:
|
||||
return VisitEnumType((IEdmEnumType)definition);
|
||||
|
||||
case EdmTypeKind.TypeDefinition:
|
||||
case EdmTypeKind.None:
|
||||
default:
|
||||
throw Error.NotSupported("Not support");
|
||||
}
|
||||
}
|
||||
|
||||
private OpenApiSchema VisitEnumType(IEdmEnumType enumType)
|
||||
{
|
||||
OpenApiSchema schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Enum = new List<string>()
|
||||
};
|
||||
|
||||
foreach (IEdmEnumMember member in enumType.Members)
|
||||
{
|
||||
schema.Enum.Add(member.Name);
|
||||
}
|
||||
|
||||
schema.Title = (enumType as IEdmSchemaElement).Name;
|
||||
return schema;
|
||||
}
|
||||
|
||||
private OpenApiSchema VisitStructuredType(IEdmStructuredType structuredType, bool processBase)
|
||||
{
|
||||
if (processBase && structuredType.BaseType != null)
|
||||
{
|
||||
return new OpenApiSchema
|
||||
{
|
||||
AllOf = new List<OpenApiSchema>
|
||||
{
|
||||
new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/" + structuredType.BaseType.FullTypeName())
|
||||
},
|
||||
|
||||
VisitStructuredType(structuredType, false)
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OpenApiSchema
|
||||
{
|
||||
Title = (structuredType as IEdmSchemaElement).Name,
|
||||
Type = "object",
|
||||
Properties = VisitStructuredTypeProperties(structuredType)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private IDictionary<string, OpenApiSchema> VisitStructuredTypeProperties(IEdmStructuredType structuredType)
|
||||
{
|
||||
IDictionary<string, OpenApiSchema> properties = new Dictionary<string, OpenApiSchema>();
|
||||
|
||||
foreach (var property in structuredType.DeclaredStructuralProperties())
|
||||
{
|
||||
OpenApiSchema propertySchema = VisitTypeReference(property.Type);
|
||||
properties.Add(property.Name, propertySchema);
|
||||
}
|
||||
|
||||
foreach (var property in structuredType.DeclaredNavigationProperties())
|
||||
{
|
||||
OpenApiSchema propertySchema = VisitTypeReference(property.Type);
|
||||
properties.Add(property.Name, propertySchema);
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private OpenApiSchema VisitTypeReference(IEdmTypeReference reference)
|
||||
{
|
||||
OpenApiSchema schema = new OpenApiSchema();
|
||||
|
||||
switch (reference.TypeKind())
|
||||
{
|
||||
case EdmTypeKind.Collection:
|
||||
schema.Type = "array";
|
||||
schema.Items = VisitTypeReference(reference.AsCollection().ElementType());
|
||||
break;
|
||||
|
||||
case EdmTypeKind.Complex:
|
||||
case EdmTypeKind.Entity:
|
||||
case EdmTypeKind.EntityReference:
|
||||
case EdmTypeKind.Enum:
|
||||
schema.Reference = new OpenApiReference("#/components/schemas/" + reference.Definition.FullTypeName());
|
||||
break;
|
||||
|
||||
case EdmTypeKind.Primitive:
|
||||
if (reference.IsInt64())
|
||||
{
|
||||
schema.OneOf = new List<OpenApiSchema>
|
||||
{
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "integer"
|
||||
},
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
};
|
||||
schema.Nullable = reference.IsNullable ? (bool?)true : null;
|
||||
schema.Format = "int64";
|
||||
}
|
||||
else
|
||||
{
|
||||
schema.Type = reference.AsPrimitive().GetOpenApiDataType().GetCommonName();
|
||||
schema.Nullable = reference.IsNullable ? (bool?)true : null;
|
||||
}
|
||||
break;
|
||||
|
||||
case EdmTypeKind.TypeDefinition:
|
||||
throw Error.NotSupported("Not supported!");
|
||||
|
||||
case EdmTypeKind.None:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return schema;
|
||||
}
|
||||
|
||||
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 OpenApiAny
|
||||
{
|
||||
{ "example", 50 } // TODO: it looks wrong here.
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
Reference = 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
|
||||
{
|
||||
Reference = 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" }
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// An class used to covert Edm model to <see cref="OpenApiDocument"/>
|
||||
/// </summary>
|
||||
internal class EdmOpenApiDocumentGenerator : EdmOpenApiGenerator
|
||||
{
|
||||
private OpenApiDocument _openApiDoc;
|
||||
private EdmOpenApiComponentsGenerator _componentsGenerator;
|
||||
private EdmOpenApiPathsGenerator _pathsGenerator;
|
||||
|
||||
/// <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 EdmOpenApiDocumentGenerator(IEdmModel model, OpenApiWriterSettings settings)
|
||||
: base(model, settings)
|
||||
{
|
||||
_componentsGenerator = new EdmOpenApiComponentsGenerator(model, settings);
|
||||
_pathsGenerator = new EdmOpenApiPathsGenerator(model, settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate Open Api document.
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="OpenApiDocument"/> object.</returns>
|
||||
public virtual OpenApiDocument Generate()
|
||||
{
|
||||
if (_openApiDoc == null)
|
||||
{
|
||||
_openApiDoc = new OpenApiDocument
|
||||
{
|
||||
Info = CreateInfo(),
|
||||
|
||||
Servers = CreateServers(),
|
||||
|
||||
Paths = CreatePaths(),
|
||||
|
||||
Components = CreateComponents(),
|
||||
|
||||
Security = CreateSecurity(),
|
||||
|
||||
Tags = CreateTags()
|
||||
};
|
||||
}
|
||||
|
||||
return _openApiDoc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create <see cref="OpenApiInfo"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The info object.</returns>
|
||||
private OpenApiInfo CreateInfo()
|
||||
{
|
||||
return new OpenApiInfo
|
||||
{
|
||||
Title = "OData Service for namespace " + Model.DeclaredNamespaces.FirstOrDefault(),
|
||||
Version = Settings.Version,
|
||||
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()
|
||||
{
|
||||
return new List<OpenApiServer>
|
||||
{
|
||||
new OpenApiServer
|
||||
{
|
||||
Url = Settings.BaseUri
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <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="OpenApiSecurity"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The security object.</returns>
|
||||
private IList<OpenApiSecurity> CreateSecurity()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// Create the collection of <see cref="OpenApiTag"/> object.
|
||||
/// </summary>
|
||||
/// <returns>The tag object.</returns>
|
||||
private IList<OpenApiTag> CreateTags()
|
||||
{
|
||||
IList<OpenApiTag> tags = new List<OpenApiTag>();
|
||||
if (Model.EntityContainer != null)
|
||||
{
|
||||
foreach (IEdmEntitySet entitySet in Model.EntityContainer.EntitySets())
|
||||
{
|
||||
tags.Add(new OpenApiTag
|
||||
{
|
||||
Name = entitySet.Name
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmOpenApiGenerator.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for Edm to Open Api generator.
|
||||
/// </summary>
|
||||
internal abstract class EdmOpenApiGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// The Edm model.
|
||||
/// </summary>
|
||||
protected IEdmModel Model { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Open Api writer setting.
|
||||
/// </summary>
|
||||
public OpenApiWriterSettings Settings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EdmOpenApiGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
protected EdmOpenApiGenerator(IEdmModel model, OpenApiWriterSettings settings)
|
||||
{
|
||||
Model = model ?? throw Error.ArgumentNull(nameof(model));
|
||||
Settings = settings ?? throw Error.ArgumentNull(nameof(settings));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Visit Edm model to generate <see cref="OpenApiPaths"/>
|
||||
/// </summary>
|
||||
internal class EdmOpenApiPathsGenerator : EdmOpenApiGenerator
|
||||
{
|
||||
private OpenApiPaths _paths;
|
||||
private EdmNavigationSourceGenerator _nsGenerator;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EdmOpenApiPathsGenerator" /> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The Open Api writer settings.</param>
|
||||
public EdmOpenApiPathsGenerator(IEdmModel model, OpenApiWriterSettings settings)
|
||||
: base(model, settings)
|
||||
{
|
||||
_nsGenerator = new EdmNavigationSourceGenerator(model, settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the <see cref="OpenApiPaths"/>
|
||||
/// </summary>
|
||||
/// <returns>the paths object.</returns>
|
||||
public OpenApiPaths Generate()
|
||||
{
|
||||
if (_paths == null)
|
||||
{
|
||||
_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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmPrimitiveExtensions.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 Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Edm primitive type extension methods.
|
||||
/// </summary>
|
||||
internal static class EdmPrimitiveExtensions
|
||||
{
|
||||
private static readonly Dictionary<EdmPrimitiveTypeKind, OpenApiDataTypeKind> _builtInTypesMapping =
|
||||
new Dictionary<EdmPrimitiveTypeKind, OpenApiDataTypeKind>
|
||||
{
|
||||
{ EdmPrimitiveTypeKind.None, OpenApiDataTypeKind.None },
|
||||
{ EdmPrimitiveTypeKind.Binary, OpenApiDataTypeKind.Binary },
|
||||
{ EdmPrimitiveTypeKind.Boolean, OpenApiDataTypeKind.Boolean },
|
||||
{ EdmPrimitiveTypeKind.Byte, OpenApiDataTypeKind.Byte },
|
||||
{ EdmPrimitiveTypeKind.DateTimeOffset, OpenApiDataTypeKind.DateTime }, // TODO:
|
||||
{ EdmPrimitiveTypeKind.Decimal, OpenApiDataTypeKind.Double },
|
||||
{ EdmPrimitiveTypeKind.Double, OpenApiDataTypeKind.Double },
|
||||
{ EdmPrimitiveTypeKind.Guid, OpenApiDataTypeKind.String }, // TODO:
|
||||
{ EdmPrimitiveTypeKind.Int16, OpenApiDataTypeKind.Integer },
|
||||
{ EdmPrimitiveTypeKind.Int32, OpenApiDataTypeKind.Integer },
|
||||
{ EdmPrimitiveTypeKind.Int64, OpenApiDataTypeKind.Long },
|
||||
{ EdmPrimitiveTypeKind.SByte, OpenApiDataTypeKind.Integer },
|
||||
{ EdmPrimitiveTypeKind.Single, OpenApiDataTypeKind.Float },
|
||||
{ EdmPrimitiveTypeKind.String, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.Stream, OpenApiDataTypeKind.String }, // TODO:
|
||||
{ EdmPrimitiveTypeKind.Duration, OpenApiDataTypeKind.DateTime },
|
||||
{ EdmPrimitiveTypeKind.Date, OpenApiDataTypeKind.DateTime },
|
||||
{ EdmPrimitiveTypeKind.TimeOfDay, OpenApiDataTypeKind.DateTime },
|
||||
|
||||
{ EdmPrimitiveTypeKind.Geography, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeographyPoint, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeographyLineString, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeographyPolygon, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeographyCollection, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeographyMultiPolygon, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeographyMultiLineString, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeographyMultiPoint, OpenApiDataTypeKind.String },
|
||||
|
||||
{ EdmPrimitiveTypeKind.Geometry, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeometryPoint, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeometryLineString, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeometryPolygon, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeometryCollection, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeometryMultiPolygon, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeometryMultiLineString, OpenApiDataTypeKind.String },
|
||||
{ EdmPrimitiveTypeKind.GeometryMultiPoint, OpenApiDataTypeKind.String },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Get Open Api Data type kind.
|
||||
/// </summary>
|
||||
/// <param name="primitiveType">The primitive type.</param>
|
||||
/// <returns>The Open Api Data type kind.</returns>
|
||||
public static OpenApiDataTypeKind GetOpenApiDataType(this IEdmPrimitiveTypeReference primitiveType)
|
||||
{
|
||||
if (primitiveType == null)
|
||||
{
|
||||
return OpenApiDataTypeKind.None;
|
||||
}
|
||||
|
||||
return GetOpenApiDataType(primitiveType.PrimitiveKind());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Open Api Data type kind.
|
||||
/// </summary>
|
||||
/// <param name="primitiveType">The primitive type.</param>
|
||||
/// <returns>The Open Api Data type kind.</returns>
|
||||
public static OpenApiDataTypeKind GetOpenApiDataType(this IEdmPrimitiveType typeReference)
|
||||
{
|
||||
if (typeReference == null)
|
||||
{
|
||||
return OpenApiDataTypeKind.None;
|
||||
}
|
||||
|
||||
return GetOpenApiDataType(typeReference.PrimitiveKind);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Open Api Data type kind.
|
||||
/// </summary>
|
||||
/// <param name="primitiveType">The primitive type kind.</param>
|
||||
/// <returns>The Open Api Data type kind.</returns>
|
||||
private static OpenApiDataTypeKind GetOpenApiDataType(this EdmPrimitiveTypeKind primitiveKind)
|
||||
{
|
||||
return _builtInTypesMapping[primitiveKind];
|
||||
}
|
||||
}
|
||||
}
|
224
src/Microsoft.OpenApi.OData.Reader/Edm/EdmValueWriter.cs
Normal file
224
src/Microsoft.OpenApi.OData.Reader/Edm/EdmValueWriter.cs
Normal file
|
@ -0,0 +1,224 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmValueWriter.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.Diagnostics;
|
||||
using System.Xml;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains methods to convert primitive values to their string representation.
|
||||
/// </summary>
|
||||
internal static class EdmValueWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Characters used in string representations of hexadecimal values
|
||||
/// </summary>
|
||||
private static char[] Hex = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
/// <summary>
|
||||
/// Converts the IEdmPrimitiveValue to a String.
|
||||
/// </summary>
|
||||
/// <param name="v">The value to convert.</param>
|
||||
/// <returns>A string representation of the IEdmPrimitiveValue.</returns>
|
||||
internal static string PrimitiveValueAsXml(IEdmPrimitiveValue v)
|
||||
{
|
||||
switch (v.ValueKind)
|
||||
{
|
||||
case EdmValueKind.Boolean:
|
||||
return BooleanAsXml(((IEdmBooleanValue)v).Value);
|
||||
case EdmValueKind.Integer:
|
||||
return LongAsXml(((IEdmIntegerValue)v).Value);
|
||||
case EdmValueKind.Floating:
|
||||
return FloatAsXml(((IEdmFloatingValue)v).Value);
|
||||
case EdmValueKind.Guid:
|
||||
return GuidAsXml(((IEdmGuidValue)v).Value);
|
||||
case EdmValueKind.Binary:
|
||||
return BinaryAsXml(((IEdmBinaryValue)v).Value);
|
||||
case EdmValueKind.Decimal:
|
||||
return DecimalAsXml(((IEdmDecimalValue)v).Value);
|
||||
case EdmValueKind.String:
|
||||
return StringAsXml(((IEdmStringValue)v).Value);
|
||||
case EdmValueKind.DateTimeOffset:
|
||||
return DateTimeOffsetAsXml(((IEdmDateTimeOffsetValue)v).Value);
|
||||
case EdmValueKind.Date:
|
||||
return DateAsXml(((IEdmDateValue)v).Value);
|
||||
case EdmValueKind.Duration:
|
||||
return DurationAsXml(((IEdmDurationValue)v).Value);
|
||||
case EdmValueKind.TimeOfDay:
|
||||
return TimeOfDayAsXml(((IEdmTimeOfDayValue)v).Value);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the String to a String.
|
||||
/// </summary>
|
||||
/// <param name="s">The value to convert.</param>
|
||||
/// <returns>The value to convert.</returns>
|
||||
internal static string StringAsXml(string s)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Byte[] to a String.
|
||||
/// </summary>
|
||||
/// <param name="binary">The value to convert.</param>
|
||||
/// <returns>A string representation of the Byte[].</returns>
|
||||
internal static string BinaryAsXml(byte[] binary)
|
||||
{
|
||||
var chars = new char[binary.Length * 2];
|
||||
for (int i = 0; i < binary.Length; ++i)
|
||||
{
|
||||
chars[i << 1] = Hex[binary[i] >> 4];
|
||||
chars[i << 1 | 1] = Hex[binary[i] & 0x0F];
|
||||
}
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Boolean to a String.
|
||||
/// </summary>
|
||||
/// <param name="b">The value to convert.</param>
|
||||
/// <returns>A string representation of the Boolean, that is, "true" or "false".</returns>
|
||||
internal static string BooleanAsXml(bool b)
|
||||
{
|
||||
return XmlConvert.ToString(b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Boolean? to a String.
|
||||
/// </summary>
|
||||
/// <param name="b">The value to convert.</param>
|
||||
/// <returns>A string representation of the Boolean, that is, "true" or "false".</returns>
|
||||
internal static string BooleanAsXml(bool? b)
|
||||
{
|
||||
Debug.Assert(b.HasValue, "Serialized nullable boolean must have value.");
|
||||
return BooleanAsXml(b.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Int32 to a String.
|
||||
/// </summary>
|
||||
/// <param name="i">The value to convert</param>
|
||||
/// <returns>A string representation of the Int32.</returns>
|
||||
internal static string IntAsXml(int i)
|
||||
{
|
||||
return XmlConvert.ToString(i);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Int32? to a String.
|
||||
/// </summary>
|
||||
/// <param name="i">The value to convert</param>
|
||||
/// <returns>A string representation of the Int32.</returns>
|
||||
internal static string IntAsXml(int? i)
|
||||
{
|
||||
Debug.Assert(i.HasValue, "Serialized nullable integer must have value.");
|
||||
return IntAsXml(i.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Int64 to a String.
|
||||
/// </summary>
|
||||
/// <param name="l">The value to convert.</param>
|
||||
/// <returns>A string representation of the Int64.</returns>
|
||||
internal static string LongAsXml(long l)
|
||||
{
|
||||
return XmlConvert.ToString(l);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Double to a String.
|
||||
/// </summary>
|
||||
/// <param name="f">The value to convert.</param>
|
||||
/// <returns>A string representation of the Double.</returns>
|
||||
internal static string FloatAsXml(double f)
|
||||
{
|
||||
return XmlConvert.ToString(f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Decimal to a String.
|
||||
/// </summary>
|
||||
/// <param name="d">The value to convert.</param>
|
||||
/// <returns>A string representation of the Decimal.</returns>
|
||||
internal static string DecimalAsXml(decimal d)
|
||||
{
|
||||
return XmlConvert.ToString(d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the TimeSpan to a String.
|
||||
/// </summary>
|
||||
/// <param name="d">The value to convert.</param>
|
||||
/// <returns>A string representation of the TimeSpan.</returns>
|
||||
internal static string DurationAsXml(TimeSpan d)
|
||||
{
|
||||
return XmlConvert.ToString(d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the DateTimeOffset to a String.
|
||||
/// </summary>
|
||||
/// <param name="d">The System.DateTimeOffset to be converted.</param>
|
||||
/// <returns>A System.String representation of the supplied System.DateTimeOffset.</returns>
|
||||
internal static string DateTimeOffsetAsXml(DateTimeOffset d)
|
||||
{
|
||||
var value = XmlConvert.ToString(d);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Date to a String.
|
||||
/// </summary>
|
||||
/// <param name="d">The <see cref="Microsoft.OData.Edm.Date"/> to be converted</param>
|
||||
/// <returns>A System.String representation of the supplied <see cref="Microsoft.OData.Edm.Date"/>.</returns>
|
||||
internal static string DateAsXml(Date d)
|
||||
{
|
||||
var value = d.ToString();
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the TimeOfDay to a String.
|
||||
/// </summary>
|
||||
/// <param name="time">The <see cref="Microsoft.OData.Edm.TimeOfDay"/> to be converted</param>
|
||||
/// <returns>A System.String representation of the supplied <see cref="Microsoft.OData.Edm.TimeOfDay"/>.</returns>
|
||||
internal static string TimeOfDayAsXml(TimeOfDay time)
|
||||
{
|
||||
var value = time.ToString();
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Guid to a String.
|
||||
/// </summary>
|
||||
/// <param name="g">The value to convert.</param>
|
||||
/// <returns>A string representation of the Guid.</returns>
|
||||
internal static string GuidAsXml(Guid g)
|
||||
{
|
||||
return XmlConvert.ToString(g);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the Uri to a String.
|
||||
/// </summary>
|
||||
/// <param name="uri">The value to convert.</param>
|
||||
/// <returns>A string representation of the Uri.</returns>
|
||||
internal static string UriAsXml(Uri uri)
|
||||
{
|
||||
Debug.Assert(uri != null, "uri != null");
|
||||
return uri.OriginalString;
|
||||
}
|
||||
}
|
||||
}
|
113
src/Microsoft.OpenApi.OData.Reader/EdmModelOpenApiExtensions.cs
Normal file
113
src/Microsoft.OpenApi.OData.Reader/EdmModelOpenApiExtensions.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmModelOpenApiExtensions.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.OData.Edm;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to write Entity Data Model (EDM) to Open API.
|
||||
/// </summary>
|
||||
public static class EdmModelOpenApiExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Outputs Edm model to an Open API artifact to the give stream.
|
||||
/// </summary>
|
||||
/// <param name="model">Edm model to be written.</param>
|
||||
/// <param name="stream">The output stream.</param>
|
||||
/// <param name="target">The Open API target.</param>
|
||||
/// <param name="settings">Settings for the generated Open API.</param>
|
||||
public static void WriteOpenApi(this IEdmModel model, Stream stream, OpenApiTarget target, OpenApiWriterSettings settings = null)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(stream));
|
||||
}
|
||||
|
||||
IOpenApiWriter openApiWriter = BuildWriter(stream, target);
|
||||
model.WriteOpenApi(openApiWriter, settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs Edm model to an Open API artifact to the give text writer.
|
||||
/// </summary>
|
||||
/// <param name="model">Edm model to be written.</param>
|
||||
/// <param name="writer">The output text writer.</param>
|
||||
/// <param name="target">The Open API target.</param>
|
||||
/// <param name="settings">Settings for the generated Open API.</param>
|
||||
public static void WriteOpenApi(this IEdmModel model, TextWriter writer, OpenApiTarget target, OpenApiWriterSettings settings = null)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(model));
|
||||
}
|
||||
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(writer));
|
||||
}
|
||||
|
||||
IOpenApiWriter openApiWriter = BuildWriter(writer, target);
|
||||
model.WriteOpenApi(openApiWriter, settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Outputs an Open API artifact to the provided Open Api writer.
|
||||
/// </summary>
|
||||
/// <param name="model">Model to be written.</param>
|
||||
/// <param name="writer">The generated Open API writer <see cref="IOpenApiWriter"/>.</param>
|
||||
/// <param name="settings">Settings for the generated Open API.</param>
|
||||
public static void WriteOpenApi(this IEdmModel model, IOpenApiWriter writer, OpenApiWriterSettings settings = null)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
throw Error.ArgumentNull("model");
|
||||
}
|
||||
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (settings == null)
|
||||
{
|
||||
settings = new OpenApiWriterSettings();
|
||||
}
|
||||
|
||||
EdmOpenApiDocumentGenerator converter = new EdmOpenApiDocumentGenerator(model, settings);
|
||||
OpenApiDocument doc = converter.Generate();
|
||||
doc.Write(writer);
|
||||
}
|
||||
|
||||
private static IOpenApiWriter BuildWriter(Stream stream, OpenApiTarget target)
|
||||
{
|
||||
StreamWriter writer = new StreamWriter(stream)
|
||||
{
|
||||
NewLine = "\n"
|
||||
};
|
||||
|
||||
return BuildWriter(writer, target);
|
||||
}
|
||||
|
||||
private static IOpenApiWriter BuildWriter(TextWriter writer, OpenApiTarget target)
|
||||
{
|
||||
if (target == OpenApiTarget.Json)
|
||||
{
|
||||
return new OpenApiJsonWriter(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OpenApiYamlWriter(writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
src/Microsoft.OpenApi.OData.Reader/Error.cs
Normal file
95
src/Microsoft.OpenApi.OData.Reader/Error.cs
Normal file
|
@ -0,0 +1,95 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="Error.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.Globalization;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class for creating and unwrapping <see cref="Exception"/> instances.
|
||||
/// </summary>
|
||||
internal static class Error
|
||||
{
|
||||
/// <summary>
|
||||
/// Formats the specified resource string using <see cref="M:CultureInfo.CurrentCulture"/>.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="args">An object array that contains zero or more objects to format.</param>
|
||||
/// <returns>The formatted string.</returns>
|
||||
internal static string Format(string format, params object[] args)
|
||||
{
|
||||
return String.Format(CultureInfo.CurrentCulture, format, args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ArgumentException"/> with the provided properties.
|
||||
/// </summary>
|
||||
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
|
||||
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
|
||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
||||
internal static ArgumentException Argument(string messageFormat, params object[] messageArgs)
|
||||
{
|
||||
return new ArgumentException(Format(messageFormat, messageArgs));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ArgumentException"/> with the provided properties.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
|
||||
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
|
||||
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
|
||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
||||
internal static ArgumentException Argument(string parameterName, string messageFormat, params object[] messageArgs)
|
||||
{
|
||||
return new ArgumentException(Format(messageFormat, messageArgs), parameterName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
|
||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
||||
internal static ArgumentNullException ArgumentNull(string parameterName)
|
||||
{
|
||||
return new ArgumentNullException(parameterName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ArgumentNullException"/> with the provided properties.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
|
||||
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
|
||||
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
|
||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
||||
internal static ArgumentNullException ArgumentNull(string parameterName, string messageFormat, params object[] messageArgs)
|
||||
{
|
||||
return new ArgumentNullException(parameterName, Format(messageFormat, messageArgs));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="ArgumentException"/> with a default message.
|
||||
/// </summary>
|
||||
/// <param name="parameterName">The name of the parameter that caused the current exception.</param>
|
||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
||||
internal static ArgumentException ArgumentNullOrEmpty(string parameterName)
|
||||
{
|
||||
return Error.Argument(parameterName, SRResource.ArgumentNullOrEmpty, parameterName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="NotSupportedException"/>.
|
||||
/// </summary>
|
||||
/// <param name="messageFormat">A composite format string explaining the reason for the exception.</param>
|
||||
/// <param name="messageArgs">An object array that contains zero or more objects to format.</param>
|
||||
/// <returns>The logged <see cref="Exception"/>.</returns>
|
||||
internal static NotSupportedException NotSupported(string messageFormat, params object[] messageArgs)
|
||||
{
|
||||
return new NotSupportedException(Format(messageFormat, messageArgs));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyName>Microsoft.OpenAPI.OData.Reader</AssemblyName>
|
||||
<RootNamespace>Microsoft.OpenAPI.OData.Reader</RootNamespace>
|
||||
<TargetFrameworks>net46; netstandard2.0</TargetFrameworks>
|
||||
<Company>Microsoft</Company>
|
||||
<Product>Microsoft.OpenAPI.OData.Reader</Product>
|
||||
<PackageId>Microsoft.OpenAPI.OData.Reader</PackageId>
|
||||
<Version>0.1.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.OData.Edm" Version="7.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\SRResource.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>SRResource.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\SRResource.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>SRResource.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
23
src/Microsoft.OpenApi.OData.Reader/ODataOpenApiConvert.cs
Normal file
23
src/Microsoft.OpenApi.OData.Reader/ODataOpenApiConvert.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="ODataOpenApiConvert.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal static class ODataOpenApiConvert
|
||||
{
|
||||
public static OpenApiDocument ConvertTo(this IEdmModel model)
|
||||
{
|
||||
return model.ConvertTo(new OpenApiWriterSettings());
|
||||
}
|
||||
|
||||
public static OpenApiDocument ConvertTo(this IEdmModel model, OpenApiWriterSettings settings)
|
||||
{
|
||||
return new EdmOpenApiDocumentGenerator(model, settings).Generate();
|
||||
}
|
||||
}
|
||||
}
|
50
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiAny.cs
Normal file
50
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiAny.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiAny.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Any object.
|
||||
/// TODO: it looks wrong
|
||||
/// </summary>
|
||||
internal class OpenApiAny : Dictionary<string, object>, IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
foreach (var item in this)
|
||||
{
|
||||
writer.WritePropertyName(item.Key);
|
||||
|
||||
IOpenApiWritable writerElement = item.Value as IOpenApiWritable;
|
||||
if (writerElement != null)
|
||||
{
|
||||
writerElement.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteValue(item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiCallback.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback Object: A map of possible out-of band callbacks related to the parent operation.
|
||||
/// The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.
|
||||
/// Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses.
|
||||
/// </summary>
|
||||
internal class OpenApiCallback : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
114
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiComponents.cs
Normal file
114
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiComponents.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiComponents.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Components Object.
|
||||
/// </summary>
|
||||
internal class OpenApiComponents : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// Schemas
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiSchema> Schemas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Responses
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiResponse> Responses { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parameters
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiParameter> Parameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Examples
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiExample> Examples { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// RequestBodies
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiRequestBody> RequestBodies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Headers
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiHeader> Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// SecuritySchemes
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiSecuritySchema> SecuritySchemes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Links
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiLink> Links { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Callbacks
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiCallback> Callbacks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write components object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// schemas
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocSchemas, Schemas);
|
||||
|
||||
// responses
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocResponses, Responses);
|
||||
|
||||
// parameters
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocParameters, Parameters);
|
||||
|
||||
// examples
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocExamples, Examples);
|
||||
|
||||
// requestBodies
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocRequestBodies, RequestBodies);
|
||||
|
||||
// headers
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocHeaders, Headers);
|
||||
|
||||
// securitySchemes
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocSecuritySchemes, SecuritySchemes);
|
||||
|
||||
// links
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocLinks, Links);
|
||||
|
||||
// callbacks
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocCallbacks, Callbacks);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
199
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiConstants.cs
Normal file
199
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiConstants.cs
Normal file
|
@ -0,0 +1,199 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiConstants.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal static class OpenApiConstants
|
||||
{
|
||||
public const string OpenApiDocOpenApi = "openapi";
|
||||
|
||||
public const string OpenApiDocInfo = "info";
|
||||
|
||||
public const string OpenApiDocTitle = "title";
|
||||
|
||||
public const string OpenApiDocType = "type";
|
||||
|
||||
public const string OpenApiDocFormat = "format";
|
||||
|
||||
public const string OpenApiDocVersion = "version";
|
||||
|
||||
public const string OpenApiDocContact = "contact";
|
||||
|
||||
public const string OpenApiDocLicense = "license";
|
||||
|
||||
public const string OpenApiDocTermsOfService = "termsOfService";
|
||||
|
||||
public const string OpenApiDocServers = "servers";
|
||||
|
||||
public const string OpenApiDocServer = "server";
|
||||
|
||||
public const string OpenApiDocPaths = "paths";
|
||||
|
||||
public const string OpenApiDocComponents = "components";
|
||||
|
||||
public const string OpenApiDocSecurity = "security";
|
||||
|
||||
public const string OpenApiDocTags = "tags";
|
||||
|
||||
public const string OpenApiDocExternalDocs = "externalDocs";
|
||||
|
||||
public const string OpenApiDocOperationRef = "operationRef";
|
||||
|
||||
public const string OpenApiDocOperationId = "operationId";
|
||||
|
||||
public const string OpenApiDocParameters = "parameters";
|
||||
|
||||
public const string OpenApiDocRequestBody = "requestBody";
|
||||
|
||||
public const string OpenApiDocExtensionFieldNamePrefix = "x-";
|
||||
|
||||
public const string OpenApiDocName = "name";
|
||||
|
||||
public const string OpenApiDocIn = "in";
|
||||
|
||||
public const string OpenApiDocSummary = "summary";
|
||||
|
||||
public const string OpenApiDocVariables = "variables";
|
||||
|
||||
public const string OpenApiDocDescription = "description";
|
||||
|
||||
public const string OpenApiDocRequired = "required";
|
||||
|
||||
public const string OpenApiDocDeprecated = "deprecated";
|
||||
|
||||
public const string OpenApiDocStyle = "style";
|
||||
|
||||
public const string OpenApiDocExplode = "explode";
|
||||
|
||||
public const string OpenApiDocAllowReserved = "allowReserved";
|
||||
|
||||
public const string OpenApiDocSchema = "schema";
|
||||
|
||||
public const string OpenApiDocSchemas = "schemas";
|
||||
|
||||
public const string OpenApiDocResponses = "responses";
|
||||
|
||||
public const string OpenApiDocExample = "example";
|
||||
|
||||
public const string OpenApiDocExamples = "examples";
|
||||
|
||||
public const string OpenApiDocEncoding = "encoding";
|
||||
|
||||
public const string OpenApiDocRequestBodies = "requestBodies";
|
||||
|
||||
public const string OpenApiDocAllowEmptyValue = "allowEmptyValue";
|
||||
|
||||
public const string OpenApiDocValue = "value";
|
||||
|
||||
public const string OpenApiDocExternalValue = "externalValue";
|
||||
|
||||
public const string OpenApiDocDollarRef = "$ref";
|
||||
|
||||
public const string OpenApiDocHeaders = "headers";
|
||||
|
||||
public const string OpenApiDocSecuritySchemes = "securitySchemes";
|
||||
|
||||
public const string OpenApiDocContent = "content";
|
||||
|
||||
public const string OpenApiDocLinks = "links";
|
||||
|
||||
public const string OpenApiDocCallbacks = "callbacks";
|
||||
|
||||
public const string OpenApiDocUrl = "url";
|
||||
|
||||
public const string OpenApiDocEmail = "email";
|
||||
|
||||
public const string OpenApiDocDefault = "default";
|
||||
|
||||
public const string OpenApiDocEnum = "enum";
|
||||
|
||||
public const string OpenApiDocMultipleOf = "multipleOf";
|
||||
|
||||
public const string OpenApiDocMaximum = "maximum";
|
||||
|
||||
public const string OpenApiDocExclusiveMaximum = "exclusiveMaximum";
|
||||
|
||||
public const string OpenApiDocMinimum = "minimum";
|
||||
|
||||
public const string OpenApiDocExclusiveMinimum = "exclusiveMinimum";
|
||||
|
||||
public const string OpenApiDocMaxLength = "maxLength";
|
||||
|
||||
public const string OpenApiDocMinLength = "minLength";
|
||||
|
||||
public const string OpenApiDocPattern = "pattern";
|
||||
|
||||
public const string OpenApiDocMaxItems = "maxItems";
|
||||
|
||||
public const string OpenApiDocMinItems = "minItems";
|
||||
|
||||
public const string OpenApiDocUniqueItems = "uniqueItems";
|
||||
|
||||
public const string OpenApiDocMaxProperties = "maxProperties";
|
||||
|
||||
public const string OpenApiDocMinProperties = "minProperties";
|
||||
|
||||
public const string OpenApiDocAllOf = "allOf";
|
||||
|
||||
public const string OpenApiDocOneOf = "oneOf";
|
||||
|
||||
public const string OpenApiDocAnyOf = "anyOf";
|
||||
|
||||
public const string OpenApiDocNot = "not";
|
||||
|
||||
public const string OpenApiDocItems = "items";
|
||||
|
||||
public const string OpenApiDocProperties = "properties";
|
||||
|
||||
public const string OpenApiDocAdditionalProperties = "additionalProperties";
|
||||
|
||||
public const string OpenApiDocNullable = "nullable";
|
||||
|
||||
public const string OpenApiDocDiscriminator = "discriminator";
|
||||
|
||||
public const string OpenApiDocReadOnly = "readOnly";
|
||||
|
||||
public const string OpenApiDocWriteOnly = "writeOnly";
|
||||
|
||||
public const string OpenApiDocXml = "xml";
|
||||
|
||||
public const string OpenApiDocImplicit = "implicit";
|
||||
|
||||
public const string OpenApiDocPassword = "password";
|
||||
|
||||
public const string OpenApiDocClientCredentials = "clientCredentials";
|
||||
|
||||
public const string OpenApiDocAuthorizationCode = "authorizationCode";
|
||||
|
||||
public const string OpenApiDocAuthorizationUrl = "authorizationUrl";
|
||||
|
||||
public const string OpenApiDocTokenUrl = "tokenUrl";
|
||||
|
||||
public const string OpenApiDocRefreshUrl = "refreshUrl";
|
||||
|
||||
public const string OpenApiDocScopes = "scopes";
|
||||
|
||||
public const string OpenApiDocContentType = "contentType";
|
||||
|
||||
public const string OpenApiDocGet = "get";
|
||||
public const string OpenApiDocPut = "put";
|
||||
public const string OpenApiDocPost = "post";
|
||||
public const string OpenApiDocDelete = "delete";
|
||||
public const string OpenApiDocOptions = "options";
|
||||
public const string OpenApiDocHead = "head";
|
||||
public const string OpenApiDocPatch = "patch";
|
||||
public const string OpenApiDocTrace = "trace";
|
||||
|
||||
public const string OpenApiDocDefaultName = "Default Name";
|
||||
public const string OpenApiDocDefaultDefault = "Default Default";
|
||||
public const string OpenApiDocDefaultTitle = "Default Title";
|
||||
public static Version OpenApiDocDefaultVersion = new Version(3, 0, 0);
|
||||
public static Uri OpenApiDocDefaultUrl = new Uri("http://localhost/");
|
||||
public const string OpenApiDocDefaultDescription = "Default Description";
|
||||
}
|
||||
}
|
68
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiContact.cs
Normal file
68
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiContact.cs
Normal file
|
@ -0,0 +1,68 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiContact.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Contact Object.
|
||||
/// </summary>
|
||||
internal class OpenApiContact : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// The identifying name of the contact person/organization.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The URL pointing to the contact information. MUST be in the format of a URL.
|
||||
/// </summary>
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The email address of the contact person/organization.
|
||||
/// MUST be in the format of an email address.
|
||||
/// </summary>
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API Contact object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// name
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocName, Name);
|
||||
|
||||
// url
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocUrl, Url?.OriginalString);
|
||||
|
||||
// email
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocEmail, Email);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiDataTypeKind.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Primitive Data Types in the Open Api Specification.
|
||||
/// </summary>
|
||||
internal enum OpenApiDataTypeKind
|
||||
{
|
||||
/// <summary>
|
||||
/// None.
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata]
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Integer
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "integer", Type = "integer", Format = "int32", Comments ="signed 32 bits")]
|
||||
Integer,
|
||||
|
||||
/// <summary>
|
||||
/// Long
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "long", Type = "integer", Format = "int642", Comments = "signed 64 bits")]
|
||||
Long,
|
||||
|
||||
/// <summary>
|
||||
/// Float
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "float", Type = "number", Format = "float")]
|
||||
Float,
|
||||
|
||||
/// <summary>
|
||||
/// Double
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "double", Type = "number", Format = "double")]
|
||||
Double,
|
||||
|
||||
/// <summary>
|
||||
/// String
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "string", Type = "string")]
|
||||
String,
|
||||
|
||||
/// <summary>
|
||||
/// Byte
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "byte", Type = "string", Format = "byte", Comments = "base64 encoded characters")]
|
||||
Byte,
|
||||
|
||||
/// <summary>
|
||||
/// Binary
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "binary", Type = "string", Format = "binary", Comments = "any sequence of octets")]
|
||||
Binary,
|
||||
|
||||
/// <summary>
|
||||
/// Boolean
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "boolean", Type = "boolean")]
|
||||
Boolean,
|
||||
|
||||
/// <summary>
|
||||
/// Date
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "date", Type = "string", Format = "date", Comments = "As defined by full-date - RFC3339")]
|
||||
Date,
|
||||
|
||||
/// <summary>
|
||||
/// DateTime
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "dateTime", Type = "string", Format = "date-time", Comments = "As defined by date-time - RFC3339")]
|
||||
DateTime,
|
||||
|
||||
/// <summary>
|
||||
/// Password
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "password", Type = "string", Format = "password", Comments = "A hint to UIs to obscure input")]
|
||||
Password
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for Open Api Data Type kind.
|
||||
/// </summary>
|
||||
internal static class OpenApiDataTypeKindExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the Common Name.
|
||||
/// </summary>
|
||||
/// <param name="kind">The Open Api data type kind.</param>
|
||||
/// <returns>The Common Name.</returns>
|
||||
public static string GetCommonName(this OpenApiDataTypeKind kind)
|
||||
{
|
||||
OpenApiDataTypeMetadataAttribute attribute = kind.GetAttributeOfType<OpenApiDataTypeMetadataAttribute>();
|
||||
return attribute?.CommonName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Type.
|
||||
/// </summary>
|
||||
/// <param name="kind">The Open Api data type kind.</param>
|
||||
/// <returns>The Type.</returns>
|
||||
public static string GetTypeName(this OpenApiDataTypeKind kind)
|
||||
{
|
||||
OpenApiDataTypeMetadataAttribute attribute = kind.GetAttributeOfType<OpenApiDataTypeMetadataAttribute>();
|
||||
return attribute?.Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Format.
|
||||
/// </summary>
|
||||
/// <param name="kind">The Open Api data type kind.</param>
|
||||
/// <returns>The Format.</returns>
|
||||
public static string GetFormat(this OpenApiDataTypeKind kind)
|
||||
{
|
||||
OpenApiDataTypeMetadataAttribute attribute = kind.GetAttributeOfType<OpenApiDataTypeMetadataAttribute>();
|
||||
return attribute?.Format;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the Comments.
|
||||
/// </summary>
|
||||
/// <param name="kind">The Open Api data type kind.</param>
|
||||
/// <returns>The Comments.</returns>
|
||||
public static string GetComments(this OpenApiDataTypeKind kind)
|
||||
{
|
||||
OpenApiDataTypeMetadataAttribute attribute = kind.GetAttributeOfType<OpenApiDataTypeMetadataAttribute>();
|
||||
return attribute?.Comments;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiDataTypeMetadataAttribute.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Open Api Data type metadata attribute.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
|
||||
internal class OpenApiDataTypeMetadataAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Common Name.
|
||||
/// </summary>
|
||||
public string CommonName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Type name.
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Format name
|
||||
/// </summary>
|
||||
public string Format { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Comments.
|
||||
/// </summary>
|
||||
public string Comments { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiDictionaryOfT.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Open Api Dictionary with extended of T.
|
||||
/// </summary>
|
||||
internal abstract class OpenApiDictionaryExtensibleOfT<T> : OpenApiDictionary<T>, IOpenApiExtensible
|
||||
where T : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write something before.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public override void WriteAfterStart(IOpenApiWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write something after.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public override void WriteBeforeEnd(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiDictionaryOfT.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Open Api Dictionary of T.
|
||||
/// </summary>
|
||||
internal abstract class OpenApiDictionary<T> : Dictionary<string, T>,
|
||||
IOpenApiElement,
|
||||
IOpenApiWritable
|
||||
where T : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// Add a key/value item.
|
||||
/// </summary>
|
||||
/// <param name="item">The key/value item.</param>
|
||||
public void Add(KeyValuePair<string, T> item)
|
||||
{
|
||||
Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a Tuple(key, value) item.
|
||||
/// </summary>
|
||||
/// <param name="item">The Tuple(key, value) item.</param>
|
||||
public void Add(Tuple<string, T> item)
|
||||
{
|
||||
Add(item.Item1, item.Item2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// write something after start
|
||||
WriteAfterStart(writer);
|
||||
|
||||
// path items
|
||||
foreach (var item in this)
|
||||
{
|
||||
writer.WriteRequiredObject(item.Key, item.Value);
|
||||
}
|
||||
|
||||
// write something before end.
|
||||
WriteBeforeEnd(writer);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
public abstract void WriteAfterStart(IOpenApiWriter writer);
|
||||
|
||||
public abstract void WriteBeforeEnd(IOpenApiWriter writer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiDiscriminator.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal class OpenApiDiscriminator : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
152
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiDocument.cs
Normal file
152
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiDocument.cs
Normal file
|
@ -0,0 +1,152 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiDocument.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.IO;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes an Open API Document. See: https://swagger.io/specification/
|
||||
/// </summary>
|
||||
internal class OpenApiDocument : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED.This string MUST be the semantic version number of the OpenAPI Specification version that the OpenAPI document uses.
|
||||
/// </summary>
|
||||
public Version OpenApi { get; set; } = new Version(3, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. Provides metadata about the API. The metadata MAY be used by tooling as required.
|
||||
/// </summary>
|
||||
public OpenApiInfo Info { get; set; } = new OpenApiInfo();
|
||||
|
||||
/// <summary>
|
||||
/// An array of Server Objects, which provide connectivity information to a target server.
|
||||
/// </summary>
|
||||
public IList<OpenApiServer> Servers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The available paths and operations for the API.
|
||||
/// </summary>
|
||||
public OpenApiPaths Paths { get; set; } = new OpenApiPaths();
|
||||
|
||||
/// <summary>
|
||||
/// An element to hold various schemas for the specification.
|
||||
/// </summary>
|
||||
public OpenApiComponents Components { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A declaration of which security mechanisms can be used across the API.
|
||||
/// </summary>
|
||||
public IList<OpenApiSecurity> Security { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of tags used by the specification with additional metadata.
|
||||
/// </summary>
|
||||
public IList<OpenApiTag> Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional external documentation.
|
||||
/// </summary>
|
||||
public OpenApiExternalDocs ExternalDoc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API document to given stream using default writer.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to write.</param>
|
||||
public virtual void Write(Stream stream)
|
||||
{
|
||||
Write(stream, DefaultOpenApiWriter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API document to given stream using given writer factory
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to write.</param>
|
||||
/// <param name="writerFactory">The writer factory.</param>
|
||||
public virtual void Write(Stream stream, Func<Stream, IOpenApiWriter> writerFactory)
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
throw Error.ArgumentNull("stream");
|
||||
}
|
||||
|
||||
if (writerFactory == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writerFactory");
|
||||
}
|
||||
|
||||
IOpenApiWriter writer = writerFactory(stream);
|
||||
this.Write(writer);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API document to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// openapi:3.0.0
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocOpenApi, OpenApi.ToString());
|
||||
|
||||
// info
|
||||
writer.WriteRequiredObject(OpenApiConstants.OpenApiDocInfo, Info);
|
||||
|
||||
// servers
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocServers, Servers);
|
||||
|
||||
// paths
|
||||
writer.WriteRequiredObject(OpenApiConstants.OpenApiDocPaths, Paths);
|
||||
|
||||
// components
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocComponents, Components);
|
||||
|
||||
// security
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocSecurity, Security);
|
||||
|
||||
// tags
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocTags, Tags);
|
||||
|
||||
// external docs
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExternalDocs, ExternalDoc);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
|
||||
// flush
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
private static IOpenApiWriter DefaultOpenApiWriter(Stream stream)
|
||||
{
|
||||
StreamWriter writer = new StreamWriter(stream)
|
||||
{
|
||||
NewLine = "\n"
|
||||
};
|
||||
|
||||
return new OpenApiJsonWriter(writer);
|
||||
}
|
||||
}
|
||||
}
|
16
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiElement.cs
Normal file
16
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiElement.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiElement.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal abstract class OpenApiElement : IOpenApiElement
|
||||
{
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
// nothing here
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiEncoding.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Encoding Object.
|
||||
/// </summary>
|
||||
internal class OpenApiEncoding : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// The Content-Type for encoding a specific property.
|
||||
/// </summary>
|
||||
public string ContentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map allowing additional information to be provided as headers.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiHeader> Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Describes how a specific property value will be serialized depending on its type.
|
||||
/// </summary>
|
||||
public ParameterStyle? Style { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Explode
|
||||
/// </summary>
|
||||
public bool? Explode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AllowReserved
|
||||
/// </summary>
|
||||
public bool? AllowReserved { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Encoding object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// contentType
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocContentType, ContentType);
|
||||
|
||||
// headers
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocHeaders, Headers);
|
||||
|
||||
// style
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocStyle, Style?.ToString());
|
||||
|
||||
// explode
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocExplode, Explode);
|
||||
|
||||
// allowReserved
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocAllowReserved, AllowReserved);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
119
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiExample.cs
Normal file
119
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiExample.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiExample.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Example Object.
|
||||
/// </summary>
|
||||
internal class OpenApiExample : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable, IOpenApiReferencable
|
||||
{
|
||||
private OpenApiAny _value;
|
||||
private Uri _externalValue;
|
||||
|
||||
/// <summary>
|
||||
/// Short description for the example.
|
||||
/// </summary>
|
||||
public string Summary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Long description for the example.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Embedded literal example.
|
||||
/// </summary>
|
||||
public OpenApiAny Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
set
|
||||
{
|
||||
// The value field and external Value field are mutually exclusive.
|
||||
_externalValue = null;
|
||||
_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A URL that points to the literal example.
|
||||
/// </summary>
|
||||
public Uri ExternalValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return _externalValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
// The value field and external Value field are mutually exclusive.
|
||||
_value = null;
|
||||
_externalValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference Object.
|
||||
/// </summary>
|
||||
public OpenApiReference Reference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Example object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (Reference != null)
|
||||
{
|
||||
Reference.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInternal(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteInternal(IOpenApiWriter writer)
|
||||
{
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// summary
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocSummary, Summary);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// value
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocValue, Value);
|
||||
|
||||
// externalValue
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocExternalValue, ExternalValue?.OriginalString);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="IOpenApiExtendable.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal abstract class OpenApiExtendableElement : OpenApiElement, IOpenApiExtensible
|
||||
{
|
||||
private IList<OpenApiExtension> _extensions;
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _extensions;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a specification extension into tag.
|
||||
/// </summary>
|
||||
/// <param name="item">The specification extension.</param>
|
||||
public void Add(OpenApiExtension item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_extensions == null)
|
||||
{
|
||||
_extensions = new List<OpenApiExtension>();
|
||||
}
|
||||
|
||||
_extensions.Add(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write specification extensions object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API Writer.</param>
|
||||
public override void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiExtension.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Additional data can be added to extend the specification at certain points.
|
||||
/// </summary>
|
||||
internal class OpenApiExtension : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// The field name MUST begin with x-, for example, x-internal-id
|
||||
/// </summary>
|
||||
public string Name { get;}
|
||||
|
||||
/// <summary>
|
||||
/// The value can be null, a primitive, an array or an object. Can have any valid JSON format value.
|
||||
/// </summary>
|
||||
public object Value { get;}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiExtension"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The field name.</param>
|
||||
/// <param name="value">The field value.</param>
|
||||
public OpenApiExtension(string name, object value)
|
||||
{
|
||||
VerifyExtensionName(name);
|
||||
VerifyExtensionValue(value);
|
||||
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API document to given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
writer.WritePropertyName(Name);
|
||||
|
||||
if (Value is IOpenApiWritable)
|
||||
{
|
||||
((IOpenApiWritable)Value).Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO:
|
||||
writer.WriteValue(Value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void VerifyExtensionName(string name)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw Error.ArgumentNullOrEmpty("name");
|
||||
}
|
||||
|
||||
if (!name.StartsWith(OpenApiConstants.OpenApiDocExtensionFieldNamePrefix))
|
||||
{
|
||||
throw new OpenApiException(SRResource.ExtensionFieldNameMustBeginWithXMinus);
|
||||
}
|
||||
}
|
||||
|
||||
private static void VerifyExtensionValue(object value)
|
||||
{
|
||||
// TODO, verify the value can be null, a primitive, an array or an object.
|
||||
// Can have any valid JSON format value
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiExternalDocs.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows referencing an external resource for extended documentation.
|
||||
/// </summary>
|
||||
internal class OpenApiExternalDocs : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED.The URL for the target documentation. Value MUST be in the format of a URL.
|
||||
/// </summary>
|
||||
public Uri Url { get; set; } = OpenApiConstants.OpenApiDocDefaultUrl;
|
||||
|
||||
/// <summary>
|
||||
/// A short description of the target documentation.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API External Documentation object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API Writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// url
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocUrl, Url?.OriginalString);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
19
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiHeader.cs
Normal file
19
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiHeader.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiHeader.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Header Object.
|
||||
/// The Header Object follows the structure of the Parameter Object
|
||||
/// </summary>
|
||||
internal class OpenApiHeader : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
91
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiInfo.cs
Normal file
91
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiInfo.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiInfo.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Open API Info Object, it provides the metadata about the Open API.
|
||||
/// </summary>
|
||||
internal class OpenApiInfo : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED. The title of the application.
|
||||
/// </summary>
|
||||
public string Title { get; set; } = OpenApiConstants.OpenApiDocDefaultTitle;
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The version of the OpenAPI document.
|
||||
/// </summary>
|
||||
public Version Version { get; set; } = OpenApiConstants.OpenApiDocDefaultVersion;
|
||||
|
||||
/// <summary>
|
||||
/// A short description of the application.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A URL to the Terms of Service for the API. MUST be in the format of a URL.
|
||||
/// </summary>
|
||||
public Uri TermsOfService { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The contact information for the exposed API.
|
||||
/// </summary>
|
||||
public OpenApiContact Contact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The license information for the exposed API.
|
||||
/// </summary>
|
||||
public OpenApiLicense License { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API Info to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// title
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocTitle, Title);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// termsOfService
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocTermsOfService, TermsOfService?.OriginalString);
|
||||
|
||||
// contact object
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocContact, Contact);
|
||||
|
||||
// license object
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocLicense, License);
|
||||
|
||||
// version
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocVersion, Version?.ToString());
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
59
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiLicense.cs
Normal file
59
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiLicense.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiLicense.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// License Object.
|
||||
/// </summary>
|
||||
internal class OpenApiLicense : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED.The license name used for the API.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = OpenApiConstants.OpenApiDocDefaultName;
|
||||
|
||||
/// <summary>
|
||||
/// The URL pointing to the contact information. MUST be in the format of a URL.
|
||||
/// </summary>
|
||||
public Uri Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API license object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// name
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocName, Name);
|
||||
|
||||
// url
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocUrl, Url?.OriginalString);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
198
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiLink.cs
Normal file
198
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiLink.cs
Normal file
|
@ -0,0 +1,198 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiLink.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Link Object.
|
||||
/// </summary>
|
||||
internal class OpenApiLink : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable, IOpenApiReferencable
|
||||
{
|
||||
private string _operationRef;
|
||||
private string _operationId;
|
||||
private string _description;
|
||||
private IDictionary<string, OpenApiAny> _parameters;
|
||||
private OpenApiAny _requestBody;
|
||||
private OpenApiServer _server;
|
||||
private IList<OpenApiExtension> _extensions;
|
||||
|
||||
/// <summary>
|
||||
/// A relative or absolute reference to an OAS operation.
|
||||
/// </summary>
|
||||
public string OperationRef
|
||||
{
|
||||
get
|
||||
{
|
||||
return _operationRef;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ValidateReference();
|
||||
|
||||
_operationRef = value;
|
||||
|
||||
// This field is mutually exclusive of the operationId field
|
||||
_operationId = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of an existing, resolvable OAS operation, as defined with a unique operationId.
|
||||
/// </summary>
|
||||
public string OperationId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _operationId;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ValidateReference();
|
||||
|
||||
_operationId = value;
|
||||
|
||||
///This field is mutually exclusive of the operationRef field.
|
||||
_operationRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A map representing parameters to pass to an operation
|
||||
/// as specified with operationId or identified via operationRef.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiAny> Parameters
|
||||
{
|
||||
get
|
||||
{
|
||||
return _parameters;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ValidateReference();
|
||||
_parameters = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A literal value or {expression} to use as a request body when calling the target operation.
|
||||
/// </summary>
|
||||
public OpenApiAny RequestBody
|
||||
{
|
||||
get
|
||||
{
|
||||
return _requestBody;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ValidateReference();
|
||||
_requestBody = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A description of the link.
|
||||
/// </summary>
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return _description;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ValidateReference();
|
||||
_description = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A server object to be used by the target operation.
|
||||
/// </summary>
|
||||
public OpenApiServer Server
|
||||
{
|
||||
get { return _server; }
|
||||
set
|
||||
{
|
||||
this.ValidateReference();
|
||||
_server = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _extensions;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.ValidateReference();
|
||||
_extensions = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reference Object.
|
||||
/// </summary>
|
||||
public OpenApiReference Reference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API response to given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (Reference != null)
|
||||
{
|
||||
Reference.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInternal(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteInternal(IOpenApiWriter writer)
|
||||
{
|
||||
// { for JSON, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// operationRef
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocOperationRef, OperationRef);
|
||||
|
||||
// operationId
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocOperationId, OperationId);
|
||||
|
||||
// parameters
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocParameters, Parameters);
|
||||
|
||||
// requestBody
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocRequestBody, RequestBody);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// server
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocServer, Server);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for JSON, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiMediaType.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Media Type Object.
|
||||
/// </summary>
|
||||
internal class OpenApiMediaType : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// The schema defining the type used for the request body.
|
||||
/// </summary>
|
||||
public OpenApiSchema Schema { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Example of the media type.
|
||||
/// </summary>
|
||||
public OpenApiAny Example { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Examples of the media type.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiExample> Examples { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map between a property name and its encoding information.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiEncoding> Encoding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write media type object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// schema
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocSchema, Schema);
|
||||
|
||||
// example
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExample, Example);
|
||||
|
||||
// examples
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocExamples, Examples);
|
||||
|
||||
// encoding
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocEncoding, Encoding);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiOAuthFlow.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// OAuth Flow Object.
|
||||
/// </summary>
|
||||
internal class OpenApiOAuthFlow : IOpenApiElement, IOpenApiWritable,IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED. The authorization URL to be used for this flow.
|
||||
/// </summary>
|
||||
public Uri AuthorizationUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The token URL to be used for this flow.
|
||||
/// </summary>
|
||||
public Uri TokenUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The URL to be used for obtaining refresh tokens.
|
||||
/// </summary>
|
||||
public Uri RefreshUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The available scopes for the OAuth2 security scheme.
|
||||
/// A map between the scope name and a short description for it.
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Scopes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// authorizationUrl
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocAuthorizationUrl, AuthorizationUrl?.OriginalString);
|
||||
|
||||
// tokenUrl
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocTokenUrl, TokenUrl?.OriginalString);
|
||||
|
||||
// refreshUrl
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocRefreshUrl, RefreshUrl?.OriginalString);
|
||||
|
||||
// scopes
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocScopes, Scopes);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiOAuthFlows.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// OAuth Flows Object.
|
||||
/// </summary>
|
||||
internal class OpenApiOAuthFlows : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration for the OAuth Implicit flow
|
||||
/// </summary>
|
||||
public OpenApiOAuthFlows Implicit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configuration for the OAuth Resource Owner Password flow
|
||||
/// </summary>
|
||||
public OpenApiOAuthFlows Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configuration for the OAuth Client Credentials flow.
|
||||
/// </summary>
|
||||
public OpenApiOAuthFlows ClientCredentials { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configuration for the OAuth Authorization Code flow.
|
||||
/// </summary>
|
||||
public OpenApiOAuthFlows AuthorizationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// implicit
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocImplicit, Implicit);
|
||||
|
||||
// password
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocPassword, Password);
|
||||
|
||||
// clientCredentials
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocClientCredentials, ClientCredentials);
|
||||
|
||||
// authorizationCode
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocAuthorizationCode, AuthorizationCode);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
138
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiOperation.cs
Normal file
138
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiOperation.cs
Normal file
|
@ -0,0 +1,138 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiOperation.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Operation Object.
|
||||
/// </summary>
|
||||
internal class OpenApiOperation : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// A list of tags for API documentation control.
|
||||
/// </summary>
|
||||
public IList<string> Tags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A short summary of what the operation does.
|
||||
/// </summary>
|
||||
public string Summary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A verbose explanation of the operation behavior.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional external documentation for this operation.
|
||||
/// </summary>
|
||||
public OpenApiExternalDocs ExternalDocs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unique string used to identify the operation.
|
||||
/// </summary>
|
||||
public string OperationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of parameters.
|
||||
/// </summary>
|
||||
public IList<OpenApiParameter> Parameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The request body applicable for this operation.
|
||||
/// </summary>
|
||||
public OpenApiRequestBody RequestBody { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The list of possible responses as they are returned from executing this operation.
|
||||
/// </summary>
|
||||
public OpenApiResponses Responses { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map of possible out-of band callbacks related to the parent operation.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiCallback> Callbacks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Declares this operation to be deprecated.
|
||||
/// </summary>
|
||||
public bool? Deprecated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Security requirement list.
|
||||
/// </summary>
|
||||
public IList<OpenApiSecurityRequirement> Security { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An alternative server array to service this operation.
|
||||
/// </summary>
|
||||
public IList<OpenApiServer> Servers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API operation object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API Writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// summary
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocSummary, Summary);
|
||||
|
||||
// tags
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocTags, Tags);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// externalDocs
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExternalDocs, ExternalDocs);
|
||||
|
||||
// operationId
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocOperationId, OperationId);
|
||||
|
||||
// parameters
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocParameters, Parameters);
|
||||
|
||||
// requestBody
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocRequestBody, RequestBody);
|
||||
|
||||
// responses
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocResponses, Responses);
|
||||
|
||||
// callbacks
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocCallbacks, Callbacks);
|
||||
|
||||
// deprecated
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDeprecated, Deprecated);
|
||||
|
||||
// security
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocSecurity, Security);
|
||||
|
||||
// servers
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocServers, Servers);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
317
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiParameter.cs
Normal file
317
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiParameter.cs
Normal file
|
@ -0,0 +1,317 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiParameter.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.Diagnostics;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameter Locations.
|
||||
/// A unique parameter is defined by a combination of a name and location.
|
||||
/// </summary>
|
||||
internal enum ParameterLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// Parameters that are appended to the URL.
|
||||
/// </summary>
|
||||
query,
|
||||
|
||||
/// <summary>
|
||||
/// Custom headers that are expected as part of the request.
|
||||
/// </summary>
|
||||
header,
|
||||
|
||||
/// <summary>
|
||||
/// Used together with Path Templating, where the parameter value is actually part of the operation's URL.
|
||||
/// </summary>
|
||||
path,
|
||||
|
||||
/// <summary>
|
||||
/// Used to pass a specific cookie value to the API.
|
||||
/// </summary>
|
||||
cookie
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type of the parameter value.
|
||||
/// </summary>
|
||||
internal enum ParameterStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// Path-style parameters.
|
||||
/// </summary>
|
||||
matrix,
|
||||
|
||||
/// <summary>
|
||||
/// Label style parameters.
|
||||
/// </summary>
|
||||
label,
|
||||
|
||||
/// <summary>
|
||||
/// Form style parameters.
|
||||
/// </summary>
|
||||
form,
|
||||
|
||||
/// <summary>
|
||||
/// Simple style parameters.
|
||||
/// </summary>
|
||||
simple,
|
||||
|
||||
/// <summary>
|
||||
/// Space separated array values.
|
||||
/// </summary>
|
||||
spaceDelimited,
|
||||
|
||||
/// <summary>
|
||||
/// Pipe separated array values.
|
||||
/// </summary>
|
||||
pipeDelimited,
|
||||
|
||||
/// <summary>
|
||||
/// Provides a simple way of rendering nested objects using form parameters.
|
||||
/// </summary>
|
||||
deepObject
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameter Object.
|
||||
/// </summary>
|
||||
internal class OpenApiParameter : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable, IOpenApiReferencable
|
||||
{
|
||||
private bool _required = false;
|
||||
private OpenApiAny _example;
|
||||
private ParameterLocation _location;
|
||||
private IDictionary<string, OpenApiExample> _examples;
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The name of the parameter.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The location of the parameter.
|
||||
/// </summary>
|
||||
public ParameterLocation In
|
||||
{
|
||||
get
|
||||
{
|
||||
return _location;
|
||||
}
|
||||
set
|
||||
{
|
||||
// Default values for the Style property:
|
||||
switch (value)
|
||||
{
|
||||
case ParameterLocation.query:
|
||||
case ParameterLocation.cookie:
|
||||
Style = ParameterStyle.form;
|
||||
break;
|
||||
case ParameterLocation.path:
|
||||
case ParameterLocation.header:
|
||||
Style = ParameterStyle.simple;
|
||||
break;
|
||||
}
|
||||
|
||||
_location = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A brief description of the parameter.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this parameter is mandatory.
|
||||
/// If the parameter location is "path", this property is REQUIRED and its value MUST be true.
|
||||
/// Otherwise, the property MAY be included and its default value is false.
|
||||
/// </summary>
|
||||
public bool Required
|
||||
{
|
||||
get
|
||||
{
|
||||
return _required;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (In == ParameterLocation.path && !value)
|
||||
{
|
||||
throw new OpenApiException(SRResource.OpenApiParameterRequiredPropertyMandatory);
|
||||
}
|
||||
|
||||
_required = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that a parameter is deprecated and SHOULD be transitioned out of usage.
|
||||
/// </summary>
|
||||
public bool Deprecated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the ability to pass empty-valued parameters.
|
||||
/// </summary>
|
||||
public bool AllowEmptyValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Describes how the parameter value will be serialized depending on the type of the parameter value.
|
||||
/// </summary>
|
||||
public ParameterStyle Style { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When this is true, parameter values of type array or object generate separate parameters for
|
||||
/// each value of the array or key-value pair of the map. For other types of parameters
|
||||
/// this property has no effect. When style is form, the default value is true.
|
||||
/// For all other styles, the default value is false.
|
||||
/// </summary>
|
||||
public bool Explode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986.
|
||||
/// </summary>
|
||||
public bool AllowReserved { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The schema defining the type used for the parameter.
|
||||
/// </summary>
|
||||
public OpenApiSchema Schema { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Example of the media type. The example object is mutually exclusive of the examples object.
|
||||
/// </summary>
|
||||
public OpenApiAny Example
|
||||
{
|
||||
get
|
||||
{
|
||||
return _example;
|
||||
}
|
||||
set
|
||||
{
|
||||
// The examples object is mutually exclusive of the example object.
|
||||
_examples = null;
|
||||
_example = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Examples of the media type. The examples object is mutually exclusive of the example object.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiExample> Examples
|
||||
{
|
||||
get
|
||||
{
|
||||
return _examples;
|
||||
}
|
||||
set
|
||||
{
|
||||
// The examples object is mutually exclusive of the example object.
|
||||
_example = null;
|
||||
_examples = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A map containing the representations for the parameter.
|
||||
/// The key is the media type and the value describes it.
|
||||
/// The map MUST only contain one entry.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiMediaType> Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference Object.
|
||||
/// </summary>
|
||||
public OpenApiReference Reference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write parameter object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (Reference != null)
|
||||
{
|
||||
Reference.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInternal(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteInternal(IOpenApiWriter writer)
|
||||
{
|
||||
Debug.Assert(writer != null);
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// name
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocName, Name);
|
||||
|
||||
// in
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocIn, In.ToString());
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// required
|
||||
if (In == ParameterLocation.path)
|
||||
{
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocRequired, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteBooleanProperty(OpenApiConstants.OpenApiDocRequired, Required, false);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
writer.WriteBooleanProperty(OpenApiConstants.OpenApiDocDeprecated, Deprecated, false);
|
||||
|
||||
// allowEmptyValue
|
||||
writer.WriteBooleanProperty(OpenApiConstants.OpenApiDocDeprecated, AllowEmptyValue, false);
|
||||
|
||||
// style
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocStyle, Style.ToString());
|
||||
|
||||
// explode
|
||||
writer.WriteBooleanProperty(OpenApiConstants.OpenApiDocExplode, Explode, false);
|
||||
|
||||
// allowReserved
|
||||
writer.WriteBooleanProperty(OpenApiConstants.OpenApiDocAllowReserved, AllowReserved, false);
|
||||
|
||||
// schema
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocSchema, Schema);
|
||||
|
||||
// example
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExample, Example);
|
||||
|
||||
// examples
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocExamples, Examples);
|
||||
|
||||
// content
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocContent, Content);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
160
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiPathItem.cs
Normal file
160
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiPathItem.cs
Normal file
|
@ -0,0 +1,160 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiPathItem.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Path Item Object: to describe the operations available on a single path.
|
||||
/// </summary>
|
||||
internal class OpenApiPathItem : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible, IOpenApiReferencable
|
||||
{
|
||||
/// <summary>
|
||||
/// An optional, string summary.
|
||||
/// </summary>
|
||||
public string Summary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An optional, string description.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a GET operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Get { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a PUT operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Put { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a POST operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Post { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a DELETE operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Delete { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a OPTIONS operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Options { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a HEAD operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Head { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a PATCH operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Patch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A definition of a TRACE operation on this path.
|
||||
/// </summary>
|
||||
public OpenApiOperation Trace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An alternative server array to service all operations in this path.
|
||||
/// </summary>
|
||||
public IList<OpenApiServer> Servers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of parameters
|
||||
/// </summary>
|
||||
public IList<OpenApiParameter> Parameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference Object.
|
||||
/// </summary>
|
||||
public OpenApiReference Reference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API response to given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (Reference != null)
|
||||
{
|
||||
Reference.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInternal(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteInternal(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// summary
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocSummary, Summary);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// get
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocGet, Get);
|
||||
|
||||
// put
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocPut, Put);
|
||||
|
||||
// post
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocPost, Post);
|
||||
|
||||
// delete
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocDelete, Delete);
|
||||
|
||||
// options
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocOptions, Options);
|
||||
|
||||
// head
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocHead, Head);
|
||||
|
||||
// patch
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocPatch, Patch);
|
||||
|
||||
// trace
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocTrace, Trace);
|
||||
|
||||
// servers
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocServers, Servers);
|
||||
|
||||
// parameters
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocParameters, Parameters);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
15
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiPaths.cs
Normal file
15
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiPaths.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiPaths.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Paths object.
|
||||
/// </summary>
|
||||
internal class OpenApiPaths : OpenApiDictionaryExtensibleOfT<OpenApiPathItem>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiReference.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference Object.
|
||||
/// </summary>
|
||||
internal class OpenApiReference : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED. The reference string.
|
||||
/// </summary>
|
||||
public string Ref { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiReference"/> class.
|
||||
/// </summary>
|
||||
/// <param name="ref"></param>
|
||||
public OpenApiReference(string @ref)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(@ref))
|
||||
{
|
||||
throw Error.ArgumentNullOrEmpty(nameof(@ref));
|
||||
}
|
||||
|
||||
Ref = @ref;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API reference object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for JSON, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// $ref
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocDollarRef, Ref);
|
||||
|
||||
// } for JSON, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiRequestBody.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Request Body Object
|
||||
/// </summary>
|
||||
internal class OpenApiRequestBody : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// A brief description of the request body.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The content of the request body.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiMediaType> Content;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the request body is required in the request. Defaults to false.
|
||||
/// </summary>
|
||||
public bool? Required { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// content
|
||||
writer.WriteRequiredDictionary(OpenApiConstants.OpenApiDocContent, Content);
|
||||
|
||||
// required
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocRequired, Required);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiResponse.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.Diagnostics;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal class OpenApiResponse : IOpenApiElement, IOpenApiWritable, IOpenApiExtensible, IOpenApiReferencable
|
||||
{
|
||||
private IDictionary<string, OpenApiHeader> _headers;
|
||||
private IDictionary<string, OpenApiMediaType> _content;
|
||||
private IDictionary<string, OpenApiLink> _link;
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. A short description of the response.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maps a header name to its definition.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiHeader> Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map containing descriptions of potential response payloads.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiMediaType> Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map of operations links that can be followed from the response.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiLink> Links { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference object.
|
||||
/// </summary>
|
||||
public OpenApiReference Reference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API response to given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (Reference != null)
|
||||
{
|
||||
Reference.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInternal(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteInternal(IOpenApiWriter writer)
|
||||
{
|
||||
Debug.Assert(writer != null);
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// description
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// headers
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocHeaders, Headers);
|
||||
|
||||
// content
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocContent, Content);
|
||||
|
||||
// headers
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocLinks, Links);
|
||||
|
||||
// Extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiResponses.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Responses object.
|
||||
/// </summary>
|
||||
internal class OpenApiResponses : OpenApiDictionaryExtensibleOfT<OpenApiResponse>
|
||||
{
|
||||
}
|
||||
}
|
343
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiSchema.cs
Normal file
343
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiSchema.cs
Normal file
|
@ -0,0 +1,343 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiSchema.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.Diagnostics;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Schema Object.
|
||||
/// </summary>
|
||||
internal class OpenApiSchema : IOpenApiElement, IOpenApiWritable, IOpenApiReferencable, IOpenApiExtensible
|
||||
{
|
||||
/// <summary>
|
||||
/// Title
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MultipleOf
|
||||
/// </summary>
|
||||
public decimal? MultipleOf { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximumn
|
||||
/// </summary>
|
||||
public decimal? Maximum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ExclusiveMaximum
|
||||
/// </summary>
|
||||
public bool? ExclusiveMaximum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum
|
||||
/// </summary>
|
||||
public decimal? Minimum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ExclusiveMinimum
|
||||
/// </summary>
|
||||
public bool? ExclusiveMinimum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MaxLength
|
||||
/// </summary>
|
||||
public int? MaxLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MinLength
|
||||
/// </summary>
|
||||
public int? MinLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pattern
|
||||
/// </summary>
|
||||
public string Pattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MaxItems
|
||||
/// </summary>
|
||||
public int? MaxItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MinItems
|
||||
/// </summary>
|
||||
public int? MinItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// UniqueItems
|
||||
/// </summary>
|
||||
public bool? UniqueItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MaxProperties
|
||||
/// </summary>
|
||||
public int? MaxProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// MinProperties
|
||||
/// </summary>
|
||||
public int? MinProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Required.
|
||||
/// </summary>
|
||||
public IList<string> Required { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enum
|
||||
/// </summary>
|
||||
public IList<string> Enum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Type
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AllOf
|
||||
/// </summary>
|
||||
public List<OpenApiSchema> AllOf { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OneOf
|
||||
/// </summary>
|
||||
public List<OpenApiSchema> OneOf { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AnyOf
|
||||
/// </summary>
|
||||
public List<OpenApiSchema> AnyOf { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Not
|
||||
/// </summary>
|
||||
public IList<OpenApiSchema> Not { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Items
|
||||
/// </summary>
|
||||
public OpenApiSchema Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Properties
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiSchema> Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AdditionalProperties
|
||||
/// </summary>
|
||||
public OpenApiSchema AdditionalProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Description
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Format
|
||||
/// </summary>
|
||||
public string Format { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default
|
||||
/// </summary>
|
||||
public string Default { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allows sending a null value for the defined schema. Default value is false.
|
||||
/// </summary>
|
||||
public bool? Nullable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The discriminator is an object name that is used to differentiate
|
||||
/// between other schemas which may satisfy the payload description.
|
||||
/// </summary>
|
||||
public OpenApiDiscriminator Discriminator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Read only.
|
||||
/// </summary>
|
||||
public bool? ReadOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write only.
|
||||
/// </summary>
|
||||
public bool? WriteOnly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Xml object.
|
||||
/// </summary>
|
||||
public OpenApiXml Xml { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional external documentation for this schema.
|
||||
/// </summary>
|
||||
public OpenApiExternalDocs ExternalDocs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A free-form property to include an example of an instance for this schema.
|
||||
/// </summary>
|
||||
public OpenApiAny Example { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that a schema is deprecated and SHOULD be transitioned out of usage.
|
||||
/// </summary>
|
||||
public bool? Deprecated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference Object.
|
||||
/// </summary>
|
||||
public OpenApiReference Reference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write schema object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (Reference != null)
|
||||
{
|
||||
Reference.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInternal(writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteInternal(IOpenApiWriter writer)
|
||||
{
|
||||
Debug.Assert(writer != null);
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// type
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocType, Type);
|
||||
|
||||
// title
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocTitle, Title);
|
||||
|
||||
// multipleOf
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMultipleOf, MultipleOf);
|
||||
|
||||
// Pattern
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocPattern, Pattern);
|
||||
|
||||
// MaxItems
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMaxItems, MaxItems);
|
||||
|
||||
// MinItems
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMinItems, MinItems);
|
||||
|
||||
// UniqueItems
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocUniqueItems, UniqueItems);
|
||||
|
||||
// MaxProperties
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMaxProperties, MaxProperties);
|
||||
|
||||
// MinProperties
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMinProperties, MinProperties);
|
||||
|
||||
// Required
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocRequired, Required);
|
||||
|
||||
// enum
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocEnum, Enum);
|
||||
|
||||
// AllOf
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocAllOf, AllOf);
|
||||
|
||||
// OneOf
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocOneOf, OneOf);
|
||||
|
||||
// AnyOf
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocAnyOf, AnyOf);
|
||||
|
||||
// Not
|
||||
writer.WriteOptionalCollection(OpenApiConstants.OpenApiDocNot, Not);
|
||||
|
||||
// Items
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocItems, Items);
|
||||
|
||||
// Properties
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocProperties, Properties);
|
||||
|
||||
// AdditionalProperties
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocAdditionalProperties, AdditionalProperties);
|
||||
|
||||
// Description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// Format
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocFormat, Format);
|
||||
|
||||
// Maximum
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMaximum, Maximum);
|
||||
|
||||
// exclusiveMaximum
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocExclusiveMaximum, ExclusiveMaximum);
|
||||
|
||||
// Minimum
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMinimum, Minimum);
|
||||
|
||||
// exclusiveMinimum
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocExclusiveMinimum, ExclusiveMinimum);
|
||||
|
||||
// MaxLength
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMaxLength, MaxLength);
|
||||
|
||||
// MaxLength
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocMinLength, MinLength);
|
||||
|
||||
// Default
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDefault, Default);
|
||||
|
||||
// nullable
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocNullable, Nullable);
|
||||
|
||||
// Discriminator
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocDiscriminator, Discriminator);
|
||||
|
||||
// ReadOnly
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocReadOnly, ReadOnly);
|
||||
|
||||
// WriteOnly
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocWriteOnly, WriteOnly);
|
||||
|
||||
// XML
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocXml, Xml);
|
||||
|
||||
// ExternalDocs
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExternalDocs, ExternalDocs);
|
||||
|
||||
// Example
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExample, Example);
|
||||
|
||||
// Deprecated
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDeprecated, Deprecated);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiSecurity.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal class OpenApiSecurity : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the tag.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A short description for the tag.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional external documentation for this tag.
|
||||
/// </summary>
|
||||
public OpenApiExternalDocs ExternalDocs { get; set; }
|
||||
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiSecurityRequirement.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Security Requirement Object
|
||||
/// </summary>
|
||||
internal class OpenApiSecurityRequirement : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiSecuritySchema.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of the security scheme.
|
||||
/// </summary>
|
||||
internal enum SecuritySchemaType
|
||||
{
|
||||
/// <summary>
|
||||
/// apiKey
|
||||
/// </summary>
|
||||
apiKey,
|
||||
|
||||
/// <summary>
|
||||
/// http
|
||||
/// </summary>
|
||||
http,
|
||||
|
||||
/// <summary>
|
||||
/// oauth2
|
||||
/// </summary>
|
||||
oauth2,
|
||||
|
||||
/// <summary>
|
||||
/// openIdConnect
|
||||
/// </summary>
|
||||
openIdConnect
|
||||
}
|
||||
|
||||
internal enum SecuritySchemaLocation
|
||||
{
|
||||
/// <summary>
|
||||
/// query
|
||||
/// </summary>
|
||||
query,
|
||||
|
||||
/// <summary>
|
||||
/// header
|
||||
/// </summary>
|
||||
header,
|
||||
|
||||
/// <summary>
|
||||
/// cookie
|
||||
/// </summary>
|
||||
cookie
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Security Scheme Object.
|
||||
/// </summary>
|
||||
internal class OpenApiSecuritySchema : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED. The type of the security scheme.
|
||||
/// </summary>
|
||||
public SecuritySchemaType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A short description for security schema.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The name of the header, query or cookie parameter to be used.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The location of the API key.
|
||||
/// </summary>
|
||||
public SecuritySchemaLocation In { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. The name of the HTTP Authorization scheme to be used in the Authorization header as defined in RFC7235.
|
||||
/// </summary>
|
||||
public string Scheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A hint to the client to identify how the bearer token is formatted.
|
||||
/// </summary>
|
||||
public string BearerFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED.An object containing configuration information for the flow types supported.
|
||||
/// </summary>
|
||||
public OpenApiOAuthFlows Flows { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// REQUIRED. OpenId Connect URL to discover OAuth2 configuration values.
|
||||
/// </summary>
|
||||
public Uri OpenIdConnectUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Any object to the given writer.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for json, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for json, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
69
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiServer.cs
Normal file
69
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiServer.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiServer.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Server Object: an object representing a Server.
|
||||
/// </summary>
|
||||
internal class OpenApiServer : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// A URL to the target host. This URL supports Server Variables and MAY be relative,
|
||||
/// to indicate that the host location is relative to the location
|
||||
/// where the OpenAPI document is being served
|
||||
/// </summary>
|
||||
public Uri Url { get; set; } = OpenApiConstants.OpenApiDocDefaultUrl;
|
||||
|
||||
/// <summary>
|
||||
/// An optional string describing the host designated by the URL.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map between a variable name and its value.
|
||||
/// </summary>
|
||||
public IDictionary<string, OpenApiServerVariable> Variables { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API server object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API Writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for JSON, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// name
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocUrl, Url.OriginalString);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// variables
|
||||
writer.WriteOptionalDictionary(OpenApiConstants.OpenApiDocVariables, Variables);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for JSON, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiServerVariable.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Server Variable Object.
|
||||
/// </summary>
|
||||
internal class OpenApiServerVariable : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// REQUIRED. The default value to use for substitution, and to send,
|
||||
/// if an alternate value is not supplied.
|
||||
/// </summary>
|
||||
public string Default { get; set; } = OpenApiConstants.OpenApiDocDefaultDefault;
|
||||
|
||||
/// <summary>
|
||||
/// An optional description for the server variable.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An enumeration of string values to be used if the substitution options are from a limited set.
|
||||
/// </summary>
|
||||
public IList<string> Enums { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API server variable object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API Writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for JSON, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// default
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocDefault, Default);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// enums
|
||||
if (Enums != null && Enums.Any())
|
||||
{
|
||||
writer.WritePropertyName(OpenApiConstants.OpenApiDocEnum);
|
||||
writer.WriteStartArray();
|
||||
foreach(string item in Enums)
|
||||
{
|
||||
writer.WriteValue(item);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for JSON, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
66
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiTag.cs
Normal file
66
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiTag.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiTag.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Tag Object.
|
||||
/// </summary>
|
||||
internal class OpenApiTag : IOpenApiElement, IOpenApiExtensible, IOpenApiWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the tag.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = OpenApiConstants.OpenApiDocDefaultName;
|
||||
|
||||
/// <summary>
|
||||
/// A short description for the tag.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional external documentation for this tag.
|
||||
/// </summary>
|
||||
public OpenApiExternalDocs ExternalDocs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This object MAY be extended with Specification Extensions.
|
||||
/// </summary>
|
||||
public IList<OpenApiExtension> Extensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Write Open API tag object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API Writer.</param>
|
||||
public virtual void Write(IOpenApiWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
// { for JSON, empty for YAML
|
||||
writer.WriteStartObject();
|
||||
|
||||
// name
|
||||
writer.WriteRequiredProperty(OpenApiConstants.OpenApiDocName, Name);
|
||||
|
||||
// description
|
||||
writer.WriteOptionalProperty(OpenApiConstants.OpenApiDocDescription, Description);
|
||||
|
||||
// External Docs
|
||||
writer.WriteOptionalObject(OpenApiConstants.OpenApiDocExternalDocs, ExternalDocs);
|
||||
|
||||
// specification extensions
|
||||
writer.WriteDictionary(Extensions);
|
||||
|
||||
// } for JSON, empty for YAML
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiTypeKind.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Type kind in the Open Api Specification.
|
||||
/// </summary>
|
||||
internal enum OpenApiTypeKind
|
||||
{
|
||||
/// <summary>
|
||||
/// None.
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "none")]
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Array
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "array")]
|
||||
Array,
|
||||
|
||||
/// <summary>
|
||||
/// Object
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "object")]
|
||||
Object,
|
||||
|
||||
/// <summary>
|
||||
/// String
|
||||
/// </summary>
|
||||
[OpenApiDataTypeMetadata(CommonName = "string")]
|
||||
String,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for Open Api Type kind.
|
||||
/// </summary>
|
||||
internal static class OpenApiTypeKindExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the Common Name.
|
||||
/// </summary>
|
||||
/// <param name="kind">The Open Api type kind.</param>
|
||||
/// <returns>The Common Name.</returns>
|
||||
public static string GetDisplayName(this OpenApiTypeKind kind)
|
||||
{
|
||||
OpenApiDataTypeMetadataAttribute attribute = kind.GetAttributeOfType<OpenApiDataTypeMetadataAttribute>();
|
||||
return attribute?.CommonName;
|
||||
}
|
||||
}
|
||||
}
|
15
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiXml.cs
Normal file
15
src/Microsoft.OpenApi.OData.Reader/OpenApi/OpenApiXml.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiXml.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal class OpenApiXml : IOpenApiElement, IOpenApiWritable
|
||||
{
|
||||
public void Write(IOpenApiWriter writer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
44
src/Microsoft.OpenApi.OData.Reader/OpenApiException.cs
Normal file
44
src/Microsoft.OpenApi.OData.Reader/OpenApiException.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiException.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception type representing exceptions in the Open API library.
|
||||
/// </summary>
|
||||
public class OpenApiException : InvalidOperationException
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="OpenApiException" /> class with default values.
|
||||
/// </summary>
|
||||
public OpenApiException()
|
||||
: this(SRResource.OpenApiExceptionGeneralError)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="OpenApiException" /> class with an error message.
|
||||
/// </summary>
|
||||
/// <param name="message">The plain text error message for this exception.</param>
|
||||
public OpenApiException(string message)
|
||||
: this(message, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="OpenApiException" /> class with an error message and an inner exception.
|
||||
/// </summary>
|
||||
/// <param name="message">The plain text error message for this exception.</param>
|
||||
/// <param name="innerException">The inner exception that is the cause of this exception to be thrown.</param>
|
||||
public OpenApiException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
24
src/Microsoft.OpenApi.OData.Reader/OpenApiTarget.cs
Normal file
24
src/Microsoft.OpenApi.OData.Reader/OpenApiTarget.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiTarget.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies what target of an Open API doc.
|
||||
/// </summary>
|
||||
public enum OpenApiTarget
|
||||
{
|
||||
/// <summary>
|
||||
/// The target is Open API version 3.0 JSON.
|
||||
/// </summary>
|
||||
Json,
|
||||
|
||||
/// <summary>
|
||||
/// The target is Open API version 3.0 YAML.
|
||||
/// </summary>
|
||||
Yaml
|
||||
}
|
||||
}
|
20
src/Microsoft.OpenApi.OData.Reader/OpenApiWriterSettings.cs
Normal file
20
src/Microsoft.OpenApi.OData.Reader/OpenApiWriterSettings.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiWriterSettings.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration settings for OData to Open API writers.
|
||||
/// </summary>
|
||||
public sealed class OpenApiWriterSettings
|
||||
{
|
||||
public Uri BaseUri { get; set; } = new Uri("http://localhost");
|
||||
|
||||
public Version Version { get; set; } = new Version(1, 0, 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="AssemblyInfo.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.OpenAPI.OData.Reader.Tests")]
|
144
src/Microsoft.OpenApi.OData.Reader/Properties/SRResource.Designer.cs
generated
Normal file
144
src/Microsoft.OpenApi.OData.Reader/Properties/SRResource.Designer.cs
generated
Normal file
|
@ -0,0 +1,144 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class SRResource {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal SRResource() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.OData.OpenAPI.Properties.SRResource", typeof(SRResource).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The argument '{0}' is null or empty..
|
||||
/// </summary>
|
||||
internal static string ArgumentNullOrEmpty {
|
||||
get {
|
||||
return ResourceManager.GetString("ArgumentNullOrEmpty", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The filed name of extension doesn't begin with x-..
|
||||
/// </summary>
|
||||
internal static string ExtensionFieldNameMustBeginWithXMinus {
|
||||
get {
|
||||
return ResourceManager.GetString("ExtensionFieldNameMustBeginWithXMinus", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An error occurred while processing the OData message..
|
||||
/// </summary>
|
||||
internal static string OpenApiExceptionGeneralError {
|
||||
get {
|
||||
return ResourceManager.GetString("OpenApiExceptionGeneralError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The object element name '{0}' is required..
|
||||
/// </summary>
|
||||
internal static string OpenApiObjectElementIsRequired {
|
||||
get {
|
||||
return ResourceManager.GetString("OpenApiObjectElementIsRequired", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The OpenApi element '{0}' is already marked as reference object..
|
||||
/// </summary>
|
||||
internal static string OpenApiObjectMarkAsReference {
|
||||
get {
|
||||
return ResourceManager.GetString("OpenApiObjectMarkAsReference", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to If the parameter location is "path", this property is REQUIRED and its value MUST be true.
|
||||
/// </summary>
|
||||
internal static string OpenApiParameterRequiredPropertyMandatory {
|
||||
get {
|
||||
return ResourceManager.GetString("OpenApiParameterRequiredPropertyMandatory", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The type '{0}' is not supported in Open API document..
|
||||
/// </summary>
|
||||
internal static string OpenApiUnsupportedValueType {
|
||||
get {
|
||||
return ResourceManager.GetString("OpenApiUnsupportedValueType", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The active scope must be an object scope for name '{0}' to be written..
|
||||
/// </summary>
|
||||
internal static string OpenApiWriterMustBeObjectScope {
|
||||
get {
|
||||
return ResourceManager.GetString("OpenApiWriterMustBeObjectScope", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to There must be an active scope for name '{0}' to be written..
|
||||
/// </summary>
|
||||
internal static string OpenApiWriterMustHaveActiveScope {
|
||||
get {
|
||||
return ResourceManager.GetString("OpenApiWriterMustHaveActiveScope", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
147
src/Microsoft.OpenApi.OData.Reader/Properties/SRResource.resx
Normal file
147
src/Microsoft.OpenApi.OData.Reader/Properties/SRResource.resx
Normal file
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ArgumentNullOrEmpty" xml:space="preserve">
|
||||
<value>The argument '{0}' is null or empty.</value>
|
||||
</data>
|
||||
<data name="ExtensionFieldNameMustBeginWithXMinus" xml:space="preserve">
|
||||
<value>The filed name of extension doesn't begin with x-.</value>
|
||||
</data>
|
||||
<data name="OpenApiExceptionGeneralError" xml:space="preserve">
|
||||
<value>An error occurred while processing the OData message.</value>
|
||||
</data>
|
||||
<data name="OpenApiObjectElementIsRequired" xml:space="preserve">
|
||||
<value>The object element name '{0}' is required.</value>
|
||||
</data>
|
||||
<data name="OpenApiObjectMarkAsReference" xml:space="preserve">
|
||||
<value>The OpenApi element '{0}' is already marked as reference object.</value>
|
||||
</data>
|
||||
<data name="OpenApiParameterRequiredPropertyMandatory" xml:space="preserve">
|
||||
<value>If the parameter location is "path", this property is REQUIRED and its value MUST be true</value>
|
||||
</data>
|
||||
<data name="OpenApiUnsupportedValueType" xml:space="preserve">
|
||||
<value>The type '{0}' is not supported in Open API document.</value>
|
||||
</data>
|
||||
<data name="OpenApiWriterMustBeObjectScope" xml:space="preserve">
|
||||
<value>The active scope must be an object scope for name '{0}' to be written.</value>
|
||||
</data>
|
||||
<data name="OpenApiWriterMustHaveActiveScope" xml:space="preserve">
|
||||
<value>There must be an active scope for name '{0}' to be written.</value>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,16 @@
|
|||
using Microsoft.OData.OpenAPI.Properties;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
internal static class OpenApiElementValidator
|
||||
{
|
||||
public static void ValidateReference(this IOpenApiReferencable reference)
|
||||
{
|
||||
if (reference != null && reference.Reference != null)
|
||||
{
|
||||
throw new OpenApiException(String.Format(SRResource.OpenApiObjectMarkAsReference, reference.GetType().Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
74
src/Microsoft.OpenApi.OData.Reader/Writer/IOpenApiWriter.cs
Normal file
74
src/Microsoft.OpenApi.OData.Reader/Writer/IOpenApiWriter.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="IOpenApiWriter.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for writing Open API documentation.
|
||||
/// </summary>
|
||||
public interface IOpenApiWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Write the start object.
|
||||
/// </summary>
|
||||
void WriteStartObject();
|
||||
|
||||
/// <summary>
|
||||
/// Write the end object.
|
||||
/// </summary>
|
||||
void WriteEndObject();
|
||||
|
||||
/// <summary>
|
||||
/// Write the start array.
|
||||
/// </summary>
|
||||
void WriteStartArray();
|
||||
|
||||
/// <summary>
|
||||
/// Write the end array.
|
||||
/// </summary>
|
||||
void WriteEndArray();
|
||||
|
||||
/// <summary>
|
||||
/// Write the property name.
|
||||
/// </summary>
|
||||
void WritePropertyName(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Write the string value.
|
||||
/// </summary>
|
||||
void WriteValue(string value);
|
||||
|
||||
/// <summary>
|
||||
/// Write the decimal value.
|
||||
/// </summary>
|
||||
void WriteValue(decimal value);
|
||||
|
||||
/// <summary>
|
||||
/// Write the int value.
|
||||
/// </summary>
|
||||
void WriteValue(int value);
|
||||
|
||||
/// <summary>
|
||||
/// Write the boolean value.
|
||||
/// </summary>
|
||||
void WriteValue(bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Write the null value.
|
||||
/// </summary>
|
||||
void WriteNull();
|
||||
|
||||
/// <summary>
|
||||
/// Write the object value.
|
||||
/// </summary>
|
||||
void WriteValue(object value);
|
||||
|
||||
/// <summary>
|
||||
/// Flush the writer.
|
||||
/// </summary>
|
||||
void Flush();
|
||||
}
|
||||
}
|
177
src/Microsoft.OpenApi.OData.Reader/Writer/OpenApiJsonWriter.cs
Normal file
177
src/Microsoft.OpenApi.OData.Reader/Writer/OpenApiJsonWriter.cs
Normal file
|
@ -0,0 +1,177 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiJsonWriter.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// JSON Writer.
|
||||
/// </summary>
|
||||
internal class OpenApiJsonWriter : OpenApiWriterBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiJsonWriter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="textWriter">The text writer.</param>
|
||||
public OpenApiJsonWriter(TextWriter textWriter)
|
||||
: this(textWriter, new OpenApiWriterSettings())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiJsonWriter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="textWriter">The text writer.</param>
|
||||
/// <param name="settings">The writer settings.</param>
|
||||
public OpenApiJsonWriter(TextWriter textWriter, OpenApiWriterSettings settings)
|
||||
: base(textWriter, settings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write JSON start object.
|
||||
/// </summary>
|
||||
public override void WriteStartObject()
|
||||
{
|
||||
Scope preScope = CurrentScope();
|
||||
|
||||
StartScope(ScopeType.Object);
|
||||
|
||||
if (preScope != null && preScope.Type == ScopeType.Array)
|
||||
{
|
||||
Writer.WriteLine();
|
||||
WriteIndentation();
|
||||
}
|
||||
|
||||
Writer.Write(WriterConstants.StartObjectScope);
|
||||
IncreaseIndentation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write JSOn end object.
|
||||
/// </summary>
|
||||
public override void WriteEndObject()
|
||||
{
|
||||
Scope current = EndScope(ScopeType.Object);
|
||||
if (current.ObjectCount != 0)
|
||||
{
|
||||
Writer.WriteLine();
|
||||
DecreaseIndentation();
|
||||
WriteIndentation();
|
||||
}
|
||||
else
|
||||
{
|
||||
Writer.Write(WriterConstants.WhiteSpaceForEmptyObjectArray);
|
||||
DecreaseIndentation();
|
||||
}
|
||||
|
||||
Writer.Write(WriterConstants.EndObjectScope);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write JSON start array.
|
||||
/// </summary>
|
||||
public override void WriteStartArray()
|
||||
{
|
||||
StartScope(ScopeType.Array);
|
||||
this.Writer.Write(WriterConstants.StartArrayScope);
|
||||
IncreaseIndentation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write JSON end array.
|
||||
/// </summary>
|
||||
public override void WriteEndArray()
|
||||
{
|
||||
Scope current = EndScope(ScopeType.Array);
|
||||
if (current.ObjectCount != 0)
|
||||
{
|
||||
Writer.WriteLine();
|
||||
DecreaseIndentation();
|
||||
WriteIndentation();
|
||||
}
|
||||
else
|
||||
{
|
||||
Writer.Write(WriterConstants.WhiteSpaceForEmptyObjectArray);
|
||||
DecreaseIndentation();
|
||||
}
|
||||
|
||||
Writer.Write(WriterConstants.EndArrayScope);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write property name.
|
||||
/// </summary>
|
||||
/// <param name="name">The property name.</param>
|
||||
/// public override void WritePropertyName(string name)
|
||||
public override void WritePropertyName(string name)
|
||||
{
|
||||
ValifyCanWritePropertyName(name);
|
||||
|
||||
Scope currentScope = CurrentScope();
|
||||
if (currentScope.ObjectCount != 0)
|
||||
{
|
||||
Writer.Write(WriterConstants.ObjectMemberSeparator);
|
||||
}
|
||||
Writer.WriteLine();
|
||||
|
||||
currentScope.ObjectCount++;
|
||||
|
||||
// JsonValueUtils.WriteEscapedJsonString(this.writer, name);
|
||||
WriteIndentation();
|
||||
|
||||
Writer.Write(WriterConstants.QuoteCharacter);
|
||||
Writer.Write(name);
|
||||
Writer.Write(WriterConstants.QuoteCharacter);
|
||||
Writer.Write(WriterConstants.NameValueSeparator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string value.
|
||||
/// </summary>
|
||||
/// <param name="value">The string value.</param>
|
||||
public override void WriteValue(string value)
|
||||
{
|
||||
WriteValueSeparator();
|
||||
|
||||
value = value.Replace("\n", "\\n");
|
||||
|
||||
Writer.Write(WriterConstants.QuoteCharacter);
|
||||
Writer.Write(value);
|
||||
Writer.Write(WriterConstants.QuoteCharacter);
|
||||
}
|
||||
|
||||
public override void WriteNull()
|
||||
{
|
||||
Writer.Write("null");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a separator of a value if it's needed for the next value to be written.
|
||||
/// </summary>
|
||||
protected override void WriteValueSeparator()
|
||||
{
|
||||
if (scopes.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Scope currentScope = this.scopes.Peek();
|
||||
if (currentScope.Type == ScopeType.Array)
|
||||
{
|
||||
if (currentScope.ObjectCount != 0)
|
||||
{
|
||||
Writer.Write(WriterConstants.ArrayElementSeparator);
|
||||
}
|
||||
|
||||
Writer.WriteLine();
|
||||
WriteIndentation();
|
||||
currentScope.ObjectCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
309
src/Microsoft.OpenApi.OData.Reader/Writer/OpenApiWriterBase.cs
Normal file
309
src/Microsoft.OpenApi.OData.Reader/Writer/OpenApiWriterBase.cs
Normal file
|
@ -0,0 +1,309 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiWriterBase.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.Diagnostics;
|
||||
using System.IO;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for Open API writer.
|
||||
/// </summary>
|
||||
internal abstract class OpenApiWriterBase : IOpenApiWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// The indentation string to prepand to each line for each indentation level.
|
||||
/// </summary>
|
||||
private const string IndentationString = " ";
|
||||
|
||||
/// <summary>
|
||||
/// Number which specifies the level of indentation. Starts with 0 which means no indentation.
|
||||
/// </summary>
|
||||
private int indentLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Scope of the Open API element - object, array, property.
|
||||
/// </summary>
|
||||
protected readonly Stack<Scope> scopes;
|
||||
|
||||
/// <summary>
|
||||
/// Number which specifies the level of indentation. Starts with 0 which means no indentation.
|
||||
/// </summary>
|
||||
private OpenApiWriterSettings settings;
|
||||
|
||||
/// <summary>
|
||||
/// Indentent shift value.
|
||||
/// </summary>
|
||||
protected virtual int IndentShift { get { return 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// The text writer.
|
||||
/// </summary>
|
||||
protected TextWriter Writer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiWriterBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="textWriter">The text writer.</param>
|
||||
/// <param name="settings">The writer settings.</param>
|
||||
public OpenApiWriterBase(TextWriter textWriter, OpenApiWriterSettings settings)
|
||||
{
|
||||
Writer = textWriter;
|
||||
Writer.NewLine = "\n";
|
||||
|
||||
this.scopes = new Stack<Scope>();
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write start object.
|
||||
/// </summary>
|
||||
public abstract void WriteStartObject();
|
||||
|
||||
/// <summary>
|
||||
/// Write end object.
|
||||
/// </summary>
|
||||
public abstract void WriteEndObject();
|
||||
|
||||
/// <summary>
|
||||
/// Write start array.
|
||||
/// </summary>
|
||||
public abstract void WriteStartArray();
|
||||
|
||||
/// <summary>
|
||||
/// Write end array.
|
||||
/// </summary>
|
||||
public abstract void WriteEndArray();
|
||||
|
||||
/// <summary>
|
||||
/// Write the start property.
|
||||
/// </summary>
|
||||
public abstract void WritePropertyName(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Writes a separator of a value if it's needed for the next value to be written.
|
||||
/// </summary>
|
||||
protected abstract void WriteValueSeparator();
|
||||
|
||||
/// <summary>
|
||||
/// Write null value.
|
||||
/// </summary>
|
||||
public abstract void WriteNull();
|
||||
|
||||
/// <summary>
|
||||
/// Flush the writer.
|
||||
/// </summary>
|
||||
public void Flush()
|
||||
{
|
||||
this.Writer.Flush();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string value.
|
||||
/// </summary>
|
||||
/// <param name="value">The string value.</param>
|
||||
public abstract void WriteValue(string value);
|
||||
|
||||
/// <summary>
|
||||
/// Write decimal value.
|
||||
/// </summary>
|
||||
/// <param name="value">The decimal value.</param>
|
||||
public virtual void WriteValue(decimal value)
|
||||
{
|
||||
WriteValueSeparator();
|
||||
Writer.Write(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write integer value.
|
||||
/// </summary>
|
||||
/// <param name="value">The integer value.</param>
|
||||
public virtual void WriteValue(int value)
|
||||
{
|
||||
WriteValueSeparator();
|
||||
Writer.Write(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write boolean value.
|
||||
/// </summary>
|
||||
/// <param name="value">The boolean value.</param>
|
||||
public virtual void WriteValue(bool value)
|
||||
{
|
||||
WriteValueSeparator();
|
||||
Writer.Write(value.ToString().ToLower());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write object value.
|
||||
/// </summary>
|
||||
/// <param name="value">The object value.</param>
|
||||
public virtual void WriteValue(object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull();
|
||||
return;
|
||||
}
|
||||
|
||||
Type type = value.GetType();
|
||||
|
||||
if (type == typeof(string))
|
||||
{
|
||||
WriteValue((String)(value));
|
||||
}
|
||||
else if (type == typeof(int) || type == typeof(int?))
|
||||
{
|
||||
WriteValue((int)value);
|
||||
}
|
||||
else if (type == typeof(bool) || type == typeof(bool?))
|
||||
{
|
||||
WriteValue((bool)value);
|
||||
}
|
||||
else if (type == typeof(decimal) || type == typeof(decimal))
|
||||
{
|
||||
WriteValue((decimal)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new OpenApiException(String.Format(SRResource.OpenApiUnsupportedValueType, type.FullName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the level of indentation applied to the output.
|
||||
/// </summary>
|
||||
public virtual void IncreaseIndentation()
|
||||
{
|
||||
indentLevel++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Decreases the level of indentation applied to the output.
|
||||
/// </summary>
|
||||
public virtual void DecreaseIndentation()
|
||||
{
|
||||
Debug.Assert(indentLevel > 0, "Trying to decrease indentation below zero.");
|
||||
if (indentLevel < 1)
|
||||
{
|
||||
indentLevel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the indentation.
|
||||
/// </summary>
|
||||
public virtual void WriteIndentation()
|
||||
{
|
||||
for (int i = 0; i < (indentLevel + IndentShift); i++)
|
||||
{
|
||||
Writer.Write(IndentationString);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void WritePrefixIndentation()
|
||||
{
|
||||
for (int i = 0; i < (indentLevel + IndentShift - 1); i++)
|
||||
{
|
||||
Writer.Write(IndentationString);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get current scope.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected Scope CurrentScope()
|
||||
{
|
||||
return scopes.Count == 0 ? null : scopes.Peek();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start the scope given the scope type.
|
||||
/// </summary>
|
||||
/// <param name="type">The scope type to start.</param>
|
||||
protected Scope StartScope(ScopeType type)
|
||||
{
|
||||
if (scopes.Count != 0)
|
||||
{
|
||||
Scope currentScope = this.scopes.Peek();
|
||||
if ((currentScope.Type == ScopeType.Array) &&
|
||||
(currentScope.ObjectCount != 0))
|
||||
{
|
||||
Writer.Write(WriterConstants.ArrayElementSeparator);
|
||||
}
|
||||
|
||||
currentScope.ObjectCount++;
|
||||
}
|
||||
|
||||
Scope scope = new Scope(type);
|
||||
this.scopes.Push(scope);
|
||||
return scope;
|
||||
}
|
||||
|
||||
protected Scope EndScope(ScopeType type)
|
||||
{
|
||||
Debug.Assert(scopes.Count > 0, "No scope to end.");
|
||||
Debug.Assert(scopes.Peek().Type == type, "Ending scope does not match.");
|
||||
return scopes.Pop();
|
||||
}
|
||||
|
||||
protected bool IsTopLevelObjectScope()
|
||||
{
|
||||
if (scopes.Count != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return scopes.Peek().Type == ScopeType.Object;
|
||||
}
|
||||
|
||||
protected bool IsObjectScope()
|
||||
{
|
||||
return IsScopeType(ScopeType.Object);
|
||||
}
|
||||
|
||||
protected bool IsArrayScope()
|
||||
{
|
||||
return IsScopeType(ScopeType.Array);
|
||||
}
|
||||
|
||||
private bool IsScopeType(ScopeType type)
|
||||
{
|
||||
if (scopes.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return scopes.Peek().Type == type;
|
||||
}
|
||||
|
||||
protected void ValifyCanWritePropertyName(string name)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw Error.ArgumentNullOrEmpty(nameof(name));
|
||||
}
|
||||
|
||||
if (this.scopes.Count == 0)
|
||||
{
|
||||
throw new OpenApiException(String.Format(SRResource.OpenApiWriterMustHaveActiveScope, name));
|
||||
}
|
||||
|
||||
if (this.scopes.Peek().Type != ScopeType.Object)
|
||||
{
|
||||
throw new OpenApiException(String.Format(SRResource.OpenApiWriterMustBeObjectScope, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,370 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiWriterExtensions.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;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for writing Open API documentation.
|
||||
/// </summary>
|
||||
internal static class OpenApiWriterExtensions
|
||||
{
|
||||
public static void WriteRequiredProperty(this IOpenApiWriter writer, string name, string value)
|
||||
{
|
||||
writer.WritePropertyInternal(name, value);
|
||||
}
|
||||
|
||||
public static void WriteOptionalProperty(this IOpenApiWriter writer, string name, string element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePropertyInternal(name, element);
|
||||
}
|
||||
|
||||
public static void WriteRequiredProperty<T>(this IOpenApiWriter writer, string name, T value)
|
||||
where T: struct
|
||||
{
|
||||
writer.WritePropertyInternal(name, value);
|
||||
}
|
||||
|
||||
public static void WriteRequiredProperty<T>(this IOpenApiWriter writer, string name, T? value)
|
||||
where T : struct
|
||||
{
|
||||
writer.WritePropertyInternal(name, value);
|
||||
}
|
||||
|
||||
public static void WriteOptionalProperty<T>(this IOpenApiWriter writer, string name, T? value)
|
||||
where T : struct
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePropertyInternal(name, value.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the single of Open API element.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API writer.</param>
|
||||
/// <param name="name">The property name.</param>
|
||||
/// <param name="value">The Open API element.</param>
|
||||
public static void WriteRequiredObject(this IOpenApiWriter writer, string name, IOpenApiWritable value)
|
||||
{
|
||||
writer.WritePropertyInternal(name, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the single of Open API element if the element is not null, otherwise skip it.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API writer.</param>
|
||||
/// <param name="name">The property name.</param>
|
||||
/// <param name="element">The Open API element.</param>
|
||||
public static void WriteOptionalObject(this IOpenApiWriter writer, string name, IOpenApiWritable element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePropertyInternal(name, element);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the collection of Open API element.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API writer.</param>
|
||||
/// <param name="name">The property name.</param>
|
||||
/// <param name="elements">The collection of Open API element.</param>
|
||||
public static void WriteRequiredCollection(this IOpenApiWriter writer, string name, IEnumerable<IOpenApiWritable> elements)
|
||||
{
|
||||
writer.WriteCollectionInternal(name, elements);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the collection of Open API element optional.
|
||||
/// </summary>
|
||||
/// <param name="writer">The Open API writer.</param>
|
||||
/// <param name="name">The property name.</param>
|
||||
/// <param name="elements">The collection of Open API element.</param>
|
||||
public static void WriteOptionalCollection(this IOpenApiWriter writer, string name, IEnumerable<IOpenApiWritable> elements)
|
||||
{
|
||||
if (elements == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteCollectionInternal(name, elements);
|
||||
}
|
||||
|
||||
public static void WriteRequiredCollection(this IOpenApiWriter writer, string name, IEnumerable<string> elements)
|
||||
{
|
||||
writer.WriteCollectionInternal(name, elements);
|
||||
}
|
||||
|
||||
public static void WriteOptionalCollection(this IOpenApiWriter writer, string name, IEnumerable<string> elements)
|
||||
{
|
||||
if (elements == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteCollectionInternal(name, elements);
|
||||
}
|
||||
|
||||
public static void WriteRequiredDictionary<T>(this IOpenApiWriter writer, string name, IDictionary<string, T> elements)
|
||||
where T : IOpenApiWritable
|
||||
{
|
||||
writer.WriteDictionaryInternal(name, elements);
|
||||
}
|
||||
|
||||
public static void WriteOptionalDictionary<T>(this IOpenApiWriter writer, string name, IDictionary<string, T> elements)
|
||||
where T : IOpenApiWritable
|
||||
{
|
||||
if (elements == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteDictionaryInternal(name, elements);
|
||||
}
|
||||
|
||||
public static void WriteRequiredDictionary(this IOpenApiWriter writer, string name, IDictionary<string, string> elements)
|
||||
{
|
||||
writer.WriteDictionaryInternal(name, elements);
|
||||
}
|
||||
|
||||
public static void WriteOptionalDictionary(this IOpenApiWriter writer, string name, IDictionary<string, string> elements)
|
||||
{
|
||||
if (elements == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteDictionaryInternal(name, elements);
|
||||
}
|
||||
|
||||
public static void WriteDictionary(this IOpenApiWriter writer, IEnumerable<IOpenApiWritable> elements)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (elements == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (IOpenApiWritable e in elements)
|
||||
{
|
||||
e.Write(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the boolean property.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="name">The property name.</param>
|
||||
/// <param name="value">The property value.</param>
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
public static void WriteBooleanProperty(this IOpenApiWriter writer, string name, bool value, bool? defaultValue)
|
||||
{
|
||||
if (defaultValue != null && value == defaultValue.Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WriteProperty(name, () => writer.WriteValue(value));
|
||||
}
|
||||
|
||||
public static void WriteSingleProperty<T>(this IOpenApiWriter writer, string name, T value, T defaultValue = default(T), bool optional = true)
|
||||
{
|
||||
if (value.Equals(defaultValue))
|
||||
{
|
||||
if (!optional)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
writer.WritePropertyInternal(name, value);
|
||||
}
|
||||
|
||||
|
||||
public static void WriteSingleProperty(this IOpenApiWriter writer, string name, string value, bool optional = true)
|
||||
{
|
||||
if (value == null && !optional)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePropertyInternal(name, value);
|
||||
}
|
||||
|
||||
public static void WriteIntegerProperty(this IOpenApiWriter writer, string name, int? value, bool optional = true)
|
||||
{
|
||||
if (value == null && !optional)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write property with an action.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="name">The property name.</param>
|
||||
/// <param name="valueAction">The value action.</param>
|
||||
public static void WriteProperty(this IOpenApiWriter writer, string name,
|
||||
Action valueAction)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw Error.ArgumentNullOrEmpty("name");
|
||||
}
|
||||
|
||||
if (valueAction == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePropertyName(name);
|
||||
valueAction();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write an object with an action.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="objectAction">The object action.</param>
|
||||
public static void WriteObject(this IOpenApiWriter writer, Action objectAction)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (objectAction == null)
|
||||
{
|
||||
throw Error.ArgumentNull("valueAction");
|
||||
}
|
||||
|
||||
writer.WriteStartObject();
|
||||
|
||||
objectAction();
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write an array with an action.
|
||||
/// </summary>
|
||||
/// <param name="writer">The writer.</param>
|
||||
/// <param name="arrayAction">The array action.</param>
|
||||
public static void WriteArray(this IOpenApiWriter writer, Action arrayAction)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull("writer");
|
||||
}
|
||||
|
||||
if (arrayAction == null)
|
||||
{
|
||||
throw Error.ArgumentNull("valueAction");
|
||||
}
|
||||
|
||||
writer.WriteStartArray();
|
||||
arrayAction();
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
private static void WritePropertyInternal<T>(this IOpenApiWriter writer, string name, T element)
|
||||
{
|
||||
CheckArgument(writer, name);
|
||||
|
||||
writer.WritePropertyName(name);
|
||||
writer.WriteValueInternal(element);
|
||||
}
|
||||
|
||||
private static void WriteCollectionInternal<T>(this IOpenApiWriter writer, string name, IEnumerable<T> elements)
|
||||
{
|
||||
CheckArgument(writer, name);
|
||||
|
||||
writer.WritePropertyName(name);
|
||||
|
||||
writer.WriteStartArray();
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
foreach (T e in elements)
|
||||
{
|
||||
writer.WriteValueInternal(e);
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
private static void WriteDictionaryInternal<T>(this IOpenApiWriter writer, string name, IDictionary<string, T> elements)
|
||||
{
|
||||
CheckArgument(writer, name);
|
||||
|
||||
writer.WritePropertyName(name);
|
||||
|
||||
writer.WriteStartObject();
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, T> e in elements)
|
||||
{
|
||||
writer.WritePropertyName(e.Key);
|
||||
writer.WriteValueInternal(e.Value);
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
private static void WriteValueInternal<T>(this IOpenApiWriter writer, T value)
|
||||
{
|
||||
IOpenApiWritable writableElement = value as IOpenApiWritable;
|
||||
if (writableElement != null)
|
||||
{
|
||||
writableElement.Write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckArgument(IOpenApiWriter writer, string name)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw Error.ArgumentNull(nameof(writer));
|
||||
}
|
||||
|
||||
if (String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw Error.ArgumentNullOrEmpty(nameof(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
177
src/Microsoft.OpenApi.OData.Reader/Writer/OpenApiYamlWriter.cs
Normal file
177
src/Microsoft.OpenApi.OData.Reader/Writer/OpenApiYamlWriter.cs
Normal file
|
@ -0,0 +1,177 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiYamlWriter.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// YAML writer.
|
||||
/// </summary>
|
||||
internal class OpenApiYamlWriter : OpenApiWriterBase
|
||||
{
|
||||
protected override int IndentShift { get { return -1; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiYamlWriter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="textWriter">The text writer.</param>
|
||||
public OpenApiYamlWriter(TextWriter textWriter)
|
||||
: this(textWriter, new OpenApiWriterSettings())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenApiYamlWriter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="textWriter">The text writer.</param>
|
||||
/// <param name="settings">The writer settings.</param>
|
||||
public OpenApiYamlWriter(TextWriter textWriter, OpenApiWriterSettings settings)
|
||||
: base(textWriter, settings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write YAML start object.
|
||||
/// </summary>
|
||||
public override void WriteStartObject()
|
||||
{
|
||||
Scope preScope = CurrentScope();
|
||||
|
||||
Scope curScope = StartScope(ScopeType.Object);
|
||||
|
||||
IncreaseIndentation();
|
||||
|
||||
if (preScope != null && preScope.Type == ScopeType.Array)
|
||||
{
|
||||
curScope.IsInArray = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write YAML end object.
|
||||
/// </summary>
|
||||
public override void WriteEndObject()
|
||||
{
|
||||
Scope current = EndScope(ScopeType.Object);
|
||||
|
||||
/*
|
||||
if (current.ObjectCount == 0)
|
||||
{
|
||||
Writer.Write(WriterConstants.WhiteSpaceForEmptyObjectArray);
|
||||
}*/
|
||||
|
||||
DecreaseIndentation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write YAML start array.
|
||||
/// </summary>
|
||||
public override void WriteStartArray()
|
||||
{
|
||||
StartScope(ScopeType.Array);
|
||||
IncreaseIndentation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write YAML end array.
|
||||
/// </summary>
|
||||
public override void WriteEndArray()
|
||||
{
|
||||
Scope current = EndScope(ScopeType.Array);
|
||||
/*
|
||||
if (current.ObjectCount == 0)
|
||||
{
|
||||
Writer.Write(WriterConstants.WhiteSpaceForEmptyObjectArray);
|
||||
}*/
|
||||
DecreaseIndentation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the start property.
|
||||
/// </summary>
|
||||
public override void WritePropertyName(string name)
|
||||
{
|
||||
ValifyCanWritePropertyName(name);
|
||||
|
||||
Scope current = CurrentScope();
|
||||
|
||||
if (current.ObjectCount == 0)
|
||||
{
|
||||
if (current.IsInArray)
|
||||
{
|
||||
Writer.WriteLine();
|
||||
|
||||
WritePrefixIndentation();
|
||||
|
||||
Writer.Write(WriterConstants.PrefixOfArrayItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsTopLevelObjectScope())
|
||||
{
|
||||
Writer.WriteLine();
|
||||
}
|
||||
WriteIndentation();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Writer.WriteLine();
|
||||
WriteIndentation();
|
||||
}
|
||||
|
||||
Writer.Write(name);
|
||||
// writer.Write(WriterConstants.NameValueSeparator);
|
||||
Writer.Write(":");
|
||||
|
||||
++current.ObjectCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string value.
|
||||
/// </summary>
|
||||
/// <param name="value">The string value.</param>
|
||||
public override void WriteValue(string value)
|
||||
{
|
||||
WriteValueSeparator();
|
||||
|
||||
value = value.Replace("\n", "\\n");
|
||||
|
||||
if (value.StartsWith("#"))
|
||||
{
|
||||
value = "'" + value + "'";
|
||||
}
|
||||
|
||||
Writer.Write(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the empty scalar as “null”.
|
||||
/// </summary>
|
||||
public override void WriteNull()
|
||||
{
|
||||
WriteValueSeparator();
|
||||
// nothing here
|
||||
}
|
||||
|
||||
protected override void WriteValueSeparator()
|
||||
{
|
||||
if (IsArrayScope())
|
||||
{
|
||||
Writer.WriteLine();
|
||||
WriteIndentation();
|
||||
Writer.Write(WriterConstants.PrefixOfArrayItem);
|
||||
|
||||
CurrentScope().ObjectCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Writer.Write(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
69
src/Microsoft.OpenApi.OData.Reader/Writer/Scope.cs
Normal file
69
src/Microsoft.OpenApi.OData.Reader/Writer/Scope.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="Scope.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Various scope types for Open API writer.
|
||||
/// </summary>
|
||||
internal enum ScopeType
|
||||
{
|
||||
/// <summary>
|
||||
/// Object scope.
|
||||
/// </summary>
|
||||
Object = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Array scope.
|
||||
/// </summary>
|
||||
Array = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class representing scope information.
|
||||
/// </summary>
|
||||
internal sealed class Scope
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of the scope.
|
||||
/// </summary>
|
||||
private readonly ScopeType type;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of the scope.</param>
|
||||
public Scope(ScopeType type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the object count for this scope.
|
||||
/// </summary>
|
||||
public int ObjectCount
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scope type for this scope.
|
||||
/// </summary>
|
||||
public ScopeType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get/Set the whether it is in previous array scope.
|
||||
/// </summary>
|
||||
public bool IsInArray { get; set; } = false;
|
||||
}
|
||||
}
|
109
src/Microsoft.OpenApi.OData.Reader/Writer/WriterConstants.cs
Normal file
109
src/Microsoft.OpenApi.OData.Reader/Writer/WriterConstants.cs
Normal file
|
@ -0,0 +1,109 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="WriterConstants.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for the writer.
|
||||
/// </summary>
|
||||
internal static class WriterConstants
|
||||
{
|
||||
/// <summary>
|
||||
/// JSON datetime format.
|
||||
/// </summary>
|
||||
internal const string ODataDateTimeFormat = @"\/Date({0})\/";
|
||||
|
||||
/// <summary>
|
||||
/// JSON datetime offset format.
|
||||
/// </summary>
|
||||
internal const string ODataDateTimeOffsetFormat = @"\/Date({0}{1}{2:D4})\/";
|
||||
|
||||
/// <summary>
|
||||
/// A plus sign for the date time offset format.
|
||||
/// </summary>
|
||||
internal const string ODataDateTimeOffsetPlusSign = "+";
|
||||
|
||||
/// <summary>
|
||||
/// The true value literal.
|
||||
/// </summary>
|
||||
internal const string JsonTrueLiteral = "true";
|
||||
|
||||
/// <summary>
|
||||
/// The false value literal.
|
||||
/// </summary>
|
||||
internal const string JsonFalseLiteral = "false";
|
||||
|
||||
/// <summary>
|
||||
/// The null value literal.
|
||||
/// </summary>
|
||||
internal const string JsonNullLiteral = "null";
|
||||
|
||||
/// <summary>
|
||||
/// Character which starts the object scope.
|
||||
/// </summary>
|
||||
internal const string StartObjectScope = "{";
|
||||
|
||||
/// <summary>
|
||||
/// Character which ends the object scope.
|
||||
/// </summary>
|
||||
internal const string EndObjectScope = "}";
|
||||
|
||||
/// <summary>
|
||||
/// Character which starts the array scope.
|
||||
/// </summary>
|
||||
internal const string StartArrayScope = "[";
|
||||
|
||||
/// <summary>
|
||||
/// Character which ends the array scope.
|
||||
/// </summary>
|
||||
internal const string EndArrayScope = "]";
|
||||
|
||||
/// <summary>
|
||||
/// "(" Json Padding Function scope open parens.
|
||||
/// </summary>
|
||||
internal const string StartPaddingFunctionScope = "(";
|
||||
|
||||
/// <summary>
|
||||
/// ")" Json Padding Function scope close parens.
|
||||
/// </summary>
|
||||
internal const string EndPaddingFunctionScope = ")";
|
||||
|
||||
/// <summary>
|
||||
/// The separator between object members.
|
||||
/// </summary>
|
||||
internal const string ObjectMemberSeparator = ",";
|
||||
|
||||
/// <summary>
|
||||
/// The separator between array elements.
|
||||
/// </summary>
|
||||
internal const string ArrayElementSeparator = ",";
|
||||
|
||||
/// <summary>
|
||||
/// The separator between the name and the value.
|
||||
/// </summary>
|
||||
internal const string NameValueSeparator = ": ";
|
||||
|
||||
/// <summary>
|
||||
/// The quote character.
|
||||
/// </summary>
|
||||
internal const char QuoteCharacter = '"';
|
||||
|
||||
/// <summary>
|
||||
/// The white space for empty object & array
|
||||
/// </summary>
|
||||
internal const string WhiteSpaceForEmptyObjectArray = " ";
|
||||
|
||||
/// <summary>
|
||||
/// The prefix of array item
|
||||
/// </summary>
|
||||
internal const string PrefixOfArrayItem = "- ";
|
||||
|
||||
/// <summary>
|
||||
/// The white space for indent
|
||||
/// </summary>
|
||||
internal const string WhiteSpaceForIndent = " ";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmModelHelper.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Edm model helpers
|
||||
/// </summary>
|
||||
public static class EdmModelHelper
|
||||
{
|
||||
public static IEdmModel EmptyModel { get; } = new EdmModel();
|
||||
|
||||
public static IEdmModel BasicEdmModel { get; }
|
||||
|
||||
public static IEdmModel TripServiceModel { get; }
|
||||
|
||||
static EdmModelHelper()
|
||||
{
|
||||
BasicEdmModel = CreateEdmModel();
|
||||
TripServiceModel = LoadTripServiceModel();
|
||||
}
|
||||
|
||||
private static IEdmModel LoadTripServiceModel()
|
||||
{
|
||||
string csdl = Resources.GetString("TripService.OData.xml");
|
||||
return CsdlReader.Parse(XElement.Parse(csdl).CreateReader());
|
||||
}
|
||||
|
||||
private static IEdmModel CreateEdmModel()
|
||||
{
|
||||
var model = new EdmModel();
|
||||
|
||||
var enumType = new EdmEnumType("DefaultNs", "Color");
|
||||
var blue = enumType.AddMember("Blue", new EdmEnumMemberValue(0));
|
||||
enumType.AddMember("White", new EdmEnumMemberValue(1));
|
||||
model.AddElement(enumType);
|
||||
|
||||
var person = new EdmEntityType("DefaultNs", "Person");
|
||||
var entityId = person.AddStructuralProperty("UserName", EdmCoreModel.Instance.GetString(false));
|
||||
person.AddKeys(entityId);
|
||||
|
||||
var city = new EdmEntityType("DefaultNs", "City");
|
||||
var cityId = city.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
|
||||
city.AddKeys(cityId);
|
||||
|
||||
var countryOrRegion = new EdmEntityType("DefaultNs", "CountryOrRegion");
|
||||
var countryId = countryOrRegion.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
|
||||
countryOrRegion.AddKeys(countryId);
|
||||
|
||||
var complex = new EdmComplexType("DefaultNs", "Address");
|
||||
complex.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
|
||||
var navP = complex.AddUnidirectionalNavigation(
|
||||
new EdmNavigationPropertyInfo()
|
||||
{
|
||||
Name = "City",
|
||||
Target = city,
|
||||
TargetMultiplicity = EdmMultiplicity.One,
|
||||
});
|
||||
|
||||
var derivedComplex = new EdmComplexType("DefaultNs", "WorkAddress", complex);
|
||||
var navP2 = derivedComplex.AddUnidirectionalNavigation(
|
||||
new EdmNavigationPropertyInfo()
|
||||
{
|
||||
Name = "CountryOrRegion",
|
||||
Target = countryOrRegion,
|
||||
TargetMultiplicity = EdmMultiplicity.One,
|
||||
});
|
||||
|
||||
person.AddStructuralProperty("HomeAddress", new EdmComplexTypeReference(complex, false));
|
||||
person.AddStructuralProperty("WorkAddress", new EdmComplexTypeReference(complex, false));
|
||||
person.AddStructuralProperty("Addresses",
|
||||
new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(complex, false))));
|
||||
|
||||
model.AddElement(person);
|
||||
model.AddElement(city);
|
||||
model.AddElement(countryOrRegion);
|
||||
model.AddElement(complex);
|
||||
model.AddElement(derivedComplex);
|
||||
|
||||
var entityContainer = new EdmEntityContainer("DefaultNs", "Container");
|
||||
model.AddElement(entityContainer);
|
||||
EdmEntitySet people = new EdmEntitySet(entityContainer, "People", person);
|
||||
EdmEntitySet cities = new EdmEntitySet(entityContainer, "City", city);
|
||||
EdmEntitySet countriesOrRegions = new EdmEntitySet(entityContainer, "CountryOrRegion", countryOrRegion);
|
||||
people.AddNavigationTarget(navP, cities, new EdmPathExpression("HomeAddress/City"));
|
||||
people.AddNavigationTarget(navP, cities, new EdmPathExpression("Addresses/City"));
|
||||
people.AddNavigationTarget(navP2, countriesOrRegions,
|
||||
new EdmPathExpression("WorkAddress/DefaultNs.WorkAddress/CountryOrRegion"));
|
||||
entityContainer.AddElement(people);
|
||||
entityContainer.AddElement(cities);
|
||||
entityContainer.AddElement(countriesOrRegions);
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiTestBase.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiTestBase
|
||||
{
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
public OpenApiTestBase(ITestOutputHelper output)
|
||||
{
|
||||
this.output = output;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiWriterTestHelper.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.IO;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
internal static class OpenApiWriterTestHelper
|
||||
{
|
||||
internal static string WriteToJson(this IOpenApiWritable element,
|
||||
Action<IOpenApiWriter, IOpenApiWritable> before = null,
|
||||
Action<IOpenApiWriter, IOpenApiWritable> after = null)
|
||||
{
|
||||
Action<IOpenApiWriter> action = writer =>
|
||||
{
|
||||
before?.Invoke(writer, element);
|
||||
element?.Write(writer);
|
||||
after?.Invoke(writer, element);
|
||||
writer?.Flush();
|
||||
};
|
||||
|
||||
return Write(OpenApiTarget.Json, action);
|
||||
}
|
||||
|
||||
internal static string WriteToYaml(this IOpenApiWritable element,
|
||||
Action<IOpenApiWriter, IOpenApiWritable> before = null,
|
||||
Action<IOpenApiWriter, IOpenApiWritable> after = null)
|
||||
{
|
||||
Action<IOpenApiWriter> action = writer =>
|
||||
{
|
||||
before?.Invoke(writer, element);
|
||||
element?.Write(writer);
|
||||
after?.Invoke(writer, element);
|
||||
writer?.Flush();
|
||||
};
|
||||
|
||||
return Write(OpenApiTarget.Yaml, action);
|
||||
}
|
||||
|
||||
internal static string Write(this IOpenApiWritable element,
|
||||
OpenApiTarget target,
|
||||
Action<IOpenApiWriter, IOpenApiWritable> before = null,
|
||||
Action<IOpenApiWriter, IOpenApiWritable> after = null)
|
||||
{
|
||||
Action<IOpenApiWriter> action = writer =>
|
||||
{
|
||||
before?.Invoke(writer, element);
|
||||
element?.Write(writer);
|
||||
after?.Invoke(writer, element);
|
||||
writer?.Flush();
|
||||
};
|
||||
|
||||
return Write(target, action);
|
||||
}
|
||||
|
||||
internal static string Write(this Action<IOpenApiWriter> action, OpenApiTarget target)
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
IOpenApiWriter writer;
|
||||
if (target == OpenApiTarget.Yaml)
|
||||
{
|
||||
writer = new OpenApiYamlWriter(new StreamWriter(stream));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer = new OpenApiJsonWriter(new StreamWriter(stream));
|
||||
}
|
||||
|
||||
action(writer);
|
||||
writer.Flush();
|
||||
stream.Position = 0;
|
||||
return new StreamReader(stream).ReadToEnd();
|
||||
}
|
||||
|
||||
|
||||
internal static string Write(OpenApiTarget target, Action<IOpenApiWriter> action)
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
IOpenApiWriter writer;
|
||||
if (target == OpenApiTarget.Yaml)
|
||||
{
|
||||
writer = new OpenApiYamlWriter(new StreamWriter(stream));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer = new OpenApiJsonWriter(new StreamWriter(stream));
|
||||
}
|
||||
|
||||
action(writer);
|
||||
writer.Flush();
|
||||
stream.Position = 0;
|
||||
return new StreamReader(stream).ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="StringHelper.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public static class StringHelper
|
||||
{
|
||||
public static string Replace(this string rawString, string newLine = "\n")
|
||||
{
|
||||
rawString = rawString.Trim('\n', '\r');
|
||||
rawString = rawString.Replace("\r\n", newLine);
|
||||
return rawString;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="EdmModelOpenApiExtensionsTest.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.IO;
|
||||
using Microsoft.OData.Edm;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class EdmModelOpenApiExtensionsTest
|
||||
{
|
||||
[Fact]
|
||||
public void EmptyEdmModelToOpenApiJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.EmptyModel;
|
||||
|
||||
// Act
|
||||
string json = WriteEdmModelToOpenApi(model, OpenApiTarget.Json);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(Resources.GetString("Empty.OpenApi.json").Replace(), json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyEdmModelToOpenApiYamlWorks()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.EmptyModel;
|
||||
|
||||
// Act
|
||||
string yaml = WriteEdmModelToOpenApi(model, OpenApiTarget.Yaml);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(Resources.GetString("Empty.OpenApi.yaml").Replace(), yaml);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BasicEdmModelToOpenApiJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
|
||||
// Act
|
||||
string json = WriteEdmModelToOpenApi(model, OpenApiTarget.Json);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(Resources.GetString("Basic.OpenApi.json").Replace(), json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BasicEdmModelToOpenApiYamlWorks()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
|
||||
// Act
|
||||
string yaml = WriteEdmModelToOpenApi(model, OpenApiTarget.Yaml);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(Resources.GetString("Basic.OpenApi.yaml").Replace(), yaml);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TripServiceMetadataToOpenApiJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.TripServiceModel;
|
||||
OpenApiWriterSettings settings = new OpenApiWriterSettings
|
||||
{
|
||||
Version = new Version(1, 0, 1),
|
||||
BaseUri = new Uri("http://services.odata.org/TrippinRESTierService/")
|
||||
};
|
||||
|
||||
// Act
|
||||
string json = WriteEdmModelToOpenApi(model, OpenApiTarget.Json, settings);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(Resources.GetString("TripService.OpenApi.json").Replace(), json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TripServiceMetadataToOpenApiYamlWorks()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.TripServiceModel;
|
||||
OpenApiWriterSettings settings = new OpenApiWriterSettings
|
||||
{
|
||||
Version = new Version(1, 0, 1),
|
||||
BaseUri = new Uri("http://services.odata.org/TrippinRESTierService/")
|
||||
};
|
||||
|
||||
// Act
|
||||
string yaml = WriteEdmModelToOpenApi(model, OpenApiTarget.Yaml, settings);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(Resources.GetString("TripService.OpenApi.yaml").Replace(), yaml);
|
||||
}
|
||||
|
||||
private static string WriteEdmModelToOpenApi(IEdmModel model, OpenApiTarget target,
|
||||
OpenApiWriterSettings settings = null)
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
model.WriteOpenApi(stream, target, settings);
|
||||
stream.Flush();
|
||||
stream.Position = 0;
|
||||
return new StreamReader(stream).ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyName>Microsoft.OpenAPI.OData.Reader.Tests</AssemblyName>
|
||||
<RootNamespace>Microsoft.OpenAPI.OData.Reader.Tests</RootNamespace>
|
||||
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\Basic.OpenApi.json" />
|
||||
<None Remove="Resources\Basic.OpenApi.yaml" />
|
||||
<None Remove="Resources\Empty.OpenApi.json" />
|
||||
<None Remove="Resources\Empty.OpenApi.yaml" />
|
||||
<None Remove="Resources\TripService.OpenApi.json" />
|
||||
<None Remove="Resources\TripService.OpenApi.yaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Basic.OpenApi.json" />
|
||||
<EmbeddedResource Include="Resources\Basic.OpenApi.yaml" />
|
||||
<EmbeddedResource Include="Resources\Empty.OpenApi.json" />
|
||||
<EmbeddedResource Include="Resources\Empty.OpenApi.yaml" />
|
||||
<EmbeddedResource Include="Resources\TripService.OData.xml" />
|
||||
<EmbeddedResource Include="Resources\TripService.OpenApi.json" />
|
||||
<EmbeddedResource Include="Resources\TripService.OpenApi.yaml" />
|
||||
<EmbeddedResource Include="Resources\YamlWriterTest.yaml.txt" />
|
||||
<EmbeddedResource Include="Resources\JsonWriterTest.json.txt" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.0-beta5-build3769" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta5-build3769" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.OpenApi.OData.Reader\Microsoft.OpenApi.OData.Reader.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,12 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="ODataOpenApiConvertTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class ODataOpenApiConvertTest
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiAnyTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiAnyTest
|
||||
{
|
||||
private OpenApiAny _wrongAny = new OpenApiAny
|
||||
{
|
||||
{ "doubleProp", 6.8 }
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void WriteNotSupportedValueTypeThrowNotSupportedException()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
var jsonExcep = Assert.Throws<OpenApiException>(() => _wrongAny.WriteToJson());
|
||||
|
||||
var yamlExcep = Assert.Throws<OpenApiException>(() => _wrongAny.WriteToYaml());
|
||||
|
||||
Assert.Equal(jsonExcep.Message, yamlExcep.Message);
|
||||
|
||||
Assert.Equal(String.Format(SRResource.OpenApiUnsupportedValueType, "System.Double"),
|
||||
jsonExcep.Message);
|
||||
}
|
||||
|
||||
private OpenApiAny _basicAny = new OpenApiAny
|
||||
{
|
||||
{ "StringProp", "value" },
|
||||
{ "nullProp", null },
|
||||
{ "intProp", 42 },
|
||||
{ "boolProp", false }
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteAnyObjectWithBasicValueToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""StringProp"": ""value"",
|
||||
""nullProp"": null,
|
||||
""intProp"": 42,
|
||||
""boolProp"": false
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _basicAny.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteAnyObjectWithBasicValueToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
StringProp: value
|
||||
nullProp:
|
||||
intProp: 42
|
||||
boolProp: false
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _basicAny.WriteToYaml());
|
||||
}
|
||||
|
||||
private OpenApiAny _anyWithWritableElement = new OpenApiAny
|
||||
{
|
||||
{ "stringProp", "value" },
|
||||
{ "writable", new OpenApiAny
|
||||
{
|
||||
{ "decimalProp", (decimal)6.8 },
|
||||
{ "nullProp", null },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteAnyObjectWithWritableElementToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""stringProp"": ""value"",
|
||||
""writable"": {
|
||||
""decimalProp"": 6.8,
|
||||
""nullProp"": null
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _anyWithWritableElement.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteAnyObjectWithWritableElementToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
stringProp: value
|
||||
writable:
|
||||
decimalProp: 6.8
|
||||
nullProp:
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _anyWithWritableElement.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiComponentsTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiComponentsTest
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiContactTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiContactTest
|
||||
{
|
||||
internal static OpenApiContact BasicContact = new OpenApiContact();
|
||||
internal static OpenApiContact AdvanceContact = new OpenApiContact
|
||||
{
|
||||
Name = "API Support",
|
||||
Url = new Uri("http://www.example.com/support"),
|
||||
Email = "support@example.com"
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicContactToJsonWorks()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Equal("{ }", BasicContact.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicContactToYamlWorks()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Equal("", BasicContact.WriteToYaml());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAdvanceContactToJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""name"": ""API Support"",
|
||||
""url"": ""http://www.example.com/support"",
|
||||
""email"": ""support@example.com""
|
||||
}"
|
||||
.Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceContact.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteFullContactToYamlWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
name: API Support
|
||||
url: http://www.example.com/support
|
||||
email: support@example.com
|
||||
"
|
||||
.Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceContact.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiDocumentTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiDocumentTest
|
||||
{
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
public OpenApiDocumentTest(ITestOutputHelper output)
|
||||
{
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriterMemeoryStream()
|
||||
{
|
||||
OpenApiDocument doc = new OpenApiDocument();
|
||||
|
||||
MemoryStream stream = new MemoryStream();
|
||||
doc.Write(stream);
|
||||
|
||||
stream.Position = 0;
|
||||
string value = new StreamReader(stream).ReadToEnd();
|
||||
|
||||
output.WriteLine(value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriter()
|
||||
{
|
||||
OpenApiDocument doc = new OpenApiDocument();
|
||||
|
||||
var builder = new StringBuilder();
|
||||
StringWriter sw = new StringWriter(builder);
|
||||
IOpenApiWriter writer = new OpenApiJsonWriter(sw, new OpenApiWriterSettings());
|
||||
doc.Write(writer);
|
||||
|
||||
sw.Flush();
|
||||
|
||||
output.WriteLine(sw.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriterYaml()
|
||||
{
|
||||
OpenApiDocument doc = new OpenApiDocument();
|
||||
|
||||
var builder = new StringBuilder();
|
||||
StringWriter sw = new StringWriter(builder);
|
||||
IOpenApiWriter writer = new OpenApiYamlWriter(sw, new OpenApiWriterSettings());
|
||||
doc.Write(writer);
|
||||
|
||||
sw.Flush();
|
||||
|
||||
output.WriteLine(sw.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiEncodingTest.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 Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiEncodingTest
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// <copyright file="OpenApiExampleTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiExampleTest
|
||||
{
|
||||
[Fact]
|
||||
public void CanWriteBasicExampleObjectAsJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""summary"": ""A bar example"",
|
||||
""externalValue"": ""http://example.org/examples/address-example.xml""
|
||||
}
|
||||
".Replace();
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Summary = "A bar example",
|
||||
ExternalValue = new Uri("http://example.org/examples/address-example.xml")
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteBasicExampleObjectAsYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
summary: A bar example
|
||||
description: A bar example description
|
||||
value:
|
||||
".Replace();
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Summary = "A bar example",
|
||||
Description = "A bar example description",
|
||||
Value = new OpenApiAny()
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToYaml());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteExampleObjectAsReferenceObjectJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""$ref"": ""#/components/schemas/Address""
|
||||
}
|
||||
".Replace();
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/Address")
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteExampleObjectAsReferenceObjectYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"$ref: #/components/schemas/Address";
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/Address")
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiExternalDocsTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiExternalDocsTest
|
||||
{
|
||||
internal static OpenApiExternalDocs BasicExDocs = new OpenApiExternalDocs();
|
||||
internal static OpenApiExternalDocs AdvanceExDocs = new OpenApiExternalDocs()
|
||||
{
|
||||
Url = new Uri("https://example.com"),
|
||||
Description = "Find more info here"
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicExternalDocsToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""url"": ""http://localhost/""
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, BasicExDocs.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicExternalDocsToYaml()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Equal("url: http://localhost/", BasicExDocs.WriteToYaml());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAdvanceExternalDocsToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""description"": ""Find more info here"",
|
||||
""url"": ""https://example.com""
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceExDocs.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAdvanceExternalDocsToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
description: Find more info here
|
||||
url: https://example.com
|
||||
"
|
||||
.Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceExDocs.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiExtensionTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Microsoft.OData.OpenAPI.Properties;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiExtensionTest
|
||||
{
|
||||
[Fact]
|
||||
public void CtorThrowsArgumentNullName()
|
||||
{
|
||||
Assert.Throws<ArgumentException>("name", () => new OpenApiExtension(null, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CtorThrowsFieldNameMustPrefix()
|
||||
{
|
||||
// Arrange
|
||||
var exception = Assert.Throws<OpenApiException>(() => new OpenApiExtension("any", null));
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(SRResource.ExtensionFieldNameMustBeginWithXMinus, exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteExtensionWithNullValueWorks()
|
||||
{
|
||||
// Arrange
|
||||
OpenApiExtension ex = new OpenApiExtension("x-name", null);
|
||||
Action<IOpenApiWriter> action = writer =>
|
||||
{
|
||||
writer.WriteStartObject(); // for valid JSON/Yaml object
|
||||
{
|
||||
ex.Write(writer);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
writer.Flush();
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal("{\n \"x-name\": null\n}",
|
||||
OpenApiWriterTestHelper.Write(OpenApiTarget.Json, action));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiTagTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiTagTest
|
||||
{
|
||||
internal static OpenApiTag BasicTag = new OpenApiTag();
|
||||
internal static OpenApiTag AdvanceTag = new OpenApiTag()
|
||||
{
|
||||
Name = "pet",
|
||||
Description = "Pets operations",
|
||||
ExternalDocs = OpenApiExternalDocsTest.AdvanceExDocs
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicTagToJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""name"": ""Default Name""
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, BasicTag.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicTagToYamlWorks()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Equal("name: Default Name", BasicTag.WriteToYaml());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAdvanceTagToJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""name"": ""pet"",
|
||||
""description"": ""Pets operations"",
|
||||
""externalDocs"": {
|
||||
""description"": ""Find more info here"",
|
||||
""url"": ""https://example.com""
|
||||
}
|
||||
}"
|
||||
.Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceTag.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAdvanceTagToYamlWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
name: pet
|
||||
description: Pets operations
|
||||
externalDocs:
|
||||
description: Find more info here
|
||||
url: https://example.com
|
||||
"
|
||||
.Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceTag.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiInfoTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiInfoTest
|
||||
{
|
||||
internal static OpenApiInfo BasicInfo = CreateBasicInfo();
|
||||
internal static OpenApiInfo AdvanceInfo = CreateAdvanceInfo();
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicInfoToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""title"": ""Sample OData Book Store App"",
|
||||
""description"": ""This is a sample OData server for a book store."",
|
||||
""termsOfService"": ""http://services.odata.org/"",
|
||||
""version"": ""1.0.1""
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, BasicInfo.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicInfoToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
title: Sample OData Book Store App
|
||||
description: This is a sample OData server for a book store.
|
||||
termsOfService: http://services.odata.org/
|
||||
version: 1.0.1
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, BasicInfo.WriteToYaml());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAdvanceInfoToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""title"": ""Sample Pet Store App"",
|
||||
""description"": ""This is a sample server for a pet store."",
|
||||
""termsOfService"": ""http://example.com/terms/"",
|
||||
""contact"": {
|
||||
""name"": ""API Support"",
|
||||
""url"": ""http://www.example.com/support"",
|
||||
""email"": ""support@example.com""
|
||||
},
|
||||
""license"": {
|
||||
""name"": ""Apache 2.0"",
|
||||
""url"": ""http://www.apache.org/licenses/LICENSE-2.0.html""
|
||||
},
|
||||
""version"": ""1.0.1""
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceInfo.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteAdvanceInfoToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
title: Sample Pet Store App
|
||||
description: This is a sample server for a pet store.
|
||||
termsOfService: http://example.com/terms/
|
||||
contact:
|
||||
name: API Support
|
||||
url: http://www.example.com/support
|
||||
email: support@example.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
version: 1.0.1
|
||||
".Replace();
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceInfo.WriteToYaml());
|
||||
}
|
||||
|
||||
private static OpenApiInfo CreateBasicInfo()
|
||||
{
|
||||
return new OpenApiInfo
|
||||
{
|
||||
Title = "Sample OData Book Store App",
|
||||
Version = new Version(1, 0, 1),
|
||||
Description = "This is a sample OData server for a book store.",
|
||||
TermsOfService = new Uri("http://services.odata.org/")
|
||||
};
|
||||
}
|
||||
|
||||
private static OpenApiInfo CreateAdvanceInfo()
|
||||
{
|
||||
return new OpenApiInfo
|
||||
{
|
||||
Title = "Sample Pet Store App",
|
||||
Version = new Version(1, 0, 1),
|
||||
Description = "This is a sample server for a pet store.",
|
||||
TermsOfService = new Uri("http://example.com/terms/"),
|
||||
Contact = OpenApiContactTest.AdvanceContact,
|
||||
License = OpenApiLicenseTest.AdvanceLicense
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiLicenseTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiLicenseTest
|
||||
{
|
||||
internal static OpenApiLicense BasicLicense = new OpenApiLicense();
|
||||
internal static OpenApiLicense AdvanceLicense = new OpenApiLicense
|
||||
{
|
||||
Name = "Apache 2.0",
|
||||
Url = new Uri("http://www.apache.org/licenses/LICENSE-2.0.html")
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicLicenseToJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""name"": ""Default Name""
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, BasicLicense.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteBasicLicenseToYamlWorks()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Equal("name: Default Name", BasicLicense.WriteToYaml());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteFullLicenseToJsonWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""name"": ""Apache 2.0"",
|
||||
""url"": ""http://www.apache.org/licenses/LICENSE-2.0.html""
|
||||
}"
|
||||
.Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceLicense.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteFullLicenseToYamlWorks()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
"
|
||||
.Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, AdvanceLicense.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiMediaTypeTest.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 Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiMediaTypeTest
|
||||
{
|
||||
private OpenApiMediaType _mediaType = new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/Pet")
|
||||
},
|
||||
Examples = new Dictionary<string, OpenApiExample>
|
||||
{
|
||||
{
|
||||
"cat",
|
||||
new OpenApiExample
|
||||
{
|
||||
Summary = "An example of a cat",
|
||||
Value = new OpenApiAny
|
||||
{
|
||||
{ "name", "Fluffy"},
|
||||
{ "petType", "Cat"},
|
||||
{ "color", "White"},
|
||||
{ "gender", "Male"},
|
||||
{ "breed", "Persian"}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"dog",
|
||||
new OpenApiExample
|
||||
{
|
||||
Summary = "An example of a dog with a cat's name",
|
||||
Value = new OpenApiAny
|
||||
{
|
||||
{ "name", "Puma"},
|
||||
{ "petType", "Dog"},
|
||||
{ "color", "Black"},
|
||||
{ "gender", "Female"},
|
||||
{ "breed", "Mixed"}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"frog",
|
||||
new OpenApiExample
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/examples/frog-example")
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteMediaTypeObjectToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""schema"": {
|
||||
""$ref"": ""#/components/schemas/Pet""
|
||||
},
|
||||
""examples"": {
|
||||
""cat"": {
|
||||
""summary"": ""An example of a cat"",
|
||||
""value"": {
|
||||
""name"": ""Fluffy"",
|
||||
""petType"": ""Cat"",
|
||||
""color"": ""White"",
|
||||
""gender"": ""Male"",
|
||||
""breed"": ""Persian""
|
||||
}
|
||||
},
|
||||
""dog"": {
|
||||
""summary"": ""An example of a dog with a cat's name"",
|
||||
""value"": {
|
||||
""name"": ""Puma"",
|
||||
""petType"": ""Dog"",
|
||||
""color"": ""Black"",
|
||||
""gender"": ""Female"",
|
||||
""breed"": ""Mixed""
|
||||
}
|
||||
},
|
||||
""frog"": {
|
||||
""$ref"": ""#/components/examples/frog-example""
|
||||
}
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _mediaType.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteMediaTypeObjectToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
schema:
|
||||
$ref: '#/components/schemas/Pet'
|
||||
examples:
|
||||
cat:
|
||||
summary: An example of a cat
|
||||
value:
|
||||
name: Fluffy
|
||||
petType: Cat
|
||||
color: White
|
||||
gender: Male
|
||||
breed: Persian
|
||||
dog:
|
||||
summary: An example of a dog with a cat's name
|
||||
value:
|
||||
name: Puma
|
||||
petType: Dog
|
||||
color: Black
|
||||
gender: Female
|
||||
breed: Mixed
|
||||
frog:
|
||||
$ref: '#/components/examples/frog-example'
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _mediaType.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
// <copyright file="OpenApiParameterTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiParameterTest
|
||||
{
|
||||
[Fact]
|
||||
public void CtorSetsPropertiesValue()
|
||||
{
|
||||
// Arrange & Act
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = "token",
|
||||
In = ParameterLocation.header
|
||||
};
|
||||
|
||||
// Assert
|
||||
Assert.Equal("token", parameter.Name);
|
||||
Assert.Equal(ParameterLocation.header, parameter.In);
|
||||
Assert.Equal(ParameterStyle.simple, parameter.Style);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteBasicParameterObjectAsJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""summary"": ""A bar example"",
|
||||
""externalValue"": ""http://example.org/examples/address-example.xml""
|
||||
}
|
||||
".Replace();
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Summary = "A bar example",
|
||||
ExternalValue = new Uri("http://example.org/examples/address-example.xml")
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteBasicParameterObjectAsYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
summary: A bar example
|
||||
description: A bar example description
|
||||
value:
|
||||
".Replace();
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Summary = "A bar example",
|
||||
Description = "A bar example description",
|
||||
Value = new OpenApiAny()
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToYaml());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteParameterObjectAsReferenceObjectJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""$ref"": ""#/components/schemas/Address""
|
||||
}
|
||||
".Replace();
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/Address")
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteParameterObjectAsReferenceObjectYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"$ref: #/components/schemas/Address";
|
||||
|
||||
OpenApiExample example = new OpenApiExample
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/Address")
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, example.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiPathItemTest.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 Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiPathItemTest
|
||||
{
|
||||
private OpenApiPathItem _pathItem = new OpenApiPathItem
|
||||
{
|
||||
Get = new OpenApiOperation
|
||||
{
|
||||
Description = "Returns pets based on ID",
|
||||
Summary = "Find pets by ID",
|
||||
OperationId = "getPetsById",
|
||||
Responses = new OpenApiResponses
|
||||
{
|
||||
{
|
||||
"200",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Description = "pet response",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"*/*",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/pet")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"default",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Description = "error payload",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"text/html",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/ErrorModel")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Parameters = new List<OpenApiParameter>
|
||||
{
|
||||
new OpenApiParameter
|
||||
{
|
||||
Name = "id",
|
||||
Description = "ID of pet to use",
|
||||
In = ParameterLocation.path,
|
||||
Required = true,
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
},
|
||||
Style = ParameterStyle.simple
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWritePathItemObjectToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""get"": {
|
||||
""summary"": ""Find pets by ID"",
|
||||
""description"": ""Returns pets based on ID"",
|
||||
""operationId"": ""getPetsById"",
|
||||
""parameters"": [
|
||||
{
|
||||
""name"": ""id"",
|
||||
""in"": ""path"",
|
||||
""description"": ""ID of pet to use"",
|
||||
""required"": true,
|
||||
""style"": ""simple"",
|
||||
""schema"": {
|
||||
""type"": ""array"",
|
||||
""items"": {
|
||||
""type"": ""string""
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
""responses"": {
|
||||
""200"": {
|
||||
""description"": ""pet response"",
|
||||
""content"": {
|
||||
""*/*"": {
|
||||
""schema"": {
|
||||
""type"": ""array"",
|
||||
""items"": {
|
||||
""$ref"": ""#/components/schemas/pet""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
""default"": {
|
||||
""description"": ""error payload"",
|
||||
""content"": {
|
||||
""text/html"": {
|
||||
""schema"": {
|
||||
""$ref"": ""#/components/schemas/ErrorModel""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _pathItem.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWritePathItemObjectToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
get:
|
||||
summary: Find pets by ID
|
||||
description: Returns pets based on ID
|
||||
operationId: getPetsById
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: ID of pet to use
|
||||
required: true
|
||||
style: simple
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: pet response
|
||||
content:
|
||||
*/*:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/pet'
|
||||
default:
|
||||
description: error payload
|
||||
content:
|
||||
text/html:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorModel'
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _pathItem.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiPathsTest.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 Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiPathsTest
|
||||
{
|
||||
internal static OpenApiPaths Paths = new OpenApiPaths
|
||||
{
|
||||
{
|
||||
"/pets",
|
||||
new OpenApiPathItem
|
||||
{
|
||||
Get = new OpenApiOperation
|
||||
{
|
||||
Description = "Returns all pets from the system that the user has access to",
|
||||
Responses = new OpenApiResponses
|
||||
{
|
||||
{
|
||||
"200",
|
||||
new OpenApiResponse
|
||||
{
|
||||
Description = "A list of pets.",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/pet")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWritePathsObjectToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""/pets"": {
|
||||
""get"": {
|
||||
""description"": ""Returns all pets from the system that the user has access to"",
|
||||
""responses"": {
|
||||
""200"": {
|
||||
""description"": ""A list of pets."",
|
||||
""content"": {
|
||||
""application/json"": {
|
||||
""schema"": {
|
||||
""type"": ""array"",
|
||||
""items"": {
|
||||
""$ref"": ""#/components/schemas/pet""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, Paths.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWritePathsObjectToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
/pets:
|
||||
get:
|
||||
description: Returns all pets from the system that the user has access to
|
||||
responses:
|
||||
200:
|
||||
description: A list of pets.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/pet'
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, Paths.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
// <copyright file="OpenApiReferenceTest.cs" company="Microsoft">
|
||||
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiReferenceTest
|
||||
{
|
||||
[Fact]
|
||||
public void CtorThrowsArgumentNullRef()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentException>("ref", () => new OpenApiReference(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CtorSetsRefPropertyValue()
|
||||
{
|
||||
// Arrange & Act
|
||||
OpenApiReference oar = new OpenApiReference("#/components/schemas/Pet");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("#/components/schemas/Pet", oar.Ref);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteReferenceObjectIntoJson()
|
||||
{
|
||||
// Arrange & Act
|
||||
string expect = @"
|
||||
{
|
||||
""$ref"": ""#/components/schemas/Pet""
|
||||
}".Replace();
|
||||
|
||||
OpenApiReference oar = new OpenApiReference("#/components/schemas/Pet");
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, oar.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteReferenceObjectIntoYaml()
|
||||
{
|
||||
// Arrange & Act
|
||||
OpenApiReference oar = new OpenApiReference("#/components/schemas/Pet");
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal("$ref: #/components/schemas/Pet", oar.WriteToYaml());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
//---------------------------------------------------------------------
|
||||
// <copyright file="OpenApiResponseTest.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 Xunit;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiResponseTest
|
||||
{
|
||||
private OpenApiResponse _responseWithComplex = new OpenApiResponse
|
||||
{
|
||||
Description = "A complex object array response",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"application/json",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "array",
|
||||
Items = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/VeryComplexType")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteResonseObjectWithComplexToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""description"": ""A complex object array response"",
|
||||
""content"": {
|
||||
""application/json"": {
|
||||
""schema"": {
|
||||
""type"": ""array"",
|
||||
""items"": {
|
||||
""$ref"": ""#/components/schemas/VeryComplexType""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _responseWithComplex.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteResonseObjectWithComplexToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
description: A complex object array response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/VeryComplexType'
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _responseWithComplex.WriteToYaml());
|
||||
}
|
||||
|
||||
private OpenApiResponse _responseWithStringType = new OpenApiResponse
|
||||
{
|
||||
Description = "A simple string response",
|
||||
Content = new Dictionary<string, OpenApiMediaType>
|
||||
{
|
||||
{
|
||||
"text/plain",
|
||||
new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteResponseObjectWithStringTypeToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""description"": ""A simple string response"",
|
||||
""content"": {
|
||||
""text/plain"": {
|
||||
""schema"": {
|
||||
""type"": ""string""
|
||||
}
|
||||
}
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _responseWithStringType.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteResponseObjectWithStringTypeToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
description: A simple string response
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _responseWithStringType.WriteToYaml());
|
||||
}
|
||||
|
||||
private OpenApiResponse _responseWithHeaders = new OpenApiResponse
|
||||
{
|
||||
Description = "A simple string response",
|
||||
Headers = new Dictionary<string, OpenApiHeader>
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,398 @@
|
|||
// <copyright file="OpenApiSchemaTest.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 Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Microsoft.OData.OpenAPI.Tests
|
||||
{
|
||||
public class OpenApiSchemaTest
|
||||
{
|
||||
#region Primitive Sample
|
||||
|
||||
private OpenApiSchema _primitiveSample = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Format = "email"
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWritePrimitiveSchemaSampleToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""type"": ""string"",
|
||||
""format"": ""email""
|
||||
}
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _primitiveSample.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWritePrimitiveSchemaSampleToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
type: string
|
||||
format: email
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _primitiveSample.WriteToYaml());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Simple Model
|
||||
|
||||
private OpenApiSchema _simpleModel = new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Required = new List<string> { "name" },
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"name",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"address",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/Address")
|
||||
}
|
||||
},
|
||||
{
|
||||
"age",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "integer",
|
||||
Format = "int32",
|
||||
Minimum = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSimpleModelSchemaToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""type"": ""object"",
|
||||
""required"": [
|
||||
""name""
|
||||
],
|
||||
""properties"": {
|
||||
""name"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""address"": {
|
||||
""$ref"": ""#/components/schemas/Address""
|
||||
},
|
||||
""age"": {
|
||||
""type"": ""integer"",
|
||||
""format"": ""int32"",
|
||||
""minimum"": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _simpleModel.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSimpleModelSchemaToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
address:
|
||||
$ref: '#/components/schemas/Address'
|
||||
age:
|
||||
type: integer
|
||||
format: int32
|
||||
minimum: 0
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _simpleModel.WriteToYaml());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Simple String to String Mapping
|
||||
|
||||
private OpenApiSchema _simpleStringToStringMapping = new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
AdditionalProperties = new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSimpleStringToStringMappingSchemaToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""type"": ""object"",
|
||||
""additionalProperties"": {
|
||||
""type"": ""string""
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _simpleStringToStringMapping.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSimpleStringToStringMappingSchemaToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _simpleStringToStringMapping.WriteToYaml());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region String to Model mapping
|
||||
|
||||
private OpenApiSchema _simpleStringToModelMapping = new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
AdditionalProperties = new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/ComplexModel")
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSimpleStringToModelMappingSchemaToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""type"": ""object"",
|
||||
""additionalProperties"": {
|
||||
""$ref"": ""#/components/schemas/ComplexModel""
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _simpleStringToModelMapping.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteSimpleStringToModelMappingSchemaToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/ComplexModel'
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _simpleStringToModelMapping.WriteToYaml());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Model with Example
|
||||
|
||||
private OpenApiSchema _modelWithExampleMapping = new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Example = new OpenApiAny
|
||||
{
|
||||
{ "name", "Puma" },
|
||||
{ "id", 1 }
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteModelWithExampleSchemaToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""type"": ""object"",
|
||||
""example"": {
|
||||
""name"": ""Puma"",
|
||||
""id"": 1
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _modelWithExampleMapping.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteModelWithExampleSchemaToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
type: object
|
||||
example:
|
||||
name: Puma
|
||||
id: 1
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _modelWithExampleMapping.WriteToYaml());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Model with Composition
|
||||
|
||||
private OpenApiSchema _modelWithCompositionMapping = new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Required = new List<string> { "message", "code" },
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"message",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"code",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "integer",
|
||||
Minimum = 100,
|
||||
Maximum = 600
|
||||
}
|
||||
}
|
||||
},
|
||||
AllOf = new List<OpenApiSchema>
|
||||
{
|
||||
new OpenApiSchema
|
||||
{
|
||||
Reference = new OpenApiReference("#/components/schemas/ErrorModel")
|
||||
},
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "object",
|
||||
Required = new List<string> { "rootCause" },
|
||||
Properties = new Dictionary<string, OpenApiSchema>
|
||||
{
|
||||
{
|
||||
"rootCause",
|
||||
new OpenApiSchema
|
||||
{
|
||||
Type = "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[Fact]
|
||||
public void CanWriteModelWithCompositionSchemaToJson()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
{
|
||||
""type"": ""object"",
|
||||
""required"": [
|
||||
""message"",
|
||||
""code""
|
||||
],
|
||||
""allOf"": [
|
||||
{
|
||||
""$ref"": ""#/components/schemas/ErrorModel""
|
||||
},
|
||||
{
|
||||
""type"": ""object"",
|
||||
""required"": [
|
||||
""rootCause""
|
||||
],
|
||||
""properties"": {
|
||||
""rootCause"": {
|
||||
""type"": ""string""
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
""properties"": {
|
||||
""message"": {
|
||||
""type"": ""string""
|
||||
},
|
||||
""code"": {
|
||||
""type"": ""integer"",
|
||||
""maximum"": 600,
|
||||
""minimum"": 100
|
||||
}
|
||||
}
|
||||
}".Replace();
|
||||
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _modelWithCompositionMapping.WriteToJson());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanWriteModelWithCompositionSchemaToYaml()
|
||||
{
|
||||
// Arrange
|
||||
string expect = @"
|
||||
type: object
|
||||
required:
|
||||
- message
|
||||
- code
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/ErrorModel',
|
||||
- type: object
|
||||
required:
|
||||
- rootCause
|
||||
properties:
|
||||
rootCause:
|
||||
type: string
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
code:
|
||||
type: integer
|
||||
maximum: 600
|
||||
minimum: 100
|
||||
".Replace();
|
||||
|
||||
// Act & Assert
|
||||
Assert.Equal(expect, _modelWithCompositionMapping.WriteToYaml());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue