Add key and operation (function) parameter mapping

This commit is contained in:
Sam Xu 2021-02-10 17:45:14 -08:00
parent 05e10c94eb
commit b4d3ae36af
19 changed files with 116263 additions and 263 deletions

View File

@ -1267,6 +1267,7 @@
{
"name": "userName",
"in": "path",
"description": "Usage: userName={userName}",
"required": true,
"schema": {
"type": "string"
@ -1350,6 +1351,7 @@
{
"name": "lastName",
"in": "path",
"description": "Usage: lastName={lastName}",
"required": true,
"schema": {
"type": "string"
@ -2517,6 +2519,7 @@
{
"name": "userName",
"in": "path",
"description": "Usage: userName={userName}",
"required": true,
"schema": {
"type": "string"
@ -2622,6 +2625,7 @@
{
"name": "lastName",
"in": "path",
"description": "Usage: lastName={lastName}",
"required": true,
"schema": {
"type": "string"
@ -3821,6 +3825,7 @@
{
"name": "userName",
"in": "path",
"description": "Usage: userName={userName}",
"required": true,
"schema": {
"type": "string"
@ -3926,6 +3931,7 @@
{
"name": "lastName",
"in": "path",
"description": "Usage: lastName={lastName}",
"required": true,
"schema": {
"type": "string"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1108,6 +1108,7 @@
{
"in": "path",
"name": "userName",
"description": "Usage: userName={userName}",
"required": true,
"type": "string"
}
@ -1184,6 +1185,7 @@
{
"in": "path",
"name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true,
"type": "string"
}
@ -2235,6 +2237,7 @@
{
"in": "path",
"name": "userName",
"description": "Usage: userName={userName}",
"required": true,
"type": "string"
}
@ -2327,6 +2330,7 @@
{
"in": "path",
"name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true,
"type": "string"
}
@ -3402,6 +3406,7 @@
{
"in": "path",
"name": "userName",
"description": "Usage: userName={userName}",
"required": true,
"type": "string"
}
@ -3494,6 +3499,7 @@
{
"in": "path",
"name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true,
"type": "string"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,22 @@ namespace Microsoft.OpenApi.OData.Edm
EntityType = entityType ?? throw Error.ArgumentNull(nameof(entityType));
}
/// <summary>
/// Initializes a new instance of <see cref="ODataKeySegment"/> class.
/// </summary>
/// <param name="entityType">The entity type contains the keys.</param>
/// <param name="keyMappings">The key/template mappings.</param>
public ODataKeySegment(IEdmEntityType entityType, IDictionary<string, string> keyMappings)
{
EntityType = entityType ?? throw Error.ArgumentNull(nameof(entityType));
KeyMappings = keyMappings ?? throw Error.ArgumentNull(nameof(keyMappings));
}
/// <summary>
/// Gets the key/template mappings.
/// </summary>
public IDictionary<string, string> KeyMappings { get; }
/// <inheritdoc />
public override IEdmEntityType EntityType { get; }
@ -51,6 +67,26 @@ namespace Microsoft.OpenApi.OData.Edm
{
Utils.CheckArgumentNull(settings, nameof(settings));
// Use the output key/template mapping
if (KeyMappings != null)
{
if (KeyMappings.Count == 1)
{
var key = KeyMappings.First();
return $"{{{key.Value}}}";
}
else
{
IList<string> keyStrings = new List<string>();
foreach (var key in KeyMappings)
{
keyStrings.Add(key.Key + "={" + key.Value + "}");
}
return String.Join(",", keyStrings);
}
}
IList<IEdmStructuralProperty> keys = EntityType.Key().ToList();
if (keys.Count() == 1)
{
@ -82,7 +118,18 @@ namespace Microsoft.OpenApi.OData.Edm
internal IDictionary<string, string> GetKeyNameMapping(OpenApiConvertSettings settings, HashSet<string> parameters)
{
// Use the output key/template mapping
IDictionary<string, string> keyNamesMapping = new Dictionary<string, string>();
if (KeyMappings != null)
{
foreach (var keyName in KeyMappings)
{
keyNamesMapping[keyName.Key] = keyName.Value;
}
return keyNamesMapping;
}
IList<IEdmStructuralProperty> keys = EntityType.Key().ToList();
if (keys.Count() == 1)
{

View File

@ -26,6 +26,22 @@ namespace Microsoft.OpenApi.OData.Edm
OperationImport = operationImport ?? throw Error.ArgumentNull(nameof(operationImport));
}
/// <summary>
/// Initializes a new instance of <see cref="ODataOperationImportSegment"/> class.
/// </summary>
/// <param name="operationImport">The operation import.</param>
/// <param name="parameterMappings">The parameter mappings.</param>
public ODataOperationImportSegment(IEdmOperationImport operationImport, IDictionary<string, string> parameterMappings)
{
OperationImport = operationImport ?? throw Error.ArgumentNull(nameof(operationImport));
ParameterMappings = parameterMappings ?? throw Error.ArgumentNull(nameof(parameterMappings));
}
/// <summary>
/// Gets the parameter mappings.
/// </summary>
public IDictionary<string, string> ParameterMappings { get; }
/// <summary>
/// Gets the operation import.
/// </summary>

View File

@ -37,6 +37,22 @@ namespace Microsoft.OpenApi.OData.Edm
IsEscapedFunction = isEscapedFunction;
}
/// <summary>
/// Initializes a new instance of <see cref="ODataOperationSegment"/> class.
/// </summary>
/// <param name="operation">The operation.</param>
/// <param name="parameterMappings">The parameter mapping.</param>
public ODataOperationSegment(IEdmOperation operation, IDictionary<string, string> parameterMappings)
{
Operation = operation ?? throw Error.ArgumentNull(nameof(operation));
ParameterMappings = parameterMappings ?? throw Error.ArgumentNull(nameof(parameterMappings));
}
/// <summary>
/// Gets the parameter mappings.
/// </summary>
public IDictionary<string, string> ParameterMappings { get; }
/// <summary>
/// Gets the operation.
/// </summary>

View File

@ -74,13 +74,22 @@ namespace Microsoft.OpenApi.OData.Generator
int skip = function.IsBound ? 1 : 0;
foreach (IEdmOperationParameter edmParameter in function.Parameters.Skip(skip))
{
if (parameterNameMapping != null)
{
if (!parameterNameMapping.ContainsKey(edmParameter.Name))
{
continue;
}
}
OpenApiParameter parameter;
// Structured or collection-valued parameters are represented as a parameter alias
// in the path template and the parameters array contains a Parameter Object for
// the parameter alias as a query option of type string.
if (edmParameter.Type.IsStructured() ||
edmParameter.Type.IsCollection())
{
parameters.Add(new OpenApiParameter
parameter = new OpenApiParameter
{
Name = parameterNameMapping == null ? edmParameter.Name : parameterNameMapping[edmParameter.Name],
In = ParameterLocation.Query, // as query option
@ -96,19 +105,26 @@ namespace Microsoft.OpenApi.OData.Generator
// The parameter description describes the format this URL-encoded JSON object or array, and/or reference to [OData-URL].
Description = "The URL-encoded JSON " + (edmParameter.Type.IsStructured() ? "array" : "object")
});
};
}
else
{
// Primitive parameters use the same type mapping as described for primitive properties.
parameters.Add(new OpenApiParameter
parameter = new OpenApiParameter
{
Name = parameterNameMapping == null ? edmParameter.Name : parameterNameMapping[edmParameter.Name],
In = ParameterLocation.Path,
Required = true,
Schema = context.CreateEdmTypeSchema(edmParameter.Type)
});
};
}
if (parameterNameMapping != null)
{
parameter.Description = $"Usage: {edmParameter.Name}={{{parameterNameMapping[edmParameter.Name]}}}";
}
parameters.Add(parameter);
}
return parameters;
@ -170,6 +186,11 @@ namespace Microsoft.OpenApi.OData.Generator
Schema = context.CreateEdmTypeSchema(keyProperty.Type)
};
if (keySegment.KeyMappings != null)
{
parameter.Description = parameter.Description + $", {keyProperty.Name}={{{parameter.Name}}}";
}
parameter.Extensions.Add(Constants.xMsKeyType, new OpenApiString(entityType.Name));
parameters.Add(parameter);
}

View File

@ -25,11 +25,22 @@ namespace Microsoft.OpenApi.OData.Operation
base.SetParameters(operation);
IEdmFunctionImport functionImport = EdmOperationImport as IEdmFunctionImport;
//The parameters array contains a Parameter Object for each parameter of the function overload,
// and it contains specific Parameter Objects for the allowed system query options.
foreach (var param in Context.CreateParameters(functionImport))
if (OperationImportSegment.ParameterMappings != null)
{
AppendParameter(operation, param);
foreach (var param in Context.CreateParameters(functionImport.Function, OperationImportSegment.ParameterMappings))
{
AppendParameter(operation, param);
}
}
else
{
//The parameters array contains a Parameter Object for each parameter of the function overload,
// and it contains specific Parameter Objects for the allowed system query options.
foreach (var param in Context.CreateParameters(functionImport))
{
AppendParameter(operation, param);
}
}
}

View File

@ -26,13 +26,18 @@ namespace Microsoft.OpenApi.OData.Operation
/// </summary>
protected IEdmOperationImport EdmOperationImport { get; private set; }
/// <summary>
/// Gets the <see cref="IEdmOperationImport"/>.
/// </summary>
protected ODataOperationImportSegment OperationImportSegment { get; private set; }
/// <inheritdoc/>
protected override void Initialize(ODataContext context, ODataPath path)
{
base.Initialize(context, path);
ODataOperationImportSegment operationImportSegment = path.LastSegment as ODataOperationImportSegment;
EdmOperationImport = operationImportSegment.OperationImport;
OperationImportSegment = path.LastSegment as ODataOperationImportSegment;
EdmOperationImport = OperationImportSegment.OperationImport;
}
/// <inheritdoc/>

View File

@ -115,19 +115,31 @@ namespace Microsoft.OpenApi.OData.Operation
if (EdmOperation.IsFunction())
{
IEdmFunction function = (IEdmFunction)EdmOperation;
IDictionary<string, string> mappings = ParameterMappings[OperationSegment];
IList<OpenApiParameter> parameters = Context.CreateParameters(function, mappings);
if (operation.Parameters == null)
{
operation.Parameters = parameters;
}
else
if (OperationSegment.ParameterMappings != null)
{
IList<OpenApiParameter> parameters = Context.CreateParameters(function, OperationSegment.ParameterMappings);
foreach (var parameter in parameters)
{
AppendParameter(operation, parameter);
}
}
else
{
IDictionary<string, string> mappings = ParameterMappings[OperationSegment];
IList<OpenApiParameter> parameters = Context.CreateParameters(function, mappings);
if (operation.Parameters == null)
{
operation.Parameters = parameters;
}
else
{
foreach (var parameter in parameters)
{
AppendParameter(operation, parameter);
}
}
}
}
}

View File

@ -1115,6 +1115,7 @@
{
"in": "path",
"name": "userName",
"description": "Usage: userName={userName}",
"required": true,
"type": "string"
}
@ -1245,6 +1246,7 @@
{
"in": "path",
"name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true,
"type": "string"
}
@ -2646,6 +2648,7 @@
{
"in": "path",
"name": "userName",
"description": "Usage: userName={userName}",
"required": true,
"type": "string"
}
@ -2800,6 +2803,7 @@
{
"in": "path",
"name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true,
"type": "string"
}
@ -4273,6 +4277,7 @@
{
"in": "path",
"name": "userName",
"description": "Usage: userName={userName}",
"required": true,
"type": "string"
}
@ -4427,6 +4432,7 @@
{
"in": "path",
"name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true,
"type": "string"
}

View File

@ -762,6 +762,7 @@ paths:
parameters:
- in: path
name: userName
description: 'Usage: userName={userName}'
required: true
type: string
responses:
@ -849,6 +850,7 @@ paths:
parameters:
- in: path
name: lastName
description: 'Usage: lastName={lastName}'
required: true
type: string
responses:
@ -1829,6 +1831,7 @@ paths:
x-ms-docs-key-type: Person
- in: path
name: userName
description: 'Usage: userName={userName}'
required: true
type: string
responses:
@ -1934,6 +1937,7 @@ paths:
x-ms-docs-key-type: Person
- in: path
name: lastName
description: 'Usage: lastName={lastName}'
required: true
type: string
responses:
@ -2968,6 +2972,7 @@ paths:
x-ms-docs-key-type: Person
- in: path
name: userName
description: 'Usage: userName={userName}'
required: true
type: string
responses:
@ -3073,6 +3078,7 @@ paths:
x-ms-docs-key-type: Person
- in: path
name: lastName
description: 'Usage: lastName={lastName}'
required: true
type: string
responses:

View File

@ -1267,6 +1267,7 @@
{
"name": "userName",
"in": "path",
"description": "Usage: userName={userName}",
"required": true,
"schema": {
"type": "string"
@ -1405,6 +1406,7 @@
{
"name": "lastName",
"in": "path",
"description": "Usage: lastName={lastName}",
"required": true,
"schema": {
"type": "string"
@ -2968,6 +2970,7 @@
{
"name": "userName",
"in": "path",
"description": "Usage: userName={userName}",
"required": true,
"schema": {
"type": "string"
@ -3140,6 +3143,7 @@
{
"name": "lastName",
"in": "path",
"description": "Usage: lastName={lastName}",
"required": true,
"schema": {
"type": "string"
@ -4795,6 +4799,7 @@
{
"name": "userName",
"in": "path",
"description": "Usage: userName={userName}",
"required": true,
"schema": {
"type": "string"
@ -4967,6 +4972,7 @@
{
"name": "lastName",
"in": "path",
"description": "Usage: lastName={lastName}",
"required": true,
"schema": {
"type": "string"

View File

@ -849,6 +849,7 @@ paths:
parameters:
- name: userName
in: path
description: 'Usage: userName={userName}'
required: true
schema:
type: string
@ -937,6 +938,7 @@ paths:
parameters:
- name: lastName
in: path
description: 'Usage: lastName={lastName}'
required: true
schema:
type: string
@ -2015,6 +2017,7 @@ paths:
x-ms-docs-key-type: Person
- name: userName
in: path
description: 'Usage: userName={userName}'
required: true
schema:
type: string
@ -2126,6 +2129,7 @@ paths:
x-ms-docs-key-type: Person
- name: lastName
in: path
description: 'Usage: lastName={lastName}'
required: true
schema:
type: string
@ -3268,6 +3272,7 @@ paths:
x-ms-docs-key-type: Person
- name: userName
in: path
description: 'Usage: userName={userName}'
required: true
schema:
type: string
@ -3379,6 +3384,7 @@ paths:
x-ms-docs-key-type: Person
- name: lastName
in: path
description: 'Usage: lastName={lastName}'
required: true
schema:
type: string