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", "name": "userName",
"in": "path", "in": "path",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"schema": { "schema": {
"type": "string" "type": "string"
@ -1350,6 +1351,7 @@
{ {
"name": "lastName", "name": "lastName",
"in": "path", "in": "path",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"schema": { "schema": {
"type": "string" "type": "string"
@ -2517,6 +2519,7 @@
{ {
"name": "userName", "name": "userName",
"in": "path", "in": "path",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"schema": { "schema": {
"type": "string" "type": "string"
@ -2622,6 +2625,7 @@
{ {
"name": "lastName", "name": "lastName",
"in": "path", "in": "path",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"schema": { "schema": {
"type": "string" "type": "string"
@ -3821,6 +3825,7 @@
{ {
"name": "userName", "name": "userName",
"in": "path", "in": "path",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"schema": { "schema": {
"type": "string" "type": "string"
@ -3926,6 +3931,7 @@
{ {
"name": "lastName", "name": "lastName",
"in": "path", "in": "path",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"schema": { "schema": {
"type": "string" "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", "in": "path",
"name": "userName", "name": "userName",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -1184,6 +1185,7 @@
{ {
"in": "path", "in": "path",
"name": "lastName", "name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -2235,6 +2237,7 @@
{ {
"in": "path", "in": "path",
"name": "userName", "name": "userName",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -2327,6 +2330,7 @@
{ {
"in": "path", "in": "path",
"name": "lastName", "name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -3402,6 +3406,7 @@
{ {
"in": "path", "in": "path",
"name": "userName", "name": "userName",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -3494,6 +3499,7 @@
{ {
"in": "path", "in": "path",
"name": "lastName", "name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"type": "string" "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)); 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 /> /// <inheritdoc />
public override IEdmEntityType EntityType { get; } public override IEdmEntityType EntityType { get; }
@ -51,6 +67,26 @@ namespace Microsoft.OpenApi.OData.Edm
{ {
Utils.CheckArgumentNull(settings, nameof(settings)); 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(); IList<IEdmStructuralProperty> keys = EntityType.Key().ToList();
if (keys.Count() == 1) if (keys.Count() == 1)
{ {
@ -82,7 +118,18 @@ namespace Microsoft.OpenApi.OData.Edm
internal IDictionary<string, string> GetKeyNameMapping(OpenApiConvertSettings settings, HashSet<string> parameters) internal IDictionary<string, string> GetKeyNameMapping(OpenApiConvertSettings settings, HashSet<string> parameters)
{ {
// Use the output key/template mapping
IDictionary<string, string> keyNamesMapping = new Dictionary<string, string>(); 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(); IList<IEdmStructuralProperty> keys = EntityType.Key().ToList();
if (keys.Count() == 1) if (keys.Count() == 1)
{ {

View file

@ -26,6 +26,22 @@ namespace Microsoft.OpenApi.OData.Edm
OperationImport = operationImport ?? throw Error.ArgumentNull(nameof(operationImport)); 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> /// <summary>
/// Gets the operation import. /// Gets the operation import.
/// </summary> /// </summary>

View file

@ -37,6 +37,22 @@ namespace Microsoft.OpenApi.OData.Edm
IsEscapedFunction = isEscapedFunction; 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> /// <summary>
/// Gets the operation. /// Gets the operation.
/// </summary> /// </summary>

View file

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

View file

@ -25,11 +25,22 @@ namespace Microsoft.OpenApi.OData.Operation
base.SetParameters(operation); base.SetParameters(operation);
IEdmFunctionImport functionImport = EdmOperationImport as IEdmFunctionImport; 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. if (OperationImportSegment.ParameterMappings != null)
foreach (var param in Context.CreateParameters(functionImport))
{ {
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> /// </summary>
protected IEdmOperationImport EdmOperationImport { get; private set; } protected IEdmOperationImport EdmOperationImport { get; private set; }
/// <summary>
/// Gets the <see cref="IEdmOperationImport"/>.
/// </summary>
protected ODataOperationImportSegment OperationImportSegment { get; private set; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Initialize(ODataContext context, ODataPath path) protected override void Initialize(ODataContext context, ODataPath path)
{ {
base.Initialize(context, path); base.Initialize(context, path);
ODataOperationImportSegment operationImportSegment = path.LastSegment as ODataOperationImportSegment; OperationImportSegment = path.LastSegment as ODataOperationImportSegment;
EdmOperationImport = operationImportSegment.OperationImport; EdmOperationImport = OperationImportSegment.OperationImport;
} }
/// <inheritdoc/> /// <inheritdoc/>

View file

@ -115,19 +115,31 @@ namespace Microsoft.OpenApi.OData.Operation
if (EdmOperation.IsFunction()) if (EdmOperation.IsFunction())
{ {
IEdmFunction function = (IEdmFunction)EdmOperation; IEdmFunction function = (IEdmFunction)EdmOperation;
IDictionary<string, string> mappings = ParameterMappings[OperationSegment];
IList<OpenApiParameter> parameters = Context.CreateParameters(function, mappings); if (OperationSegment.ParameterMappings != null)
if (operation.Parameters == null)
{
operation.Parameters = parameters;
}
else
{ {
IList<OpenApiParameter> parameters = Context.CreateParameters(function, OperationSegment.ParameterMappings);
foreach (var parameter in parameters) foreach (var parameter in parameters)
{ {
AppendParameter(operation, parameter); 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", "in": "path",
"name": "userName", "name": "userName",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -1245,6 +1246,7 @@
{ {
"in": "path", "in": "path",
"name": "lastName", "name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -2646,6 +2648,7 @@
{ {
"in": "path", "in": "path",
"name": "userName", "name": "userName",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -2800,6 +2803,7 @@
{ {
"in": "path", "in": "path",
"name": "lastName", "name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -4273,6 +4277,7 @@
{ {
"in": "path", "in": "path",
"name": "userName", "name": "userName",
"description": "Usage: userName={userName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }
@ -4427,6 +4432,7 @@
{ {
"in": "path", "in": "path",
"name": "lastName", "name": "lastName",
"description": "Usage: lastName={lastName}",
"required": true, "required": true,
"type": "string" "type": "string"
} }

View file

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

View file

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

View file

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