modify the HttpRequest annotation and add test cases
This commit is contained in:
parent
97ff1aaf1d
commit
8495c737b7
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
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
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
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
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
|
@ -0,0 +1,129 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Org.OData.Core.V1.HttpRequests provider
|
||||
/// </summary>
|
||||
internal class HttpRequestProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Annotatable: EntitySet Singleton ActionImport FunctionImport Action Function
|
||||
/// Collection(Core.HttpRequest)
|
||||
/// </summary>
|
||||
private IDictionary<IEdmVocabularyAnnotatable, IList<HttpRequest>> _requests
|
||||
= new Dictionary<IEdmVocabularyAnnotatable, IList<HttpRequest>>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Edm mode.
|
||||
/// </summary>
|
||||
public IEdmModel Model { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Edm Term.
|
||||
/// </summary>
|
||||
public IEdmTerm Term { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="HttpRequestProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
public HttpRequestProvider(IEdmModel model)
|
||||
{
|
||||
Utils.CheckArgumentNull(model, nameof(model));
|
||||
|
||||
Term = model.FindTerm("Org.OData.Core.V1.HttpRequests");
|
||||
|
||||
Model = model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets Org.OData.Core.V1.HttpRequest.
|
||||
/// </summary>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <param name="method">The request method.</param>
|
||||
/// <returns>The Org.OData.Core.V1.HttpRequest or null.</returns>
|
||||
public HttpRequest GetHttpRequest(IEdmVocabularyAnnotatable target, string method)
|
||||
{
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
Utils.CheckArgumentNull(method, nameof(method));
|
||||
|
||||
var requests = GetHttpRequests(target);
|
||||
return requests?.FirstOrDefault(e => string.Equals(e.MethodType, method, System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of Org.OData.Core.V1.HttpRequest for a given <see cref="IEdmVocabularyAnnotatable"/>.
|
||||
/// </summary>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <returns>The collection of Org.OData.Core.V1.HttpRequest</returns>
|
||||
public IEnumerable<HttpRequest> GetHttpRequests(IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
if (Term == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Search the cache.
|
||||
if (_requests.TryGetValue(target, out IList<HttpRequest> value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(target, Term);
|
||||
if (annotation == null)
|
||||
{
|
||||
IEdmNavigationSource navigationSource = target as IEdmNavigationSource;
|
||||
|
||||
// if not, search the entity type.
|
||||
if (navigationSource != null)
|
||||
{
|
||||
IEdmEntityType entityType = navigationSource.EntityType();
|
||||
annotation = Model.GetVocabularyAnnotation(entityType, Term);
|
||||
}
|
||||
}
|
||||
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Collection)
|
||||
{
|
||||
_requests[target] = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (target is IEdmEntitySet)
|
||||
{
|
||||
IEdmEntitySet entitySet = target as IEdmEntitySet;
|
||||
if (entitySet.Name == "domains")
|
||||
{
|
||||
int pp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value;
|
||||
var httpRequests = new List<HttpRequest>();
|
||||
foreach (var item in collection.Elements)
|
||||
{
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)item;
|
||||
HttpRequest newRequest = new HttpRequest();
|
||||
newRequest.Init(record);
|
||||
httpRequests.Add(newRequest);
|
||||
}
|
||||
|
||||
_requests[target] = httpRequests;
|
||||
return httpRequests;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Org.OData.Core.V1.HttpRequests
|
||||
/// </summary>
|
||||
internal class HttpRequestsAnnotation
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// </summary>
|
||||
public virtual string QualifiedName => "Org.OData.Core.V1.HttpRequests";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the http request array.
|
||||
/// </summary>
|
||||
public IList<HttpRequest> Requests { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Edm mode.
|
||||
/// </summary>
|
||||
public IEdmModel Model { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vocabulary annotatble.
|
||||
/// </summary>
|
||||
public IEdmVocabularyAnnotatable Target { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="HttpRequestsAnnotation"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="target">The Edm annotation target.</param>
|
||||
public HttpRequestsAnnotation(IEdmModel model, IEdmVocabularyAnnotatable target)
|
||||
{
|
||||
Utils.CheckArgumentNull(model, nameof(model));
|
||||
Utils.CheckArgumentNull(target, nameof(target));
|
||||
|
||||
Model = model;
|
||||
Target = target;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public HttpRequest GetRequest(string method)
|
||||
{
|
||||
if (Requests == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Requests.FirstOrDefault(e => string.Equals(e.MethodType, method, System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(Target, QualifiedName);
|
||||
if (annotation == null)
|
||||
{
|
||||
IEdmNavigationSource navigationSource = Target as IEdmNavigationSource;
|
||||
|
||||
// if not, search the entity type.
|
||||
if (navigationSource != null)
|
||||
{
|
||||
IEdmEntityType entityType = navigationSource.EntityType();
|
||||
annotation = Model.GetVocabularyAnnotation(entityType, QualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Collection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value;
|
||||
|
||||
Requests = new List<HttpRequest>();
|
||||
foreach (var item in collection.Elements)
|
||||
{
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)item;
|
||||
HttpRequest request = new HttpRequest();
|
||||
request.Init(record);
|
||||
Requests.Add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
|
||||
#if false
|
||||
namespace Microsoft.OpenApi.OData.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Org.OData.Core.V1.HttpRequests
|
||||
/// </summary>
|
||||
internal class HttpRequestsHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// The Term type name.
|
||||
/// </summary>
|
||||
public virtual string QualifiedName => "Org.OData.Core.V1.HttpRequests";
|
||||
|
||||
public IEdmTerm Term { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the http request array.
|
||||
/// </summary>
|
||||
public IDictionary<IEdmVocabularyAnnotatable, IList<HttpRequest> > Requests { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Edm mode.
|
||||
/// </summary>
|
||||
public IEdmModel Model { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="HttpRequestsAnnotation"/> class.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
public HttpRequestsHelper(IEdmModel model)
|
||||
{
|
||||
Utils.CheckArgumentNull(model, nameof(model));
|
||||
Term = model.FindTerm(QualifiedName);
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public HttpRequest GetRequest(string method)
|
||||
{
|
||||
if (Requests == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Requests.FirstOrDefault(e => string.Equals(e.MethodType, method, System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
protected virtual HttpRequest FindRequest(IEdmVocabularyAnnotatable target, string method)
|
||||
{
|
||||
if (Requests == null)
|
||||
{
|
||||
Requests = new Dictionary<IEdmVocabularyAnnotatable, IList<HttpRequest>>();
|
||||
}
|
||||
|
||||
IEdmVocabularyAnnotatable newTarget = target;
|
||||
IEdmNavigationSource navigationSource = target as IEdmNavigationSource;
|
||||
if (navigationSource != null)
|
||||
{
|
||||
newTarget = navigationSource.EntityType();
|
||||
}
|
||||
|
||||
if (Requests.TryGetValue(newTarget, out IList<HttpRequest> values))
|
||||
{
|
||||
return values.FirstOrDefault(e => string.Equals(e.MethodType, method, System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
var annotations = Model.FindVocabularyAnnotations<IEdmVocabularyAnnotation>(target, Term);
|
||||
if (annotations != null && annotations.Any())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(Target, QualifiedName);
|
||||
if (annotation == null)
|
||||
{
|
||||
IEdmNavigationSource navigationSource = Target as IEdmNavigationSource;
|
||||
|
||||
// if not, search the entity type.
|
||||
if (navigationSource != null)
|
||||
{
|
||||
IEdmEntityType entityType = navigationSource.EntityType();
|
||||
annotation = Model.GetVocabularyAnnotation(entityType, QualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Collection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value;
|
||||
|
||||
Requests = new List<HttpRequest>();
|
||||
foreach (var item in collection.Elements)
|
||||
{
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)item;
|
||||
HttpRequest request = new HttpRequest();
|
||||
request.Init(record);
|
||||
Requests.Add(request);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
{
|
||||
IEdmVocabularyAnnotation annotation = Model.GetVocabularyAnnotation(Target, QualifiedName);
|
||||
if (annotation == null)
|
||||
{
|
||||
IEdmNavigationSource navigationSource = Target as IEdmNavigationSource;
|
||||
|
||||
// if not, search the entity type.
|
||||
if (navigationSource != null)
|
||||
{
|
||||
IEdmEntityType entityType = navigationSource.EntityType();
|
||||
annotation = Model.GetVocabularyAnnotation(entityType, QualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
if (annotation == null ||
|
||||
annotation.Value == null ||
|
||||
annotation.Value.ExpressionKind != EdmExpressionKind.Collection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEdmCollectionExpression collection = (IEdmCollectionExpression)annotation.Value;
|
||||
|
||||
Requests = new List<HttpRequest>();
|
||||
foreach (var item in collection.Elements)
|
||||
{
|
||||
IEdmRecordExpression record = (IEdmRecordExpression)item;
|
||||
HttpRequest request = new HttpRequest();
|
||||
request.Init(record);
|
||||
Requests.Add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -29,6 +29,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
private bool _keyAsSegmentSupported = false;
|
||||
private IList<OpenApiTag> _tags = new List<OpenApiTag>();
|
||||
private ODataPathHandler _pathHandler;
|
||||
public HttpRequestProvider _httpRequestProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ODataContext"/> class.
|
||||
|
@ -53,13 +54,13 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
visitor.Visit(model);
|
||||
IsSpatialTypeUsed = visitor.IsSpatialTypeUsed;
|
||||
|
||||
|
||||
_pathHandler = new ODataPathHandler(this);
|
||||
|
||||
OperationHanderProvider = new OperationHandlerProvider();
|
||||
PathItemHanderProvider = new PathItemHandlerProvider();
|
||||
|
||||
AuthorizationProvider = new AuthorizationProvider();
|
||||
_httpRequestProvider = new HttpRequestProvider(model);
|
||||
|
||||
if (settings.EnableKeyAsSegment != null)
|
||||
{
|
||||
|
@ -89,8 +90,6 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// </summary>
|
||||
public AuthorizationProvider AuthorizationProvider { get; }
|
||||
|
||||
//public CapabilitiesProvider CapabilitiesProvider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Edm model.
|
||||
/// </summary>
|
||||
|
@ -143,6 +142,17 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the Org.OData.Core.V1.HttpRequest for a given target.
|
||||
/// </summary>
|
||||
/// <param name="target">The target.</param>
|
||||
/// <param name="method">The method name.</param>
|
||||
/// <returns>The <see cref="HttpRequest"/> or null.</returns>
|
||||
public HttpRequest FindRequest(IEdmVocabularyAnnotatable target, string method)
|
||||
{
|
||||
return _httpRequestProvider?.GetHttpRequest(target, method);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the operations using the <see cref="IEdmEntityType"/>
|
||||
/// </summary>
|
||||
|
@ -187,24 +197,6 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
}
|
||||
}
|
||||
|
||||
private IDictionary<IEdmVocabularyAnnotatable, HttpRequestsAnnotation> _requests;
|
||||
|
||||
public HttpRequest FindRequest(IEdmVocabularyAnnotatable target, string method)
|
||||
{
|
||||
if (_requests == null)
|
||||
{
|
||||
_requests = new Dictionary<IEdmVocabularyAnnotatable, HttpRequestsAnnotation>();
|
||||
}
|
||||
|
||||
if (!_requests.TryGetValue(target, out HttpRequestsAnnotation value))
|
||||
{
|
||||
value = new HttpRequestsAnnotation(Model, target);
|
||||
_requests.Add(target, value);
|
||||
}
|
||||
|
||||
return value.GetRequest(method);
|
||||
}
|
||||
|
||||
private void GenerateBoundOperations()
|
||||
{
|
||||
if (_boundOperations != null)
|
||||
|
@ -236,20 +228,5 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
}
|
||||
_tags.Add(tagItem);
|
||||
}
|
||||
|
||||
private IDictionary<string, int> _cached1 = new Dictionary<string, int>();
|
||||
public int GetIndex(string source)
|
||||
{
|
||||
if (_cached1.TryGetValue(source, out int value))
|
||||
{
|
||||
_cached1[source]++;
|
||||
return _cached1[source];
|
||||
}
|
||||
else
|
||||
{
|
||||
_cached1[source] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
if (Context.Settings.OperationId)
|
||||
{
|
||||
string key = "OperationImport." + EdmOperationImport.Name;
|
||||
operation.OperationId += "OperationImport." + Context.GetIndex(key) + "-" + Utils.UpperFirstChar(EdmOperationImport.Name);
|
||||
|
||||
if (EdmOperationImport.IsActionImport())
|
||||
{
|
||||
operation.OperationId = "OperationImport." + EdmOperationImport.Name;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
// Summary
|
||||
operation.Summary = "Delete entity from " + EntitySet.Name;
|
||||
// override the summary using the request.Description.
|
||||
var request = Context.FindRequest(EntitySet.EntityType(), OperationType.ToString());
|
||||
var request = Context.FindRequest(EntitySet, OperationType.ToString());
|
||||
if (request != null && request.Description != null)
|
||||
{
|
||||
operation.Summary = request.Description;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OData.Edm;
|
||||
|
@ -29,7 +28,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
operation.Summary = "Get entity from " + EntitySet.Name + " by key";
|
||||
|
||||
// override the summary using the request.Description.
|
||||
var request = Context.FindRequest(EntitySet.EntityType(), OperationType.ToString());
|
||||
var request = Context.FindRequest(EntitySet, OperationType.ToString());
|
||||
if (request != null && request.Description != null)
|
||||
{
|
||||
operation.Summary = request.Description;
|
||||
|
@ -61,9 +60,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
{
|
||||
operation.Parameters.Add(parameter);
|
||||
}
|
||||
|
||||
var request = Context.FindRequest(EntitySet.EntityType(), OperationType.ToString());
|
||||
AppendCustomParameters(operation, request);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -99,15 +95,5 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
};
|
||||
operation.Responses.Add(Constants.StatusCodeDefault, Constants.StatusCodeDefault.GetResponse());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
var request = Context.FindRequest(EntitySet.EntityType(), OperationType.ToString());
|
||||
if (request != null)
|
||||
{
|
||||
operation.Security = Context.CreateSecurityRequirements(request.SecuritySchemes).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
// Summary
|
||||
operation.Summary = "Update entity in " + EntitySet.Name;
|
||||
// override the summary using the request.Description.
|
||||
var request = Context.FindRequest(EntitySet.EntityType(), OperationType.ToString());
|
||||
var request = Context.FindRequest(EntitySet, OperationType.ToString());
|
||||
if (request != null && request.Description != null)
|
||||
{
|
||||
operation.Summary = request.Description;
|
||||
|
|
|
@ -109,9 +109,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
{
|
||||
operation.Parameters.Add(parameter);
|
||||
}
|
||||
|
||||
var request = Context.FindRequest(EntitySet, OperationType.ToString());
|
||||
AppendCustomParameters(operation, request);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Generator;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation
|
||||
{
|
||||
|
@ -42,5 +44,29 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
Context.AppendTag(tag);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
base.SetSecurity(operation);
|
||||
|
||||
var request = Context.FindRequest(EntitySet, OperationType.ToString());
|
||||
if (request != null)
|
||||
{
|
||||
operation.Security = Context.CreateSecurityRequirements(request.SecuritySchemes).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetParameters(OpenApiOperation operation)
|
||||
{
|
||||
base.SetParameters(operation);
|
||||
|
||||
var request = Context.FindRequest(EntitySet, OperationType.ToString());
|
||||
if (request != null)
|
||||
{
|
||||
AppendCustomParameters(operation, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
Description = param.Description,
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
// Type = param.Type
|
||||
Type = "string"
|
||||
},
|
||||
Required = param.Required ?? false
|
||||
};
|
||||
|
|
|
@ -60,9 +60,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
{
|
||||
operation.Parameters.Add(parameter);
|
||||
}
|
||||
|
||||
var request = Context.FindRequest(Singleton, OperationType.ToString());
|
||||
AppendCustomParameters(operation, request);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Generator;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation
|
||||
{
|
||||
|
@ -45,5 +47,29 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
|
||||
Context.AppendTag(tag);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetSecurity(OpenApiOperation operation)
|
||||
{
|
||||
base.SetSecurity(operation);
|
||||
|
||||
var request = Context.FindRequest(Singleton, OperationType.ToString());
|
||||
if (request != null)
|
||||
{
|
||||
operation.Security = Context.CreateSecurityRequirements(request.SecuritySchemes).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void SetParameters(OpenApiOperation operation)
|
||||
{
|
||||
base.SetParameters(operation);
|
||||
|
||||
var request = Context.FindRequest(Singleton, OperationType.ToString());
|
||||
if (request != null)
|
||||
{
|
||||
AppendCustomParameters(operation, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
using Microsoft.OpenApi.OData.Annotations;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Reader.Annotations.Tests
|
||||
{
|
||||
public class HttpRequestProviderTest
|
||||
{
|
||||
[Fact]
|
||||
public void CtorThrowArgumentNullModel()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("model", () => new HttpRequestProvider(model: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHttpRequestThrowArgumentNullTarget()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("target",
|
||||
() => new HttpRequestProvider(EdmCoreModel.Instance).GetHttpRequest(target: null, method: "GET"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHttpRequestThrowArgumentNullMethod()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentNullException>("method",
|
||||
() => new HttpRequestProvider(EdmCoreModel.Instance).GetHttpRequest(new EdmEntityContainer("NS", "Default"), method: null));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Customers")]
|
||||
[InlineData("Me")]
|
||||
public void GetHttpRequestsReturnsNullForTargetWithoutAnnotations(string name)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel("", "");
|
||||
var httpRequestProvider = new HttpRequestProvider(model);
|
||||
IEdmNavigationSource navigationSource = model.FindDeclaredNavigationSource(name);
|
||||
Assert.NotNull(navigationSource);
|
||||
|
||||
// Act & Assert
|
||||
var requests = httpRequestProvider.GetHttpRequests(navigationSource as IEdmVocabularyAnnotatable);
|
||||
|
||||
// Assert
|
||||
Assert.Null(requests);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Customers")]
|
||||
[InlineData("Me")]
|
||||
public void GetHttpRequestsReturnsForEdmModelNavigationSourceWithAnnotations(string name)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = @"
|
||||
<Annotation Term=""Org.OData.Core.V1.HttpRequests"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Description"" />
|
||||
<PropertyValue Property=""MethodDescription"" String=""Example"" />
|
||||
<PropertyValue Property=""MethodType"" String=""DELETE"" />
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""Authorization"" />
|
||||
<PropertyValue Property=""Description"" String=""String"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomQueryOptions"">
|
||||
<Collection />
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""HttpResponses"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""ResponseCode"" String=""204"" />
|
||||
<PropertyValue Property=""Examples"">
|
||||
<Record Type=""Org.OData.Core.V1.InlineExample"">
|
||||
<PropertyValue Property=""InlineExample"" />
|
||||
<PropertyValue Property=""Description"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""SecuritySchemes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""AuthorizationSchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""RequiredScopes"">
|
||||
<Collection>
|
||||
<String>Directory.AccessAsUser.All</String>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Description"" />
|
||||
<PropertyValue Property=""MethodDescription"" String=""Example"" />
|
||||
<PropertyValue Property=""MethodType"" String=""GET"" />
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""Authorization"" />
|
||||
<PropertyValue Property=""Description"" String=""String"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomQueryOptions"">
|
||||
<Collection />
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""HttpResponses"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""ResponseCode"" String=""200"" />
|
||||
<PropertyValue Property=""Examples"">
|
||||
<Record Type=""Org.OData.Core.V1.InlineExample"">
|
||||
<PropertyValue Property=""InlineExample"" String=""{
 "accountEnabled":false,
 "deviceId":"4c299165-6e8f-4b45-a5ba-c5d250a707ff",
 "displayName":"Test device",
 "id": "id-value",
 "operatingSystem":"linux",
 "operatingSystemVersion":"1"
}
"" />
|
||||
<PropertyValue Property=""Description"" String=""application/json"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""SecuritySchemes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""AuthorizationSchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""RequiredScopes"">
|
||||
<Collection>
|
||||
<String>Directory.Read.All</String>
|
||||
<String>Directory.ReadWrite.All</String>
|
||||
<String>Directory.AccessAsUser.All</String>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""AuthorizationSchemeName"" String=""Application"" />
|
||||
<PropertyValue Property=""RequiredScopes"">
|
||||
<Collection>
|
||||
<String>Device.ReadWrite.All</String>
|
||||
<String>Directory.Read.All</String>
|
||||
<String>Directory.ReadWrite.All</String>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
<Record>
|
||||
<PropertyValue Property=""Description"" />
|
||||
<PropertyValue Property=""MethodDescription"" String=""PATCH Example"" />
|
||||
<PropertyValue Property=""MethodType"" String=""PATCH"" />
|
||||
<PropertyValue Property=""CustomHeaders"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""Name"" String=""Authorization"" />
|
||||
<PropertyValue Property=""Description"" String=""String"" />
|
||||
<PropertyValue Property=""Required"" Bool=""false"" />
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""CustomQueryOptions"">
|
||||
<Collection />
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""HttpResponses"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""ResponseCode"" String=""204"" />
|
||||
<PropertyValue Property=""Examples"">
|
||||
<Record Type=""Org.OData.Core.V1.InlineExample"">
|
||||
<PropertyValue Property=""InlineExample"" />
|
||||
<PropertyValue Property=""Description"" />
|
||||
</Record>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
<PropertyValue Property=""SecuritySchemes"">
|
||||
<Collection>
|
||||
<Record>
|
||||
<PropertyValue Property=""AuthorizationSchemeName"" String=""Delegated (work or school account)"" />
|
||||
<PropertyValue Property=""RequiredScopes"">
|
||||
<Collection>
|
||||
<String>Directory.ReadWrite.All</String>
|
||||
<String>Directory.AccessAsUser.All</String>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Collection>
|
||||
</Annotation>";
|
||||
|
||||
IEdmModel model = GetEdmModel(annotation, annotation);
|
||||
var httpRequestProvider = new HttpRequestProvider(model);
|
||||
|
||||
IEdmNavigationSource navigationSource = model.FindDeclaredNavigationSource(name);
|
||||
Assert.NotNull(navigationSource);
|
||||
|
||||
// Act
|
||||
var requests = httpRequestProvider.GetHttpRequests(navigationSource as IEdmVocabularyAnnotatable);
|
||||
|
||||
// Assert
|
||||
Assert.NotEmpty(requests);
|
||||
Assert.Equal(3, requests.Count());
|
||||
|
||||
// Act
|
||||
var anotherRequests = httpRequestProvider.GetHttpRequests(navigationSource as IEdmVocabularyAnnotatable);
|
||||
|
||||
// Assert
|
||||
Assert.True(ReferenceEquals(requests, anotherRequests));
|
||||
|
||||
// Act (PATCH)
|
||||
var request = httpRequestProvider.GetHttpRequest(navigationSource as IEdmVocabularyAnnotatable, "PATCH");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(request);
|
||||
Assert.Equal("PATCH Example", request.MethodDescription);
|
||||
Assert.NotNull(request.SecuritySchemes);
|
||||
var securityScheme = Assert.Single(request.SecuritySchemes);
|
||||
Assert.Equal("Delegated (work or school account)", securityScheme.AuthorizationSchemeName);
|
||||
Assert.NotNull(securityScheme.RequiredScopes);
|
||||
Assert.Equal(new[] { "Directory.ReadWrite.All", "Directory.AccessAsUser.All" }, securityScheme.RequiredScopes);
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string entitySetAnnotation, string singletonAnnotation)
|
||||
{
|
||||
string template = @"<?xml version=""1.0"" encoding=""utf-16""?>
|
||||
<edmx:Edmx xmlns:ags=""http://aggregator.microsoft.com/internal"" Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""Customer"">
|
||||
<Key>
|
||||
<PropertyRef Name=""Id"" />
|
||||
</Key>
|
||||
<Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
</EntityType>
|
||||
<EntityContainer Name=""Container"">
|
||||
<EntitySet Name=""Customers"" EntityType=""NS.Customer"">
|
||||
{0}
|
||||
</EntitySet>
|
||||
<Singleton Name=""Me"" Type=""NS.Customer"" >
|
||||
{1}
|
||||
</Singleton>
|
||||
</EntityContainer>
|
||||
</Schema>
|
||||
<Schema Namespace=""Org.OData.Core.V1"" Alias=""Core"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<Term Name=""HttpRequests"" Type=""Collection(Core.HttpRequest)"" AppliesTo=""EntitySet Singleton ActionImport FunctionImport Action Function"">
|
||||
<Annotation Term=""Core.Description"" String=""Describes possible HTTP requests"" />
|
||||
<Annotation Term=""Core.LongDescription"" String=""The list need not be complete. It may be used to generate API documentation, so restricting it to the most common and most important responses may increase readability."" />
|
||||
</Term>
|
||||
<ComplexType Name=""HttpRequest"">
|
||||
<Property Name=""Description"" Type=""Edm.String"" />
|
||||
<!-- text such as ""For a specific user:"" to describe the http request-->
|
||||
<Property Name=""Method"" Type=""Edm.String"" />
|
||||
<Property Name=""CustomQueryOptions"" Type=""Collection(Core.CustomParameter)"" />
|
||||
<Property Name=""CustomHeaders"" Type=""Collection(Core.CustomParameter)"" /> <!-- Map to Parameter in Operation as Header object.-->
|
||||
<Property Name=""HttpResponses"" Type=""Collection(Core.HttpResponse)"" /> <!-- Map to Response object in Operation. -->
|
||||
<Property Name=""SecuritySchemes"" Type=""Collection(Auth.SecurityScheme)""/>
|
||||
</ComplexType>
|
||||
<ComplexType Name=""HttpResponse"">
|
||||
<Property Name=""ResponseCode"" Type=""Edm.String"" />
|
||||
<Property Name=""Examples"" Type=""Collection(Core.Example)"" />
|
||||
<Property Name=""Description"" Type=""Edm.String"" />
|
||||
</ComplexType>
|
||||
<ComplexType Name=""CustomParameter"">
|
||||
<Property Name=""Name"" Type=""Edm.String"" Nullable=""false"" />
|
||||
<Property Name=""Description"" Type=""Edm.String"" />
|
||||
<Property Name=""DocumentationURL"" Type=""Edm.String"" />
|
||||
<Property Name=""Required"" Type=""Edm.Boolean"" Nullable=""false"" />
|
||||
<Property Name=""ExampleValues"" Type=""Collection(Core.Example)"" Nullable=""false"" />
|
||||
</ComplexType>
|
||||
<ComplexType Name=""Example"" Abstract=""true"">
|
||||
<Property Name=""Description"" Type=""Edm.String"" Nullable=""false"" />
|
||||
</ComplexType>
|
||||
<ComplexType Name=""ExternalExample"" BaseType=""Core.Example"">
|
||||
<Property Name=""ExternalValue"" Type=""Edm.String"" Nullable=""false"" />
|
||||
</ComplexType>
|
||||
<ComplexType Name=""InlineExample"" BaseType=""Core.Example"">
|
||||
<Property Name=""InlineValue"" Type=""Edm.String"" Nullable=""false"" />
|
||||
</ComplexType>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>
|
||||
";
|
||||
string modelText = string.Format(template, entitySetAnnotation, singletonAnnotation);
|
||||
|
||||
return CsdlReader.Parse(XElement.Parse(modelText).CreateReader());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,6 +20,10 @@ namespace UpdateDocs
|
|||
{
|
||||
static int Main(string[] args)
|
||||
{
|
||||
if (!Test())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// we assume the path are existed for simplicity.
|
||||
string path = Directory.GetCurrentDirectory();
|
||||
string csdl = path + "../../../../../../docs/csdl";
|
||||
|
@ -75,6 +79,15 @@ namespace UpdateDocs
|
|||
return 0;
|
||||
}
|
||||
|
||||
public static bool Test()
|
||||
{
|
||||
var model = LoadEdmModel(@"E:\work\OpenApi\metadata_withRequestTerms.xml");
|
||||
OpenApiDocument document = model.ConvertToOpenApi();
|
||||
string output = @"E:\work\OpenApi\metadata_withRequestTerms.json";
|
||||
File.WriteAllText(output, document.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0));
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEdmModel LoadEdmModel(string file)
|
||||
{
|
||||
try
|
||||
|
|
Loading…
Reference in a new issue