diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/EdmAnnotationExtensions.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/EdmAnnotationExtensions.cs
index 9da97a5d..1568fa79 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Edm/EdmAnnotationExtensions.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Edm/EdmAnnotationExtensions.cs
@@ -67,6 +67,19 @@ internal static class EdmVocabularyAnnotationExtensions
});
}
+ public static bool? GetBoolean(this IEdmModel model, string targetPath, string qualifiedName)
+ {
+ Utils.CheckArgumentNull(model, nameof(model));
+ Utils.CheckArgumentNull(targetPath, nameof(targetPath));
+ Utils.CheckArgumentNull(qualifiedName, nameof(qualifiedName));
+
+ IEdmTargetPath target = model.GetTargetPath(targetPath);
+ if (target == null)
+ return default;
+
+ return model.GetBoolean(target, qualifiedName);
+ }
+
///
/// Gets the string term value for the given .
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPath.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPath.cs
index 254d1325..e3a28619 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPath.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPath.cs
@@ -145,7 +145,6 @@ public string GetPathItemName(OpenApiConvertSettings settings)
Utils.CheckArgumentNull(settings, nameof(settings));
// From Open API spec, parameter name is case sensitive, so don't use the IgnoreCase HashSet.
- // HashSet parameters = new HashSet(StringComparer.OrdinalIgnoreCase);
HashSet parameters = new();
StringBuilder sb = new();
@@ -238,7 +237,6 @@ internal IDictionary> CalculateParamet
IDictionary> parameterMapping = new Dictionary>();
// From Open API spec, parameter name is case sensitive, so don't use the IgnoreCase HashSet.
- // HashSet parameters = new HashSet(StringComparer.OrdinalIgnoreCase);
HashSet parameters = new HashSet();
foreach (var segment in Segments)
@@ -259,6 +257,28 @@ internal IDictionary> CalculateParamet
return parameterMapping;
}
+ ///
+ /// Get string representation of the Edm Target Path for annotations
+ ///
+ /// The Edm model.
+ /// The string representation of the Edm target path.
+ internal string GetTargetPath(IEdmModel model)
+ {
+ Utils.CheckArgumentNull(model, nameof(model));
+
+ var targetPath = new StringBuilder(model.EntityContainer.FullName());
+
+ bool skipLastSegment = LastSegment is ODataRefSegment
+ || LastSegment is ODataDollarCountSegment
+ || LastSegment is ODataStreamContentSegment;
+ foreach (var segment in Segments.Where(segment => segment is not ODataKeySegment
+ && !(skipLastSegment && segment == LastSegment)))
+ {
+ targetPath.Append($"/{segment.Identifier}");
+ }
+ return targetPath.ToString();
+ }
+
///
/// Output the path string.
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs
index 7a3e3ba9..0a2197f3 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs
@@ -249,7 +249,9 @@ private void RetrieveNavigationSourcePaths(IEdmNavigationSource navigationSource
// for entity set, create a path with key and a $count path
if (entitySet != null)
{
- count = _model.GetRecord(entitySet, CapabilitiesConstants.CountRestrictions);
+ string targetPath = path.GetTargetPath(_model);
+ count = _model.GetRecord(targetPath, CapabilitiesConstants.CountRestrictions)
+ ?? _model.GetRecord(entitySet, CapabilitiesConstants.CountRestrictions);
if(count?.Countable ?? true) // ~/entitySet/$count
CreateCountPath(path, convertSettings);
@@ -310,16 +312,22 @@ private void RetrieveComplexPropertyPaths(IEdmEntityType entityType, ODataPath c
.Where(x => x.Type.IsComplex() ||
x.Type.IsCollection() && x.Type.Definition.AsElementType() is IEdmComplexType))
{
- if (!ShouldCreateComplexPropertyPaths(sp, convertSettings)) continue;
-
currentPath.Push(new ODataComplexPropertySegment(sp));
+ var targetPath = currentPath.GetTargetPath(_model);
+ if (!ShouldCreateComplexPropertyPaths(sp, targetPath, convertSettings))
+ {
+ currentPath.Pop();
+ continue;
+ }
AppendPath(currentPath.Clone());
if (sp.Type.IsCollection())
{
CreateTypeCastPaths(currentPath, convertSettings, sp.Type.Definition.AsElementType() as IEdmComplexType, sp, true);
- var count = _model.GetRecord(sp, CapabilitiesConstants.CountRestrictions);
- if (count?.IsCountable ?? true)
+ var isCountable = _model.GetRecord(targetPath, CapabilitiesConstants.CountRestrictions)?.IsCountable
+ ?? _model.GetRecord(sp, CapabilitiesConstants.CountRestrictions)?.IsCountable
+ ?? true;
+ if (isCountable)
CreateCountPath(currentPath, convertSettings);
}
else
@@ -363,7 +371,9 @@ private bool RetrieveComplexTypeNavigationPropertyPaths(IEdmComplexType complexT
foreach (var np in navigationProperties)
{
- var count = _model.GetRecord(np, CapabilitiesConstants.CountRestrictions);
+ var targetPath = currentPath.GetTargetPath(_model);
+ var count = _model.GetRecord(targetPath, CapabilitiesConstants.CountRestrictions)
+ ?? _model.GetRecord(np, CapabilitiesConstants.CountRestrictions);
RetrieveNavigationPropertyPaths(np, count, currentPath, convertSettings);
}
@@ -407,9 +417,10 @@ private void TraverseComplexProperty(IEdmStructuralProperty structuralProperty,
/// Evaluates whether or not to create paths for complex properties.
///
/// The target complex property.
+ /// The annotation target path for the complex property.
/// The settings for the current conversion.
/// true or false.
- private bool ShouldCreateComplexPropertyPaths(IEdmStructuralProperty complexProperty, OpenApiConvertSettings convertSettings)
+ private bool ShouldCreateComplexPropertyPaths(IEdmStructuralProperty complexProperty, string targetPath, OpenApiConvertSettings convertSettings)
{
Utils.CheckArgumentNull(complexProperty, nameof(complexProperty));
Utils.CheckArgumentNull(convertSettings, nameof(convertSettings));
@@ -417,9 +428,15 @@ private bool ShouldCreateComplexPropertyPaths(IEdmStructuralProperty complexProp
if (!convertSettings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
return true;
- bool isReadable = _model.GetRecord(complexProperty, CapabilitiesConstants.ReadRestrictions)?.Readable ?? false;
- bool isUpdatable = _model.GetRecord(complexProperty, CapabilitiesConstants.UpdateRestrictions)?.Updatable ?? false;
- bool isInsertable = _model.GetRecord(complexProperty, CapabilitiesConstants.InsertRestrictions)?.Insertable ?? false;
+ bool isReadable = _model.GetRecord(targetPath, CapabilitiesConstants.ReadRestrictions)?.Readable
+ ?? _model.GetRecord(complexProperty, CapabilitiesConstants.ReadRestrictions)?.Readable
+ ?? false;
+ bool isUpdatable = _model.GetRecord(targetPath, CapabilitiesConstants.UpdateRestrictions)?.Updatable
+ ??_model.GetRecord(complexProperty, CapabilitiesConstants.UpdateRestrictions)?.Updatable
+ ?? false;
+ bool isInsertable = _model.GetRecord(targetPath, CapabilitiesConstants.InsertRestrictions)?.Insertable
+ ?? _model.GetRecord(complexProperty, CapabilitiesConstants.InsertRestrictions)?.Insertable
+ ?? false;
return isReadable || isUpdatable || isInsertable;
}
@@ -525,9 +542,13 @@ private void RetrieveNavigationPropertyPaths(
AppendPath(currentPath.Clone());
visitedNavigationProperties.Push(navPropFullyQualifiedName);
+ // For fetching annotations
+ var targetPath = currentPath.GetTargetPath(_model);
+
// Check whether a collection-valued navigation property should be indexed by key value(s).
// Find indexability annotation annotated directly via NavigationPropertyRestriction.
- bool? annotatedIndexability = _model.GetBoolean(navigationProperty, CapabilitiesConstants.IndexableByKey);
+ bool? annotatedIndexability = _model.GetBoolean(targetPath, CapabilitiesConstants.IndexableByKey)
+ ?? _model.GetBoolean(navigationProperty, CapabilitiesConstants.IndexableByKey);
bool indexableByKey = true;
if (restriction?.IndexableByKey != null)
@@ -550,7 +571,8 @@ private void RetrieveNavigationPropertyPaths(
if (count == null)
{
// First, get the directly annotated restriction annotation of the navigation property
- count = _model.GetRecord(navigationProperty, CapabilitiesConstants.CountRestrictions);
+ count = _model.GetRecord(targetPath, CapabilitiesConstants.CountRestrictions)
+ ?? _model.GetRecord(navigationProperty, CapabilitiesConstants.CountRestrictions);
createCountPath = count?.Countable;
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiParameterGenerator.cs b/src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiParameterGenerator.cs
index 439dc631..39e152c5 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiParameterGenerator.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Generator/OpenApiParameterGenerator.cs
@@ -455,7 +455,6 @@ public static OpenApiParameter CreateSearch(this ODataContext context, IEdmVocab
return null;
}
-
///
/// Create the $search parameter for Edm target path.
///
@@ -558,6 +557,18 @@ public static OpenApiParameter CreateFilter(this ODataContext context, string ta
return context.CreateFilter(target);
}
+ public static OpenApiParameter CreateOrderBy(this ODataContext context, string targetPath, IEdmEntityType entityType)
+ {
+ Utils.CheckArgumentNull(context, nameof(context));
+ Utils.CheckArgumentNull(targetPath, nameof(targetPath));
+
+ IEdmTargetPath target = context.Model.GetTargetPath(targetPath);
+ if (target == null)
+ return null;
+
+ return context.CreateOrderBy(target, entityType);
+ }
+
public static OpenApiParameter CreateOrderBy(this ODataContext context, IEdmEntitySet entitySet)
{
Utils.CheckArgumentNull(context, nameof(context));
@@ -592,7 +603,17 @@ public static OpenApiParameter CreateOrderBy(this ODataContext context, IEdmNavi
public static OpenApiParameter CreateOrderBy(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmEntityType entityType)
{// patchwork to avoid breaking changes
return context.CreateOrderBy(target, entityType as IEdmStructuredType);
+ }
+
+ public static OpenApiParameter CreateOrderBy(this ODataContext context, string targetPath, IEdmStructuredType structuredType)
+ {
+ IEdmTargetPath target = context.Model.GetTargetPath(targetPath);
+ if (target == null)
+ return null;
+
+ return context.CreateOrderBy(target, structuredType);
}
+
public static OpenApiParameter CreateOrderBy(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmStructuredType structuredType)
{
Utils.CheckArgumentNull(context, nameof(context));
@@ -653,6 +674,18 @@ public static OpenApiParameter CreateOrderBy(this ODataContext context, IEdmVoca
};
}
+ public static OpenApiParameter CreateSelect(this ODataContext context, string targetPath, IEdmEntityType entityType)
+ {
+ Utils.CheckArgumentNull(context, nameof(context));
+ Utils.CheckArgumentNull(targetPath, nameof(targetPath));
+
+ IEdmTargetPath target = context.Model.GetTargetPath(targetPath);
+ if (target == null)
+ return null;
+
+ return context.CreateSelect(target, entityType);
+ }
+
public static OpenApiParameter CreateSelect(this ODataContext context, IEdmEntitySet entitySet)
{
Utils.CheckArgumentNull(context, nameof(context));
@@ -688,6 +721,16 @@ public static OpenApiParameter CreateSelect(this ODataContext context, IEdmVocab
{ // patchwork to avoid breaking changes
return context.CreateSelect(target, entityType as IEdmStructuredType);
}
+
+ public static OpenApiParameter CreateSelect(this ODataContext context, string targetPath, IEdmStructuredType structuredType)
+ {
+ IEdmTargetPath target = context.Model.GetTargetPath(targetPath);
+ if (target == null)
+ return null;
+
+ return context.CreateSelect(target, structuredType);
+ }
+
public static OpenApiParameter CreateSelect(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmStructuredType structuredType)
{
Utils.CheckArgumentNull(context, nameof(context));
@@ -736,6 +779,19 @@ public static OpenApiParameter CreateSelect(this ODataContext context, IEdmVocab
Explode = false
};
}
+
+ public static OpenApiParameter CreateExpand(this ODataContext context, string targetPath, IEdmEntityType entityType)
+ {
+ Utils.CheckArgumentNull(context, nameof(context));
+ Utils.CheckArgumentNull(targetPath, nameof(targetPath));
+
+ IEdmTargetPath target = context.Model.GetTargetPath(targetPath);
+ if (target == null)
+ return null;
+
+ return context.CreateExpand(target, entityType);
+ }
+
public static OpenApiParameter CreateExpand(this ODataContext context, IEdmEntitySet entitySet)
{
Utils.CheckArgumentNull(context, nameof(context));
@@ -771,6 +827,16 @@ public static OpenApiParameter CreateExpand(this ODataContext context, IEdmVocab
{ // patchwork to avoid breaking changes
return context.CreateExpand(target, entityType as IEdmStructuredType);
}
+
+ public static OpenApiParameter CreateExpand(this ODataContext context, string targetPath, IEdmStructuredType structuredType)
+ {
+ IEdmTargetPath target = context.Model.GetTargetPath(targetPath);
+ if (target == null)
+ return null;
+
+ return context.CreateExpand(target, structuredType);
+ }
+
public static OpenApiParameter CreateExpand(this ODataContext context, IEdmVocabularyAnnotatable target, IEdmStructuredType structuredType)
{
Utils.CheckArgumentNull(context, nameof(context));
diff --git a/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj b/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
index 1a83e5b0..f0cf95ca 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
+++ b/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
@@ -15,13 +15,13 @@
netstandard2.0
Microsoft.OpenApi.OData
true
- 1.6.4
+ 1.6.5
This package contains the codes you need to convert OData CSDL to Open API Document of Model.
© Microsoft Corporation. All rights reserved.
Microsoft OpenApi OData EDM
https://github.com/Microsoft/OpenAPI.NET.OData
- - Add support for Edm.Untyped #511
+ - Use annotations with path as target to dermine whether to add an operation #535
Microsoft.OpenApi.OData.Reader
..\..\tool\Microsoft.OpenApi.OData.snk
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs
index 00db6ab1..42a163e2 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyGetOperationHandler.cs
@@ -28,15 +28,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
var complexPropertyReadRestrictions = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.ReadRestrictions);
-
- if (_readRestrictions == null)
- {
- _readRestrictions = complexPropertyReadRestrictions;
- }
- else
- {
- _readRestrictions.MergePropertiesIfNull(complexPropertyReadRestrictions);
- }
+ _readRestrictions?.MergePropertiesIfNull(complexPropertyReadRestrictions);
+ _readRestrictions ??= complexPropertyReadRestrictions;
}
///
@@ -108,7 +101,8 @@ protected override void SetParameters(OpenApiOperation operation)
// of just providing a comma-separated list of properties can be expressed via an array-valued
// parameter with an enum constraint
// $order
- parameter = Context.CreateOrderBy(ComplexPropertySegment.Property, ComplexPropertySegment.ComplexType);
+ parameter = Context.CreateOrderBy(TargetPath, ComplexPropertySegment.ComplexType)
+ ?? Context.CreateOrderBy(ComplexPropertySegment.Property, ComplexPropertySegment.ComplexType);
if (parameter != null)
{
operation.Parameters.Add(parameter);
@@ -116,14 +110,16 @@ protected override void SetParameters(OpenApiOperation operation)
}
// $select
- parameter = Context.CreateSelect(ComplexPropertySegment.Property, ComplexPropertySegment.ComplexType);
+ parameter = Context.CreateSelect(TargetPath, ComplexPropertySegment.ComplexType)
+ ?? Context.CreateSelect(ComplexPropertySegment.Property, ComplexPropertySegment.ComplexType);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
// $expand
- parameter = Context.CreateExpand(ComplexPropertySegment.Property, ComplexPropertySegment.ComplexType);
+ parameter = Context.CreateExpand(TargetPath, ComplexPropertySegment.ComplexType)
+ ?? Context.CreateExpand(ComplexPropertySegment.Property, ComplexPropertySegment.ComplexType);
if (parameter != null)
{
operation.Parameters.Add(parameter);
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs
index 4efb8d23..50b58e12 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyPostOperationHandler.cs
@@ -28,15 +28,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_insertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
var complexPropertyInsertRestrictions = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.InsertRestrictions);
-
- if (_insertRestrictions == null)
- {
- _insertRestrictions = complexPropertyInsertRestrictions;
- }
- else
- {
- _insertRestrictions.MergePropertiesIfNull(complexPropertyInsertRestrictions);
- }
+ _insertRestrictions?.MergePropertiesIfNull(complexPropertyInsertRestrictions);
+ _insertRestrictions ??= complexPropertyInsertRestrictions;
}
///
public override OperationType OperationType => OperationType.Post;
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs
index 8830276d..d3790baa 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ComplexPropertyUpdateOperationHandler.cs
@@ -25,15 +25,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
var complexPropertyUpdateRestrictions = Context.Model.GetRecord(ComplexPropertySegment.Property, CapabilitiesConstants.UpdateRestrictions);
-
- if (_updateRestrictions == null)
- {
- _updateRestrictions = complexPropertyUpdateRestrictions;
- }
- else
- {
- _updateRestrictions.MergePropertiesIfNull(complexPropertyUpdateRestrictions);
- }
+ _updateRestrictions?.MergePropertiesIfNull(complexPropertyUpdateRestrictions);
+ _updateRestrictions ??= complexPropertyUpdateRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/DollarCountGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/DollarCountGetOperationHandler.cs
index 1bf4551d..74082736 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/DollarCountGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/DollarCountGetOperationHandler.cs
@@ -201,15 +201,8 @@ protected override void AppendCustomParameters(OpenApiOperation operation)
ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
ReadRestrictionsType annotatableReadRestrictions = Context.Model.GetRecord(annotatable, CapabilitiesConstants.ReadRestrictions);
-
- if (readRestrictions == null)
- {
- readRestrictions = annotatableReadRestrictions;
- }
- else
- {
- readRestrictions.MergePropertiesIfNull(annotatableReadRestrictions);
- }
+ readRestrictions?.MergePropertiesIfNull(annotatableReadRestrictions);
+ readRestrictions ??= annotatableReadRestrictions;
if (readRestrictions == null)
{
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs
index 204642de..e099e371 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs
@@ -28,15 +28,8 @@ protected override void SetBasicInfo(OpenApiOperation operation)
InsertRestrictionsType insertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
InsertRestrictionsType operationReadRestrictions = Context.Model.GetRecord(EdmOperation, CapabilitiesConstants.InsertRestrictions);
-
- if (insertRestrictions == null)
- {
- insertRestrictions = operationReadRestrictions;
- }
- else
- {
- insertRestrictions.MergePropertiesIfNull(operationReadRestrictions);
- }
+ insertRestrictions?.MergePropertiesIfNull(operationReadRestrictions);
+ insertRestrictions ??= operationReadRestrictions;
// Description
if (!string.IsNullOrWhiteSpace(insertRestrictions?.LongDescription))
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs
index 85a8f3b1..60184c8f 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs
@@ -32,15 +32,8 @@ protected override void SetBasicInfo(OpenApiOperation operation)
ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
ReadRestrictionsType operationReadRestrictions = Context.Model.GetRecord(EdmOperation, CapabilitiesConstants.ReadRestrictions);
-
- if (readRestrictions == null)
- {
- readRestrictions = operationReadRestrictions;
- }
- else
- {
- readRestrictions.MergePropertiesIfNull(operationReadRestrictions);
- }
+ readRestrictions?.MergePropertiesIfNull(operationReadRestrictions);
+ readRestrictions ??= operationReadRestrictions;
// Description
if (!string.IsNullOrWhiteSpace(readRestrictions?.LongDescription))
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
index 0db40d2c..72ebb225 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
@@ -59,15 +59,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_operationRestriction = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.OperationRestrictions);
var operationRestrictions = Context.Model.GetRecord(EdmOperation, CapabilitiesConstants.OperationRestrictions);
-
- if (_operationRestriction == null)
- {
- _operationRestriction = operationRestrictions;
- }
- else
- {
- _operationRestriction.MergePropertiesIfNull(operationRestrictions);
- }
+ _operationRestriction?.MergePropertiesIfNull(operationRestrictions);
+ _operationRestriction ??= operationRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs
index db909513..b50b78f1 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityDeleteOperationHandler.cs
@@ -31,15 +31,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_deleteRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.DeleteRestrictions);
var entityDeleteRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.DeleteRestrictions);
-
- if (_deleteRestrictions == null)
- {
- _deleteRestrictions = entityDeleteRestrictions;
- }
- else
- {
- _deleteRestrictions.MergePropertiesIfNull(entityDeleteRestrictions);
- }
+ _deleteRestrictions?.MergePropertiesIfNull(entityDeleteRestrictions);
+ _deleteRestrictions ??= entityDeleteRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs
index 75af3544..9a0cfd23 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityGetOperationHandler.cs
@@ -32,15 +32,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
var entityReadRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions);
-
- if (_readRestrictions == null)
- {
- _readRestrictions = entityReadRestrictions;
- }
- else
- {
- _readRestrictions.MergePropertiesIfNull(entityReadRestrictions);
- }
+ _readRestrictions?.MergePropertiesIfNull(entityReadRestrictions);
+ _readRestrictions ??= entityReadRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs
index cb971654..de4f9d30 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetGetOperationHandler.cs
@@ -33,15 +33,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
var entityReadRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions);
-
- if (_readRestrictions == null)
- {
- _readRestrictions = entityReadRestrictions;
- }
- else
- {
- _readRestrictions.MergePropertiesIfNull(entityReadRestrictions);
- }
+ _readRestrictions?.MergePropertiesIfNull(entityReadRestrictions);
+ _readRestrictions ??= entityReadRestrictions;
}
///
@@ -124,21 +117,21 @@ protected override void SetParameters(OpenApiOperation operation)
// of just providing a comma-separated list of properties can be expressed via an array-valued
// parameter with an enum constraint
// $order
- parameter = Context.CreateOrderBy(EntitySet);
+ parameter = Context.CreateOrderBy(TargetPath, EntitySet.EntityType()) ?? Context.CreateOrderBy(EntitySet);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
// $select
- parameter = Context.CreateSelect(EntitySet);
+ parameter = Context.CreateSelect(TargetPath, EntitySet.EntityType()) ?? Context.CreateSelect(EntitySet);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
// $expand
- parameter = Context.CreateExpand(EntitySet);
+ parameter = Context.CreateExpand(TargetPath, EntitySet.EntityType()) ?? Context.CreateExpand(EntitySet);
if (parameter != null)
{
operation.Parameters.Add(parameter);
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs
index 28cb40d7..aabe1057 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntitySetPostOperationHandler.cs
@@ -33,15 +33,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_insertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
var entityInsertRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.InsertRestrictions);
-
- if (_insertRestrictions == null)
- {
- _insertRestrictions = entityInsertRestrictions;
- }
- else
- {
- _insertRestrictions.MergePropertiesIfNull(entityInsertRestrictions);
- }
+ _insertRestrictions?.MergePropertiesIfNull(entityInsertRestrictions);
+ _insertRestrictions ??= entityInsertRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs
index fa30d859..7ce526df 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EntityUpdateOperationHandler.cs
@@ -27,15 +27,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
var entityUpdateRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.UpdateRestrictions);
-
- if (_updateRestrictions == null)
- {
- _updateRestrictions = entityUpdateRestrictions;
- }
- else
- {
- _updateRestrictions.MergePropertiesIfNull(entityUpdateRestrictions);
- }
+ _updateRestrictions?.MergePropertiesIfNull(entityUpdateRestrictions);
+ _updateRestrictions ??= entityUpdateRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityDeleteOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityDeleteOperationHandler.cs
index d8b18ac7..54e712a2 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityDeleteOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityDeleteOperationHandler.cs
@@ -26,19 +26,13 @@ protected override void Initialize(ODataContext context, ODataPath path)
{
var navigationDeleteRestrictions = Context.Model.GetRecord(Property, CapabilitiesConstants.NavigationRestrictions)?
.RestrictedProperties?.FirstOrDefault()?.DeleteRestrictions;
- if (_deleteRestrictions != null && navigationDeleteRestrictions != null)
- {
- _deleteRestrictions.MergePropertiesIfNull(navigationDeleteRestrictions);
- }
+ _deleteRestrictions?.MergePropertiesIfNull(navigationDeleteRestrictions);
_deleteRestrictions ??= navigationDeleteRestrictions;
}
else
{
var propertyDeleteRestrictions = Context.Model.GetRecord(Property, CapabilitiesConstants.DeleteRestrictions);
- if (_deleteRestrictions != null && propertyDeleteRestrictions != null)
- {
- _deleteRestrictions.MergePropertiesIfNull(propertyDeleteRestrictions);
- }
+ _deleteRestrictions?.MergePropertiesIfNull(propertyDeleteRestrictions);
_deleteRestrictions ??= propertyDeleteRestrictions;
}
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs
index a0cd1951..125141e9 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityGetOperationHandler.cs
@@ -34,19 +34,13 @@ protected override void Initialize(ODataContext context, ODataPath path)
{
var navigationReadRestrictions = Context.Model.GetRecord(Property, CapabilitiesConstants.NavigationRestrictions)?
.RestrictedProperties?.FirstOrDefault()?.ReadRestrictions;
- if (_readRestrictions != null && navigationReadRestrictions != null)
- {
- _readRestrictions.MergePropertiesIfNull(navigationReadRestrictions);
- }
+ _readRestrictions?.MergePropertiesIfNull(navigationReadRestrictions);
_readRestrictions ??= navigationReadRestrictions;
}
else
{
var propertyReadRestrictions = Context.Model.GetRecord(Property, CapabilitiesConstants.ReadRestrictions);
- if (_readRestrictions != null && propertyReadRestrictions != null)
- {
- _readRestrictions.MergePropertiesIfNull(propertyReadRestrictions);
- }
+ _readRestrictions?.MergePropertiesIfNull(propertyReadRestrictions);
_readRestrictions ??= propertyReadRestrictions;
}
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs
index 722f06ac..20f810b8 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/MediaEntityPutOperationHandler.cs
@@ -36,19 +36,13 @@ protected override void Initialize(ODataContext context, ODataPath path)
{
var navigationUpdateRestrictions = Context.Model.GetRecord(Property, CapabilitiesConstants.NavigationRestrictions)?
.RestrictedProperties?.FirstOrDefault()?.UpdateRestrictions;
- if (_updateRestrictions != null && navigationUpdateRestrictions != null)
- {
- _updateRestrictions.MergePropertiesIfNull(navigationUpdateRestrictions);
- }
+ _updateRestrictions?.MergePropertiesIfNull(navigationUpdateRestrictions);
_updateRestrictions ??= navigationUpdateRestrictions;
}
else
{
var propertyUpdateRestrictions = Context.Model.GetRecord(Property, CapabilitiesConstants.UpdateRestrictions);
- if (_updateRestrictions != null && propertyUpdateRestrictions != null)
- {
- _updateRestrictions.MergePropertiesIfNull(propertyUpdateRestrictions);
- }
+ _updateRestrictions?.MergePropertiesIfNull(propertyUpdateRestrictions);
_updateRestrictions ??= propertyUpdateRestrictions;
}
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs
index 22e6cb03..fd94a4f5 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyGetOperationHandler.cs
@@ -165,6 +165,12 @@ protected override void SetParameters(OpenApiOperation operation)
{
base.SetParameters(operation);
+ OpenApiParameter selectParameter = Context.CreateSelect(TargetPath, NavigationProperty.ToEntityType())
+ ?? Context.CreateSelect(NavigationProperty);
+
+ OpenApiParameter expandParameter = Context.CreateExpand(TargetPath, NavigationProperty.ToEntityType())
+ ?? Context.CreateExpand(NavigationProperty);
+
if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
{
// Need to verify that TopSupported or others should be applied to navigation source.
@@ -199,36 +205,32 @@ protected override void SetParameters(OpenApiOperation operation)
operation.Parameters.Add(parameter);
}
- parameter = Context.CreateOrderBy(NavigationProperty);
+ parameter = Context.CreateOrderBy(TargetPath, NavigationProperty.ToEntityType()) ?? Context.CreateOrderBy(NavigationProperty);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
- parameter = Context.CreateSelect(NavigationProperty);
- if (parameter != null)
+ if (selectParameter != null)
{
- operation.Parameters.Add(parameter);
+ operation.Parameters.Add(selectParameter);
}
- parameter = Context.CreateExpand(NavigationProperty);
- if (parameter != null)
+ if (expandParameter != null)
{
- operation.Parameters.Add(parameter);
+ operation.Parameters.Add(expandParameter);
}
}
else
{
- OpenApiParameter parameter = Context.CreateSelect(NavigationProperty);
- if (parameter != null)
+ if (selectParameter != null)
{
- operation.Parameters.Add(parameter);
+ operation.Parameters.Add(selectParameter);
}
- parameter = Context.CreateExpand(NavigationProperty);
- if (parameter != null)
+ if (expandParameter != null)
{
- operation.Parameters.Add(parameter);
+ operation.Parameters.Add(expandParameter);
}
}
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs
index d7eb990a..8bdbacc7 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/NavigationPropertyOperationHandler.cs
@@ -141,65 +141,41 @@ protected IRecord GetRestrictionAnnotation(string annotationTerm)
{
case CapabilitiesConstants.ReadRestrictions:
var readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
- if (readRestrictions != null && Restriction?.ReadRestrictions != null)
- {
- readRestrictions.MergePropertiesIfNull(Restriction.ReadRestrictions);
- }
+ readRestrictions?.MergePropertiesIfNull(Restriction?.ReadRestrictions);
readRestrictions ??= Restriction?.ReadRestrictions;
var navPropReadRestrictions = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.ReadRestrictions);
- if (readRestrictions != null && navPropReadRestrictions != null)
- {
- readRestrictions.MergePropertiesIfNull(navPropReadRestrictions);
- }
+ readRestrictions?.MergePropertiesIfNull(navPropReadRestrictions);
readRestrictions ??= navPropReadRestrictions;
return readRestrictions;
case CapabilitiesConstants.UpdateRestrictions:
var updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
- if (updateRestrictions != null && Restriction?.UpdateRestrictions != null)
- {
- updateRestrictions.MergePropertiesIfNull(Restriction.UpdateRestrictions);
- }
+ updateRestrictions?.MergePropertiesIfNull(Restriction?.UpdateRestrictions);
updateRestrictions ??= Restriction?.UpdateRestrictions;
var navPropUpdateRestrictions = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.UpdateRestrictions);
- if (updateRestrictions != null && navPropUpdateRestrictions != null)
- {
- updateRestrictions.MergePropertiesIfNull(navPropUpdateRestrictions);
- }
+ updateRestrictions?.MergePropertiesIfNull(navPropUpdateRestrictions);
updateRestrictions ??= navPropUpdateRestrictions;
return updateRestrictions;
case CapabilitiesConstants.InsertRestrictions:
var insertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
- if (insertRestrictions != null && Restriction?.InsertRestrictions != null)
- {
- insertRestrictions.MergePropertiesIfNull(Restriction.InsertRestrictions);
- }
+ insertRestrictions?.MergePropertiesIfNull(Restriction?.InsertRestrictions);
insertRestrictions ??= Restriction?.InsertRestrictions;
var navPropInsertRestrictions = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.InsertRestrictions);
- if (insertRestrictions != null && navPropInsertRestrictions != null)
- {
- insertRestrictions.MergePropertiesIfNull(navPropInsertRestrictions);
- }
+ insertRestrictions?.MergePropertiesIfNull(navPropInsertRestrictions);
insertRestrictions ??= navPropInsertRestrictions;
return insertRestrictions;
case CapabilitiesConstants.DeleteRestrictions:
var deleteRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.DeleteRestrictions);
- if (deleteRestrictions != null && Restriction?.DeleteRestrictions != null)
- {
- deleteRestrictions.MergePropertiesIfNull(Restriction.DeleteRestrictions);
- }
+ deleteRestrictions?.MergePropertiesIfNull(Restriction?.DeleteRestrictions);
deleteRestrictions ??= Restriction?.DeleteRestrictions;
var navPropDeleteRestrictions = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.DeleteRestrictions);
- if (deleteRestrictions != null && navPropDeleteRestrictions != null)
- {
- deleteRestrictions.MergePropertiesIfNull(navPropDeleteRestrictions);
- }
+ deleteRestrictions?.MergePropertiesIfNull(navPropDeleteRestrictions);
deleteRestrictions ??= navPropDeleteRestrictions;
return deleteRestrictions;
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/ODataTypeCastGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/ODataTypeCastGetOperationHandler.cs
index 1a236ae8..c790dbe1 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/ODataTypeCastGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/ODataTypeCastGetOperationHandler.cs
@@ -310,8 +310,8 @@ protected override void SetParameters(OpenApiOperation operation)
if (IsSingleElement)
{
new OpenApiParameter[] {
- Context.CreateSelect(navigationProperty),
- Context.CreateExpand(navigationProperty),
+ Context.CreateSelect(TargetPath, navigationProperty.ToEntityType()) ?? Context.CreateSelect(navigationProperty),
+ Context.CreateExpand(TargetPath, navigationProperty.ToEntityType()) ?? Context.CreateExpand(navigationProperty),
}
.Where(x => x != null)
.ToList()
@@ -322,9 +322,9 @@ protected override void SetParameters(OpenApiOperation operation)
GetParametersForAnnotableOfMany(navigationProperty)
.Union(
new OpenApiParameter[] {
- Context.CreateOrderBy(navigationProperty),
- Context.CreateSelect(navigationProperty),
- Context.CreateExpand(navigationProperty),
+ Context.CreateOrderBy(TargetPath, navigationProperty.ToEntityType()) ?? Context.CreateOrderBy(navigationProperty),
+ Context.CreateSelect(TargetPath, navigationProperty.ToEntityType()) ?? Context.CreateSelect(navigationProperty),
+ Context.CreateExpand(TargetPath, navigationProperty.ToEntityType()) ?? Context.CreateExpand(navigationProperty),
})
.Where(x => x != null)
.ToList()
@@ -336,8 +336,8 @@ protected override void SetParameters(OpenApiOperation operation)
if(IsSingleElement)
{
new OpenApiParameter[] {
- Context.CreateSelect(entitySet),
- Context.CreateExpand(entitySet),
+ Context.CreateSelect(TargetPath, entitySet.EntityType()) ?? Context.CreateSelect(entitySet),
+ Context.CreateExpand(TargetPath, entitySet.EntityType()) ?? Context.CreateExpand(entitySet),
}
.Where(x => x != null)
.ToList()
@@ -348,9 +348,9 @@ protected override void SetParameters(OpenApiOperation operation)
GetParametersForAnnotableOfMany(entitySet)
.Union(
new OpenApiParameter[] {
- Context.CreateOrderBy(entitySet),
- Context.CreateSelect(entitySet),
- Context.CreateExpand(entitySet),
+ Context.CreateOrderBy(TargetPath, entitySet.EntityType()) ?? Context.CreateOrderBy(entitySet),
+ Context.CreateSelect(TargetPath, entitySet.EntityType()) ?? Context.CreateSelect(entitySet),
+ Context.CreateExpand(TargetPath, entitySet.EntityType()) ?? Context.CreateExpand(entitySet),
})
.Where(x => x != null)
.ToList()
@@ -360,8 +360,8 @@ protected override void SetParameters(OpenApiOperation operation)
else if(singleton != null)
{
new OpenApiParameter[] {
- Context.CreateSelect(singleton),
- Context.CreateExpand(singleton),
+ Context.CreateSelect(TargetPath, singleton.EntityType()) ?? Context.CreateSelect(singleton),
+ Context.CreateExpand(TargetPath, singleton.EntityType()) ?? Context.CreateExpand(singleton),
}
.Where(x => x != null)
.ToList()
@@ -373,7 +373,7 @@ private IEnumerable GetParametersForAnnotableOfMany(IEdmVocabu
// Need to verify that TopSupported or others should be applied to navigation source.
// So, how about for the navigation property.
return new OpenApiParameter[] {
- Context.CreateTop(annotable),
+ Context.CreateTop(annotable),
Context.CreateSkip(annotable),
Context.CreateSearch(annotable),
Context.CreateFilter(annotable),
@@ -413,8 +413,11 @@ protected override void AppendCustomParameters(OpenApiOperation operation)
{
if (annotatable == null)
return;
-
- ReadRestrictionsType readRestrictions = Context.Model.GetRecord(annotatable, CapabilitiesConstants.ReadRestrictions);
+
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ var annotatableReadRestrictions = Context.Model.GetRecord(annotatable, CapabilitiesConstants.ReadRestrictions);
+ readRestrictions?.MergePropertiesIfNull(annotatableReadRestrictions);
+ readRestrictions ??= annotatableReadRestrictions;
if (readRestrictions == null)
{
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/OperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/OperationHandler.cs
index d7224780..cc864153 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/OperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/OperationHandler.cs
@@ -128,7 +128,7 @@ private void SetDeprecation(OpenApiOperation operation)
protected virtual void Initialize(ODataContext context, ODataPath path)
{
SetCustomLinkRelType();
- SetTargetPath();
+ TargetPath = path.GetTargetPath(context.Model);
}
///
@@ -298,21 +298,5 @@ protected virtual void SetCustomLinkRelType()
}
}
- ///
- /// Set string representation of the Edm Target Path for annotations
- ///
- protected virtual void SetTargetPath()
- {
- var targetPath = new StringBuilder(Context.Model.EntityContainer.FullName());
-
- bool skipLastSegment = Path.LastSegment is ODataRefSegment || Path.LastSegment is ODataDollarCountSegment;
- foreach (var segment in Path.Segments.Where(segment => segment is not ODataKeySegment
- && !(skipLastSegment && segment == Path.LastSegment)))
- {
- targetPath.Append($"/{segment.Identifier}");
- }
- TargetPath = targetPath.ToString();
- }
-
}
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs
index bff78f2c..bf07dcf7 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/RefGetOperationHandler.cs
@@ -145,39 +145,39 @@ protected override void SetParameters(OpenApiOperation operation)
if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
{
- // Need to verify that TopSupported or others should be applyed to navigaiton source.
+ // Need to verify that TopSupported or others should be applied to navigaiton source.
// So, how about for the navigation property.
- OpenApiParameter parameter = Context.CreateTop(NavigationProperty);
+ OpenApiParameter parameter = Context.CreateTop(TargetPath) ?? Context.CreateTop(NavigationProperty);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
- parameter = Context.CreateSkip(NavigationProperty);
+ parameter = Context.CreateSkip(TargetPath) ?? Context.CreateSkip(NavigationProperty);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
- parameter = Context.CreateSearch(NavigationProperty);
+ parameter = Context.CreateSearch(TargetPath) ?? Context.CreateSearch(NavigationProperty);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
- parameter = Context.CreateFilter(NavigationProperty);
+ parameter = Context.CreateFilter(TargetPath) ?? Context.CreateFilter(NavigationProperty);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
- parameter = Context.CreateCount(NavigationProperty);
+ parameter = Context.CreateCount(TargetPath) ?? Context.CreateCount(NavigationProperty);
if (parameter != null)
{
operation.Parameters.Add(parameter);
}
- parameter = Context.CreateOrderBy(NavigationProperty);
+ parameter = Context.CreateOrderBy(TargetPath, NavigationProperty.ToEntityType()) ?? Context.CreateOrderBy(NavigationProperty);
if (parameter != null)
{
operation.Parameters.Add(parameter);
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs
index e235ac76..0dc90b9e 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonGetOperationHandler.cs
@@ -32,15 +32,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
var singletonReadRestrictions = Context.Model.GetRecord(Singleton, CapabilitiesConstants.ReadRestrictions);
-
- if (_readRestrictions == null)
- {
- _readRestrictions = singletonReadRestrictions;
- }
- else
- {
- _readRestrictions.MergePropertiesIfNull(singletonReadRestrictions);
- }
+ _readRestrictions?.MergePropertiesIfNull(singletonReadRestrictions);
+ _readRestrictions ??= singletonReadRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs
index dc74fec3..68e3c11a 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/SingletonPatchOperationHandler.cs
@@ -32,15 +32,8 @@ protected override void Initialize(ODataContext context, ODataPath path)
_updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
var singletonUpdateRestrictions = Context.Model.GetRecord(Singleton, CapabilitiesConstants.UpdateRestrictions);
-
- if (_updateRestrictions == null)
- {
- _updateRestrictions = singletonUpdateRestrictions;
- }
- else
- {
- _updateRestrictions.MergePropertiesIfNull(singletonUpdateRestrictions);
- }
+ _updateRestrictions?.MergePropertiesIfNull(singletonUpdateRestrictions);
+ _updateRestrictions ??= singletonUpdateRestrictions;
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs
index a0019c19..866dcef3 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/ComplexPropertyItemHandler.cs
@@ -24,41 +24,65 @@ internal class ComplexPropertyItemHandler : PathItemHandler
///
protected override void SetOperations(OpenApiPathItem item)
{
- bool isReadable = Context.Model.GetRecord(ComplexProperty, CapabilitiesConstants.ReadRestrictions)?.Readable ?? false;
- if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isReadable) ||
- !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
+ AddReadOperation(item);
+ AddUpdateOperation(item);
+ AddInsertOperation(item);
+ }
+
+ public void AddReadOperation(OpenApiPathItem item)
+ {
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ ReadRestrictionsType complexTypeReadRestrictions = Context.Model.GetRecord(ComplexProperty, CapabilitiesConstants.ReadRestrictions);
+ readRestrictions?.MergePropertiesIfNull(complexTypeReadRestrictions);
+ readRestrictions ??= complexTypeReadRestrictions;
+ bool isReadable = readRestrictions?.Readable ?? false;
+ if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isReadable) ||
+ !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
{
- AddOperation(item, OperationType.Get);
- }
+ AddOperation(item, OperationType.Get);
+ }
+ }
- UpdateRestrictionsType update = Context.Model.GetRecord(ComplexProperty, CapabilitiesConstants.UpdateRestrictions);
- bool isUpdatable = update?.Updatable ?? false;
- if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isUpdatable) ||
- !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
- {
- if (update != null && update.IsUpdateMethodPut)
- {
- AddOperation(item, OperationType.Put);
- }
- else
+ public void AddInsertOperation(OpenApiPathItem item)
+ {
+ if (Path.LastSegment is ODataComplexPropertySegment segment && segment.Property.Type.IsCollection())
+ {
+ InsertRestrictionsType insertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
+ InsertRestrictionsType entityInsertRestrictions = Context.Model.GetRecord(ComplexProperty, CapabilitiesConstants.InsertRestrictions);
+ insertRestrictions?.MergePropertiesIfNull(entityInsertRestrictions);
+ insertRestrictions ??= entityInsertRestrictions;
+ bool isInsertable = insertRestrictions?.Insertable ?? false;
+ if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isInsertable) ||
+ !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
{
- AddOperation(item, OperationType.Patch);
- }
- }
+ AddOperation(item, OperationType.Post);
+ }
+ }
+ }
- if (Path.LastSegment is ODataComplexPropertySegment segment && segment.Property.Type.IsCollection())
+ public void AddUpdateOperation(OpenApiPathItem item)
+ {
+ UpdateRestrictionsType updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
+ UpdateRestrictionsType complexTypeUpdateRestrictions = Context.Model.GetRecord(ComplexProperty, CapabilitiesConstants.UpdateRestrictions);
+ updateRestrictions?.MergePropertiesIfNull(complexTypeUpdateRestrictions);
+ updateRestrictions ??= complexTypeUpdateRestrictions;
+ bool isUpdatable = updateRestrictions?.Updatable ?? false;
+ if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isUpdatable) ||
+ !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
{
- bool isInsertable = Context.Model.GetRecord(ComplexProperty, CapabilitiesConstants.InsertRestrictions)?.Insertable ?? false;
- if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isInsertable) ||
- !Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
- {
- AddOperation(item, OperationType.Post);
- }
- }
- }
+ if (updateRestrictions != null && updateRestrictions.IsUpdateMethodPut)
+ {
+ AddOperation(item, OperationType.Put);
+ }
+ else
+ {
+ AddOperation(item, OperationType.Patch);
+ }
+ }
+ }
- ///
- protected override void Initialize(ODataContext context, ODataPath path)
+ ///
+ protected override void Initialize(ODataContext context, ODataPath path)
{
base.Initialize(context, path);
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs
index cc428cb8..7c66d7d9 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/EntityPathItemHandler.cs
@@ -22,19 +22,25 @@ internal class EntityPathItemHandler : EntitySetPathItemHandler
///
protected override void SetOperations(OpenApiPathItem item)
{
- ReadRestrictionsType read = Context.Model.GetRecord(EntitySet);
- if (read == null ||
- (read.ReadByKeyRestrictions == null && read.IsReadable) ||
- (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.IsReadable))
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ ReadRestrictionsType entityReadRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions);
+ readRestrictions?.MergePropertiesIfNull(entityReadRestrictions);
+ readRestrictions ??= entityReadRestrictions;
+ if (readRestrictions == null ||
+ (readRestrictions.ReadByKeyRestrictions == null && readRestrictions.IsReadable) ||
+ (readRestrictions.ReadByKeyRestrictions != null && readRestrictions.ReadByKeyRestrictions.IsReadable))
{
// If we don't have Read by key read restriction, we should check the set read restrction.
AddOperation(item, OperationType.Get);
}
- UpdateRestrictionsType update = Context.Model.GetRecord(EntitySet);
- if (update == null || update.IsUpdatable)
+ UpdateRestrictionsType updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
+ UpdateRestrictionsType entityUpdateRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.UpdateRestrictions);
+ updateRestrictions?.MergePropertiesIfNull(entityUpdateRestrictions);
+ updateRestrictions ??= entityUpdateRestrictions;
+ if (updateRestrictions?.IsUpdatable ?? true)
{
- if (update != null && update.IsUpdateMethodPut)
+ if (updateRestrictions != null && updateRestrictions.IsUpdateMethodPut)
{
AddOperation(item, OperationType.Put);
}
@@ -44,8 +50,11 @@ protected override void SetOperations(OpenApiPathItem item)
}
}
- DeleteRestrictionsType delete = Context.Model.GetRecord(EntitySet);
- if (delete == null || delete.IsDeletable)
+ DeleteRestrictionsType deleteRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.DeleteRestrictions);
+ DeleteRestrictionsType entityDeleteRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.DeleteRestrictions);
+ deleteRestrictions?.MergePropertiesIfNull(entityDeleteRestrictions);
+ deleteRestrictions ??= entityDeleteRestrictions;
+ if (deleteRestrictions?.IsDeletable ?? true)
{
AddOperation(item, OperationType.Delete);
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/EntitySetPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/EntitySetPathItemHandler.cs
index 29450c37..a6c0019b 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/EntitySetPathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/EntitySetPathItemHandler.cs
@@ -27,14 +27,20 @@ internal class EntitySetPathItemHandler : PathItemHandler
///
protected override void SetOperations(OpenApiPathItem item)
{
- ReadRestrictionsType read = Context.Model.GetRecord(EntitySet);
- if (read == null || read.IsReadable)
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ ReadRestrictionsType entityReadRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.ReadRestrictions);
+ readRestrictions?.MergePropertiesIfNull(entityReadRestrictions);
+ readRestrictions ??= entityReadRestrictions;
+ if (readRestrictions?.IsReadable ?? true)
{
AddOperation(item, OperationType.Get);
}
- InsertRestrictionsType insert = Context.Model.GetRecord(EntitySet);
- if (insert == null || insert.IsInsertable)
+ InsertRestrictionsType insertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
+ InsertRestrictionsType entityInsertRestrictions = Context.Model.GetRecord(EntitySet, CapabilitiesConstants.InsertRestrictions);
+ insertRestrictions?.MergePropertiesIfNull(entityInsertRestrictions);
+ insertRestrictions ??= entityInsertRestrictions;
+ if (insertRestrictions?.IsInsertable ?? true)
{
AddOperation(item, OperationType.Post);
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/MediaEntityPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/MediaEntityPathItemHandler.cs
index 1dfd089e..83eeae03 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/MediaEntityPathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/MediaEntityPathItemHandler.cs
@@ -31,31 +31,34 @@ internal class MediaEntityPathItemHandler : PathItemHandler
///
protected override void SetOperations(OpenApiPathItem item)
{
- ReadRestrictionsType read = EntitySet != null
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ ReadRestrictionsType navSourceReadRestrictions = EntitySet != null
? Context.Model.GetRecord(EntitySet)
: Context.Model.GetRecord(Singleton);
-
- if (read == null ||
- (read.ReadByKeyRestrictions == null && read.IsReadable) ||
- (read.ReadByKeyRestrictions != null && read.ReadByKeyRestrictions.IsReadable))
+ readRestrictions ??= navSourceReadRestrictions;
+ if (readRestrictions == null ||
+ (readRestrictions.ReadByKeyRestrictions == null && readRestrictions.IsReadable) ||
+ (readRestrictions.ReadByKeyRestrictions != null && readRestrictions.ReadByKeyRestrictions.IsReadable))
{
AddOperation(item, OperationType.Get);
}
- UpdateRestrictionsType update = EntitySet != null
+ UpdateRestrictionsType updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
+ UpdateRestrictionsType navSourceUpdateRestrictions = EntitySet != null
? Context.Model.GetRecord(EntitySet)
: Context.Model.GetRecord(Singleton);
-
- if (update == null || update.IsUpdatable)
+ updateRestrictions ??= navSourceUpdateRestrictions;
+ if (updateRestrictions?.IsUpdatable ?? true)
{
AddOperation(item, OperationType.Put);
}
- DeleteRestrictionsType delete = EntitySet != null
+ DeleteRestrictionsType deleteRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.DeleteRestrictions);
+ DeleteRestrictionsType navSourceDeleteRestrictions = EntitySet != null
? Context.Model.GetRecord(EntitySet)
: Context.Model.GetRecord(Singleton);
-
- if (delete == null || delete.IsDeletable)
+ deleteRestrictions ??= navSourceDeleteRestrictions;
+ if (deleteRestrictions?.IsDeletable ?? true)
{
AddOperation(item, OperationType.Delete);
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs
index 37084b61..57b36119 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/NavigationPropertyPathItemHandler.cs
@@ -54,16 +54,14 @@ protected override void SetOperations(OpenApiPathItem item)
{
IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet;
IEdmVocabularyAnnotatable target = entitySet;
- if (target == null)
- {
- target = NavigationSource as IEdmSingleton;
- }
+ target ??= NavigationSource as IEdmSingleton;
+ NavigationRestrictionsType targetPathRestrictionType = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.NavigationRestrictions);
NavigationRestrictionsType navSourceRestrictionType = Context.Model.GetRecord(target, CapabilitiesConstants.NavigationRestrictions);
NavigationRestrictionsType navPropRestrictionType = Context.Model.GetRecord(NavigationProperty, CapabilitiesConstants.NavigationRestrictions);
- NavigationPropertyRestriction restriction = navSourceRestrictionType?.RestrictedProperties?
- .FirstOrDefault(r => r.NavigationProperty == Path.NavigationPropertyPath())
+ NavigationPropertyRestriction restriction = targetPathRestrictionType?.RestrictedProperties?.FirstOrDefault()
+ ?? navSourceRestrictionType?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == Path.NavigationPropertyPath())
?? navPropRestrictionType?.RestrictedProperties?.FirstOrDefault();
// Check whether the navigation property should be part of the path
@@ -75,23 +73,36 @@ protected override void SetOperations(OpenApiPathItem item)
AddGetOperation(item, restriction);
- UpdateRestrictionsType navPropUpdateRestriction = restriction?.UpdateRestrictions ??
- Context.Model.GetRecord(NavigationProperty);
- InsertRestrictionsType navPropInsertRestriction = restriction?.InsertRestrictions ??
- Context.Model.GetRecord(NavigationProperty);
- UpdateRestrictionsType entityUpdateRestriction = Context.Model.GetRecord(_navPropEntityType);
+ // Update restrictions
+ UpdateRestrictionsType navPropUpdateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
+ navPropUpdateRestrictions?.MergePropertiesIfNull(restriction?.UpdateRestrictions);
+ navPropUpdateRestrictions ??= restriction?.UpdateRestrictions;
+ UpdateRestrictionsType updateRestrictions = Context.Model.GetRecord(NavigationProperty);
+ navPropUpdateRestrictions?.MergePropertiesIfNull(updateRestrictions);
+ navPropUpdateRestrictions ??= updateRestrictions;
+
+ // Insert restrictions
+ InsertRestrictionsType navPropInsertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
+ navPropInsertRestrictions?.MergePropertiesIfNull(restriction?.InsertRestrictions);
+ navPropInsertRestrictions ??= restriction?.InsertRestrictions;
+ InsertRestrictionsType insertRestrictions = Context.Model.GetRecord(NavigationProperty);
+ navPropInsertRestrictions?.MergePropertiesIfNull(insertRestrictions);
+ navPropInsertRestrictions ??= insertRestrictions;
+
+ // Entity insert restrictions
+ UpdateRestrictionsType entityUpdateRestrictions = Context.Model.GetRecord(_navPropEntityType);
// containment: (Post - Collection | Patch/Put - Single)
if (NavigationProperty.ContainsTarget)
{
- UpdateRestrictionsType updateRestrictionType = navPropUpdateRestriction ?? entityUpdateRestriction;
+ UpdateRestrictionsType updateRestrictionType = navPropUpdateRestrictions ?? entityUpdateRestrictions;
if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
{
if (LastSegmentIsKeySegment)
{
- if ((entityUpdateRestriction?.IsUpdatable ?? true) &&
- (navPropUpdateRestriction?.IsUpdatable ?? true))
+ if ((entityUpdateRestrictions?.IsUpdatable ?? true) &&
+ (navPropUpdateRestrictions?.IsUpdatable ?? true))
{
AddUpdateOperation(item, updateRestrictionType);
@@ -99,12 +110,12 @@ protected override void SetOperations(OpenApiPathItem item)
}
else
{
- InsertRestrictionsType entityInsertRestriction = Context.Model.GetRecord(_navPropEntityType);
- bool isInsertableDefault = navPropInsertRestriction == null && entityInsertRestriction == null;
+ InsertRestrictionsType entityInsertRestrictions = Context.Model.GetRecord(_navPropEntityType);
+ bool isInsertableDefault = navPropInsertRestrictions == null && entityInsertRestrictions == null;
if (isInsertableDefault ||
- ((entityInsertRestriction?.IsInsertable ?? true) &&
- (navPropInsertRestriction?.IsInsertable ?? true)))
+ ((entityInsertRestrictions?.IsInsertable ?? true) &&
+ (navPropInsertRestrictions?.IsInsertable ?? true)))
{
AddOperation(item, OperationType.Post);
}
@@ -123,14 +134,14 @@ protected override void SetOperations(OpenApiPathItem item)
{
if (LastSegmentIsKeySegment)
{
- if (navPropUpdateRestriction?.Updatable ?? false)
+ if (navPropUpdateRestrictions?.Updatable ?? false)
{
- AddUpdateOperation(item, navPropUpdateRestriction);
+ AddUpdateOperation(item, navPropUpdateRestrictions);
}
}
else
{
- if (navPropInsertRestriction?.Insertable ?? false)
+ if (navPropInsertRestrictions?.Insertable ?? false)
{
AddOperation(item, OperationType.Post);
}
@@ -138,9 +149,9 @@ protected override void SetOperations(OpenApiPathItem item)
}
else
{
- if (navPropUpdateRestriction?.Updatable ?? false)
+ if (navPropUpdateRestrictions?.Updatable ?? false)
{
- AddUpdateOperation(item, navPropUpdateRestriction);
+ AddUpdateOperation(item, navPropUpdateRestrictions);
}
}
}
@@ -150,11 +161,15 @@ protected override void SetOperations(OpenApiPathItem item)
private void AddGetOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
{
- ReadRestrictionsType navPropReadRestriction = restriction?.ReadRestrictions ??
- Context.Model.GetRecord(NavigationProperty);
+ ReadRestrictionsType navPropReadRestriction = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ navPropReadRestriction?.MergePropertiesIfNull(restriction?.ReadRestrictions);
+ navPropReadRestriction ??= restriction?.ReadRestrictions;
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(NavigationProperty);
+ navPropReadRestriction?.MergePropertiesIfNull(readRestrictions);
+ navPropReadRestriction ??= readRestrictions;
+
ReadRestrictionsType entityReadRestriction = Context.Model.GetRecord(_navPropEntityType);
bool isReadableDefault = navPropReadRestriction == null && entityReadRestriction == null;
-
if (isReadableDefault)
{
AddOperation(item, OperationType.Get);
@@ -196,8 +211,12 @@ private void AddDeleteOperation(OpenApiPathItem item, NavigationPropertyRestrict
{
Debug.Assert(!LastSegmentIsRefSegment);
- DeleteRestrictionsType navPropDeleteRestriction = restriction?.DeleteRestrictions ??
- Context.Model.GetRecord(NavigationProperty);
+ DeleteRestrictionsType navPropDeleteRestriction = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.DeleteRestrictions);
+ navPropDeleteRestriction?.MergePropertiesIfNull(restriction?.DeleteRestrictions);
+ navPropDeleteRestriction ??= restriction?.DeleteRestrictions;
+ DeleteRestrictionsType insertRestrictions = Context.Model.GetRecord(NavigationProperty);
+ navPropDeleteRestriction?.MergePropertiesIfNull(insertRestrictions);
+ navPropDeleteRestriction ??= insertRestrictions;
if (!(NavigationProperty.TargetMultiplicity() != EdmMultiplicity.Many || LastSegmentIsKeySegment))
return;
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/OperationImportPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/OperationImportPathItemHandler.cs
index 9ab0bd3b..b447fa1c 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/OperationImportPathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/OperationImportPathItemHandler.cs
@@ -43,8 +43,11 @@ protected override void SetOperations(OpenApiPathItem item)
// how to invoke the function import.
// so far,
- ReadRestrictionsType read = Context.Model.GetRecord(EdmOperationImport, CapabilitiesConstants.ReadRestrictions);
- if (read == null || read.IsReadable)
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ ReadRestrictionsType operationReadRestrictions = Context.Model.GetRecord(EdmOperationImport, CapabilitiesConstants.ReadRestrictions);
+ readRestrictions?.MergePropertiesIfNull(operationReadRestrictions);
+ readRestrictions ??= operationReadRestrictions;
+ if (readRestrictions?.IsReadable ?? true)
{
AddOperation(item, OperationType.Get);
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/PathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/PathItemHandler.cs
index c9f84c91..5cd00b38 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/PathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/PathItemHandler.cs
@@ -3,18 +3,13 @@
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.OData.Edm;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
using Microsoft.OpenApi.OData.Generator;
using Microsoft.OpenApi.OData.Operation;
using Microsoft.OpenApi.OData.Properties;
+using System;
namespace Microsoft.OpenApi.OData.PathItem
{
@@ -38,6 +33,11 @@ internal abstract class PathItemHandler : IPathItemHandler
///
protected ODataPath Path { get; private set; }
+ ///
+ /// Gets the string representation of the Edm target path for annotations.
+ ///
+ protected string TargetPath;
+
///
public virtual OpenApiPathItem CreatePathItem(ODataContext context, ODataPath path)
{
@@ -86,6 +86,7 @@ protected virtual void Initialize(ODataContext context, ODataPath path)
{
throw Error.InvalidOperation(String.Format(SRResource.InvalidPathKindForPathItemHandler, GetType().Name, path.Kind));
}
+ TargetPath = path.GetTargetPath(context.Model);
}
///
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/RefPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/RefPathItemHandler.cs
index 68751b4b..f4f28342 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/RefPathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/RefPathItemHandler.cs
@@ -37,32 +37,32 @@ protected override void SetOperations(OpenApiPathItem item)
{
IEdmEntitySet entitySet = NavigationSource as IEdmEntitySet;
IEdmVocabularyAnnotatable target = entitySet;
- if (target == null)
- {
- target = NavigationSource as IEdmSingleton;
- }
+ target ??= NavigationSource as IEdmSingleton;
string navigationPropertyPath = String.Join("/",
Path.Segments.Where(s => !(s is ODataKeySegment || s is ODataNavigationSourceSegment)).Select(e => e.Identifier));
-
- NavigationRestrictionsType navigation = Context.Model.GetRecord(target, CapabilitiesConstants.NavigationRestrictions);
- NavigationPropertyRestriction restriction = navigation?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath);
+
+ NavigationRestrictionsType navigationRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.NavigationRestrictions);
+ NavigationRestrictionsType sourceNavigationRestrictions = Context.Model.GetRecord(target, CapabilitiesConstants.NavigationRestrictions);
+ navigationRestrictions?.MergePropertiesIfNull(sourceNavigationRestrictions);
+ navigationRestrictions ??= sourceNavigationRestrictions;
+ NavigationPropertyRestriction restriction = navigationRestrictions?.RestrictedProperties?.FirstOrDefault(r => r.NavigationProperty == navigationPropertyPath);
// verify using individual first
- if (restriction != null && restriction.Navigability != null && restriction.Navigability.Value == NavigationType.None)
+ if (restriction?.Navigability != null && restriction.Navigability.Value == NavigationType.None)
{
return;
}
- if (restriction == null || restriction.Navigability == null)
+ // if the individual has not navigability setting, use the global navigability setting
+ if (restriction?.Navigability == null
+ && navigationRestrictions != null
+ && navigationRestrictions.Navigability != null
+ && navigationRestrictions.Navigability.Value == NavigationType.None)
{
- // if the individual has not navigability setting, use the global navigability setting
- if (navigation != null && navigation.Navigability != null && navigation.Navigability.Value == NavigationType.None)
- {
- // Default navigability for all navigation properties of the annotation target.
- // Individual navigation properties can override this value via `RestrictedProperties/Navigability`.
- return;
- }
+ // Default navigability for all navigation properties of the annotation target.
+ // Individual navigation properties can override this value via `RestrictedProperties/Navigability`.
+ return;
}
// Create the ref
@@ -92,8 +92,10 @@ protected override void SetOperations(OpenApiPathItem item)
private void AddDeleteOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
{
- DeleteRestrictionsType delete = restriction?.DeleteRestrictions;
- if (delete == null || delete.IsDeletable)
+ DeleteRestrictionsType deleteRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.DeleteRestrictions);
+ deleteRestrictions?.MergePropertiesIfNull(restriction?.DeleteRestrictions);
+ deleteRestrictions ??= restriction?.DeleteRestrictions;
+ if (deleteRestrictions?.IsDeletable ?? true)
{
AddOperation(item, OperationType.Delete);
}
@@ -101,8 +103,10 @@ private void AddDeleteOperation(OpenApiPathItem item, NavigationPropertyRestrict
private void AddReadOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
{
- ReadRestrictionsType read = restriction?.ReadRestrictions;
- if (read == null || read.IsReadable)
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ readRestrictions?.MergePropertiesIfNull(restriction?.ReadRestrictions);
+ readRestrictions ??= restriction?.ReadRestrictions;
+ if (readRestrictions?.IsReadable ?? true)
{
AddOperation(item, OperationType.Get);
}
@@ -110,8 +114,10 @@ private void AddReadOperation(OpenApiPathItem item, NavigationPropertyRestrictio
private void AddInsertOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
{
- InsertRestrictionsType insert = restriction?.InsertRestrictions;
- if (insert == null || insert.IsInsertable)
+ InsertRestrictionsType insertRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.InsertRestrictions);
+ insertRestrictions?.MergePropertiesIfNull(restriction?.InsertRestrictions);
+ insertRestrictions ??= restriction?.InsertRestrictions;
+ if (insertRestrictions?.IsInsertable ?? true)
{
AddOperation(item, OperationType.Post);
}
@@ -119,8 +125,10 @@ private void AddInsertOperation(OpenApiPathItem item, NavigationPropertyRestrict
private void AddUpdateOperation(OpenApiPathItem item, NavigationPropertyRestriction restriction)
{
- UpdateRestrictionsType update = restriction?.UpdateRestrictions;
- if (update == null || update.IsUpdatable)
+ UpdateRestrictionsType updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
+ updateRestrictions?.MergePropertiesIfNull(restriction?.UpdateRestrictions);
+ updateRestrictions ??= restriction?.UpdateRestrictions;
+ if (updateRestrictions?.IsUpdatable ?? true)
{
AddOperation(item, OperationType.Put);
}
@@ -136,6 +144,7 @@ protected override void Initialize(ODataContext context, ODataPath path)
NavigationProperty = path.OfType().Last().NavigationProperty;
}
+
///
protected override void SetBasicInfo(OpenApiPathItem pathItem)
{
diff --git a/src/Microsoft.OpenApi.OData.Reader/PathItem/SingletonPathItemHandler.cs b/src/Microsoft.OpenApi.OData.Reader/PathItem/SingletonPathItemHandler.cs
index 6ffbc66c..9cb2cb48 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PathItem/SingletonPathItemHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/PathItem/SingletonPathItemHandler.cs
@@ -28,15 +28,21 @@ internal class SingletonPathItemHandler : PathItemHandler
protected override void SetOperations(OpenApiPathItem item)
{
// Retrieve a singleton.
- ReadRestrictionsType read = Context.Model.GetRecord(Singleton);
- if (read == null || read.IsReadable)
+ ReadRestrictionsType readRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.ReadRestrictions);
+ ReadRestrictionsType singletonReadRestrictions = Context.Model.GetRecord(Singleton, CapabilitiesConstants.ReadRestrictions);
+ readRestrictions?.MergePropertiesIfNull(singletonReadRestrictions);
+ readRestrictions ??= singletonReadRestrictions;
+ if (readRestrictions?.IsReadable ?? true)
{
AddOperation(item, OperationType.Get);
}
// Update a singleton
- UpdateRestrictionsType update = Context.Model.GetRecord(Singleton);
- if (update == null || update.IsUpdatable)
+ UpdateRestrictionsType updateRestrictions = Context.Model.GetRecord(TargetPath, CapabilitiesConstants.UpdateRestrictions);
+ UpdateRestrictionsType singletonUpdateRestrictions = Context.Model.GetRecord(Singleton, CapabilitiesConstants.UpdateRestrictions);
+ updateRestrictions?.MergePropertiesIfNull(singletonUpdateRestrictions);
+ updateRestrictions ??= singletonUpdateRestrictions;
+ if (updateRestrictions?.IsUpdatable ?? true)
{
AddOperation(item, OperationType.Patch);
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Vocabulary/Capabilities/NavigationRestrictionsType.cs b/src/Microsoft.OpenApi.OData.Reader/Vocabulary/Capabilities/NavigationRestrictionsType.cs
index 0145a07e..e0ff6696 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Vocabulary/Capabilities/NavigationRestrictionsType.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Vocabulary/Capabilities/NavigationRestrictionsType.cs
@@ -3,11 +3,11 @@
// 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.Vocabularies;
using Microsoft.OpenApi.OData.Common;
using Microsoft.OpenApi.OData.Edm;
+using System.Collections.Generic;
+using System.Linq;
namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
{
@@ -239,5 +239,21 @@ public void Initialize(IEdmRecordExpression record)
// Referenceable
Referenceable = record.GetBoolean("Referenceable");
}
+
+ ///
+ /// Merges properties of the specified object into this instance if they are null.
+ ///
+ /// The object containing properties to merge.
+ public void MergePropertiesIfNull(NavigationRestrictionsType source)
+ {
+ if (source == null)
+ return;
+
+ Navigability ??= source.Navigability;
+
+ RestrictedProperties ??= source.RestrictedProperties;
+
+ Referenceable ??= source.Referenceable;
+ }
}
}
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs
index 790d601b..b3e2ec18 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/MediaEntityGetOperationHandlerTests.cs
@@ -207,6 +207,7 @@ public void CreateMediaEntityPropertyGetOperationWithTargetPathAnnotationsReturn
Assert.NotNull(operation);
Assert.Equal("Get photo", operation.Summary);
Assert.Equal("Get photo of a specific user", operation.Description);
+ Assert.Single(operation.Parameters);
Assert.NotNull(operation.ExternalDocs);
Assert.Equal("Find more info here", operation.ExternalDocs.Description);
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/ComplexPropertyPathItemHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/ComplexPropertyPathItemHandlerTests.cs
index d1d342a3..391acd4b 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/ComplexPropertyPathItemHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/ComplexPropertyPathItemHandlerTests.cs
@@ -207,4 +207,64 @@ public void CreateComplexPropertyPathItemAddsCustomAttributeValuesToPathExtensio
string isHiddenValue = (isHiddenExtension as OpenApiString)?.Value;
Assert.Equal("true", isHiddenValue);
}
+
+ [Theory]
+ [InlineData("true", "true", "true", 3)]
+ [InlineData("false", "false", "false", 0)]
+ [InlineData ("false", "false", "true", 1)]
+ public void CreatesComplexPropertyPathsBasedOnTargetPathAnnotations(string readable, string insertable, string updatable, int operationCount)
+ {
+ // Arrange
+ var annotation = $@"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+";
+ var target = @"""NS.Default/Customers/AlternativeAddresses""";
+ var model = EntitySetPathItemHandlerTests.GetEdmModel(annotation, target);
+ var context = new ODataContext(model, new OpenApiConvertSettings());
+
+ var entitySet = model.EntityContainer.FindEntitySet("Customers");
+ Assert.NotNull(entitySet); // guard
+
+ var entityType = entitySet.EntityType();
+ var property = entityType.FindProperty("AlternativeAddresses");
+ Assert.NotNull(property); // guard
+
+ var path = new ODataPath(
+ new ODataNavigationSourceSegment(entitySet),
+ new ODataKeySegment(entityType),
+ new ODataComplexPropertySegment(property as IEdmStructuralProperty));
+ Assert.Equal(ODataPathKind.ComplexProperty, path.Kind); // guard
+
+ // Act
+ var pathItem = _pathItemHandler.CreatePathItem(context, path);
+
+ // Assert
+ Assert.NotNull(pathItem);
+ Assert.Equal(operationCount, pathItem.Operations.Count);
+ if (operationCount == 1)
+ {
+ Assert.True(pathItem.Operations.ContainsKey(OperationType.Patch));
+ Assert.False(pathItem.Operations.ContainsKey(OperationType.Post));
+ Assert.False(pathItem.Operations.ContainsKey(OperationType.Get));
+ }
+ else if (operationCount == 3)
+ {
+ Assert.True(pathItem.Operations.ContainsKey(OperationType.Patch));
+ Assert.True(pathItem.Operations.ContainsKey(OperationType.Post));
+ Assert.True(pathItem.Operations.ContainsKey(OperationType.Get));
+ }
+ }
}
\ No newline at end of file
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/MediaEntityPathItemHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/MediaEntityPathItemHandlerTests.cs
index 7f1d0006..dd7ac1b1 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/MediaEntityPathItemHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/PathItem/MediaEntityPathItemHandlerTests.cs
@@ -137,6 +137,32 @@ public void CreateMediaEntityPathItemWorksForUpdateRestrictionsCapabilities(bool
VerifyPathItemOperationsForStreamContentSegment(annotation, expected);
}
+ [Theory]
+ [InlineData(true, new OperationType[] { OperationType.Get, OperationType.Put, OperationType.Delete })]
+ [InlineData(false, new OperationType[] { OperationType.Get, OperationType.Delete })]
+ public void CreateMediaEntityPathItemWorksForUpdateRestrictionsCapabilitiesWithTargetPathAnnotations(bool updatable, OperationType[] expected)
+ {
+ string annotation = $@"
+
+
+
+
+";
+
+ // Arrange
+ string streamPropertyTargetPathAnnotation = $@"
+
+
+
+
+
+
+";
+
+ // Assert
+ VerifyPathItemOperationsForStreamPropertySegment(annotation, expected, streamPropertyTargetPathAnnotation);
+ }
+
[Theory]
[InlineData(true, new OperationType[] { OperationType.Get, OperationType.Put, OperationType.Delete })]
[InlineData(false, new OperationType[] { OperationType.Get, OperationType.Put })]
@@ -155,10 +181,39 @@ public void CreateMediaEntityPathItemWorksForDeleteRestrictionsCapabilities(bool
VerifyPathItemOperationsForStreamContentSegment(annotation, expected);
}
- private void VerifyPathItemOperationsForStreamPropertySegment(string annotation, OperationType[] expected)
+ [Theory]
+ [InlineData(true, new OperationType[] { OperationType.Get, OperationType.Put, OperationType.Delete })]
+ [InlineData(false, new OperationType[] { OperationType.Get, OperationType.Put })]
+ public void CreateMediaEntityPathItemWorksForDeleteRestrictionsCapabilitiesWithTargetPathAnnotations(bool deletable, OperationType[] expected)
+ {
+ // Arrange
+ string annotation = $@"
+
+
+
+
+";
+
+
+ // Arrange
+ string streamPropertyTargetPathAnnotation = $@"
+
+
+
+
+
+
+";
+
+ // Assert
+ VerifyPathItemOperationsForStreamPropertySegment(annotation, expected, streamPropertyTargetPathAnnotation);
+ }
+
+ private void VerifyPathItemOperationsForStreamPropertySegment(string annotation, OperationType[] expected, string targetPathAnnotations = "")
{
// Arrange
- IEdmModel model = GetEdmModel(annotation);
+
+ IEdmModel model = GetEdmModel(annotation, targetPathAnnotations);
ODataContext context = new ODataContext(model);
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Todos");
Assert.NotNull(entitySet); // guard
@@ -180,10 +235,10 @@ private void VerifyPathItemOperationsForStreamPropertySegment(string annotation,
Assert.Equal(expected, pathItem.Operations.Select(e => e.Key));
}
- private void VerifyPathItemOperationsForStreamContentSegment(string annotation, OperationType[] expected)
+ private void VerifyPathItemOperationsForStreamContentSegment(string annotation, OperationType[] expected, string targetPathAnnotations = null)
{
// Arrange
- IEdmModel model = GetEdmModel(annotation);
+ IEdmModel model = GetEdmModel(annotation, targetPathAnnotations);
ODataContext context = new ODataContext(model);
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Todos");
IEdmSingleton singleton = model.EntityContainer.FindSingleton("me");
@@ -217,7 +272,7 @@ private void VerifyPathItemOperationsForStreamContentSegment(string annotation,
Assert.Equal(expected, pathItem2.Operations.Select(e => e.Key));
}
- private IEdmModel GetEdmModel(string annotation)
+ private IEdmModel GetEdmModel(string annotation, string targetPathAnnotation = "")
{
const string template = @"
@@ -247,10 +302,11 @@ private IEdmModel GetEdmModel(string annotation)
{0}
+ {1}
";
- string modelText = string.Format(template, annotation);
+ string modelText = string.Format(template, annotation, targetPathAnnotation);
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out IEdmModel model, out _);
Assert.True(result);
return model;