214 lines
7.8 KiB
C#
214 lines
7.8 KiB
C#
// ------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
|
// ------------------------------------------------------------
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.OpenApi.Any;
|
|
using Microsoft.OpenApi.Models;
|
|
using Microsoft.OpenApi.OData.Common;
|
|
using Microsoft.OpenApi.OData.Edm;
|
|
using Microsoft.OpenApi.OData.Generator;
|
|
using Microsoft.OpenApi.OData.Vocabulary.Capabilities;
|
|
|
|
namespace Microsoft.OpenApi.OData.Operation
|
|
{
|
|
/// <summary>
|
|
/// Base class for <see cref="OpenApiOperation"/> handler.
|
|
/// All derived class should call base method for Set** at the end of override.
|
|
/// </summary>
|
|
internal abstract class OperationHandler : IOperationHandler
|
|
{
|
|
/// <inheritdoc/>
|
|
public abstract OperationType OperationType { get; }
|
|
|
|
/// <inheritdoc/>
|
|
public virtual OpenApiOperation CreateOperation(ODataContext context, ODataPath path)
|
|
{
|
|
Context = context ?? throw Error.ArgumentNull(nameof(context));
|
|
Path = path ?? throw Error.ArgumentNull(nameof(path));
|
|
|
|
// Initialize the object ahead.
|
|
Initialize(context, path);
|
|
|
|
OpenApiOperation operation = new OpenApiOperation();
|
|
|
|
// Description / Summary / OperationId
|
|
SetBasicInfo(operation);
|
|
|
|
// Security
|
|
SetSecurity(operation);
|
|
|
|
// Responses
|
|
SetResponses(operation);
|
|
|
|
// RequestBody
|
|
SetRequestBody(operation);
|
|
|
|
// Parameters
|
|
SetParameters(operation);
|
|
|
|
// Tags
|
|
SetTags(operation);
|
|
|
|
// Extensions
|
|
SetExtensions(operation);
|
|
|
|
return operation;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the OData context.
|
|
/// </summary>
|
|
protected ODataContext Context { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Gets the OData path.
|
|
/// </summary>
|
|
protected ODataPath Path { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Initialize the handler.
|
|
/// It should be call ahead of in derived class.
|
|
/// </summary>
|
|
/// <param name="context">The context.</param>
|
|
/// <param name="path">The path.</param>
|
|
protected virtual void Initialize(ODataContext context, ODataPath path)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Set the basic information for <see cref="OpenApiOperation"/>.
|
|
/// </summary>
|
|
/// <param name="operation">The <see cref="OpenApiOperation"/>.</param>
|
|
protected virtual void SetBasicInfo(OpenApiOperation operation)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Set the security information for <see cref="OpenApiOperation"/>.
|
|
/// </summary>
|
|
/// <param name="operation">The <see cref="OpenApiOperation"/>.</param>
|
|
protected virtual void SetSecurity(OpenApiOperation operation)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Set the responses information for <see cref="OpenApiOperation"/>.
|
|
/// </summary>
|
|
/// <param name="operation">The <see cref="OpenApiOperation"/>.</param>
|
|
protected virtual void SetResponses(OpenApiOperation operation)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Set the request body information for <see cref="OpenApiOperation"/>.
|
|
/// </summary>
|
|
/// <param name="operation">The <see cref="OpenApiOperation"/>.</param>
|
|
protected virtual void SetRequestBody(OpenApiOperation operation)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Set the parameters information for <see cref="OpenApiOperation"/>.
|
|
/// </summary>
|
|
/// <param name="operation">The <see cref="OpenApiOperation"/>.</param>
|
|
protected virtual void SetParameters(OpenApiOperation operation)
|
|
{
|
|
foreach (ODataKeySegment keySegment in Path.OfType<ODataKeySegment>())
|
|
{
|
|
foreach (var p in Context.CreateKeyParameters(keySegment))
|
|
{
|
|
operation.Parameters.Add(p);
|
|
}
|
|
}
|
|
|
|
AppendCustomParameters(operation);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the Tags information for <see cref="OpenApiOperation"/>.
|
|
/// </summary>
|
|
/// <param name="operation">The <see cref="OpenApiOperation"/>.</param>
|
|
protected virtual void SetTags(OpenApiOperation operation)
|
|
{
|
|
/// The OASIS mapping doc says:
|
|
/// The tags array of the Operation Object includes the entity set or singleton name
|
|
/// in the first segment of the path template. Additional tag values,
|
|
/// e.g. for the entity type of a containment navigation property or the target entity set
|
|
/// of a non-containment navigation property, can be included to make this operation more easily discoverable.
|
|
/// However, in this SDK, we use the different pattern for the Tags. See each hander.
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the Extensions information for <see cref="OpenApiOperation"/>.
|
|
/// </summary>
|
|
/// <param name="operation">The <see cref="OpenApiOperation"/>.</param>
|
|
protected virtual void SetExtensions(OpenApiOperation operation)
|
|
{ }
|
|
|
|
/// <summary>
|
|
/// Set the <see cref="HttpRequest"/> annotation for the operation.
|
|
/// </summary>
|
|
/// <param name="operation">The operation.</param>
|
|
/// <param name="request">The <see cref="HttpRequest"/>.</param>
|
|
protected virtual void AppendCustomParameters(OpenApiOperation operation)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the addition annotation for the response.
|
|
/// </summary>
|
|
/// <param name="operation">The operation.</param>
|
|
/// <param name="request">The <see cref="HttpRequest"/>.</param>
|
|
protected virtual void AppendHttpResponses(OpenApiOperation operation)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the custom parameters.
|
|
/// </summary>
|
|
/// <param name="parameters">The parameters.</param>
|
|
/// <param name="customParameters">The custom parameters.</param>
|
|
/// <param name="location">The parameter location.</param>
|
|
protected static void AppendCustomParameters(IList<OpenApiParameter> parameters, IList<CustomParameter> customParameters, ParameterLocation location)
|
|
{
|
|
foreach (var param in customParameters)
|
|
{
|
|
OpenApiParameter parameter = new OpenApiParameter
|
|
{
|
|
In = location,
|
|
Name = param.Name,
|
|
Description = param.Description,
|
|
Schema = new OpenApiSchema
|
|
{
|
|
Type = "string"
|
|
},
|
|
Required = param.Required ?? false
|
|
};
|
|
|
|
if (param.DocumentationURL != null)
|
|
{
|
|
parameter.Example = new OpenApiString(param.DocumentationURL ?? "N/A");
|
|
}
|
|
|
|
if (param.ExampleValues != null)
|
|
{
|
|
parameter.Examples = new Dictionary<string, OpenApiExample>();
|
|
int index = 1;
|
|
foreach (var example in param.ExampleValues)
|
|
{
|
|
OpenApiExample ex = new OpenApiExample
|
|
{
|
|
Description = example.Description
|
|
};
|
|
|
|
// maybe call convert to Uri literal
|
|
ex.Value = new OpenApiString(example.Value.ToString());
|
|
|
|
parameter.Examples.Add("example-" + index++, ex);
|
|
}
|
|
}
|
|
|
|
parameters.Add(parameter);
|
|
}
|
|
}
|
|
}
|
|
}
|