Skip to content

Commit 6ab40ab

Browse files
authored
Enables configuring appending bound operations on derived types (#226)
* Add new convert setting * Rename new convert setting * Use convert setting to control generation of actions on OData type cast paths * Update tests to validate generation of bound operations on derived types * Update csproj with release note * Rename convert setting property * Update tests
1 parent fb4bb5e commit 6ab40ab

File tree

6 files changed

+68
-27
lines changed

6 files changed

+68
-27
lines changed

src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ bool filter(IEdmStructuredType x) =>
567567
{
568568
RetrieveNavigationPropertyPaths(declaredNavigationProperty, null, castPath, convertSettings);
569569
}
570-
}
570+
}
571571
}
572572
}
573573
}
@@ -614,7 +614,7 @@ bool filter(IEdmNavigationSource z) =>
614614
foreach (var bindingEntityType in allEntitiesForOperation)
615615
{
616616
// 1. Search for corresponding navigation source path
617-
AppendBoundOperationOnNavigationSourcePath(edmOperation, isCollection, bindingEntityType);
617+
AppendBoundOperationOnNavigationSourcePath(edmOperation, isCollection, bindingEntityType, convertSettings);
618618

619619
// 2. Search for generated navigation property
620620
AppendBoundOperationOnNavigationPropertyPath(edmOperation, isCollection, bindingEntityType);
@@ -633,7 +633,7 @@ bool filter(IEdmNavigationSource z) =>
633633
ODataPathKind.DollarCount,
634634
ODataPathKind.ComplexProperty,
635635
};
636-
private void AppendBoundOperationOnNavigationSourcePath(IEdmOperation edmOperation, bool isCollection, IEdmEntityType bindingEntityType)
636+
private void AppendBoundOperationOnNavigationSourcePath(IEdmOperation edmOperation, bool isCollection, IEdmEntityType bindingEntityType, OpenApiConvertSettings convertSettings)
637637
{
638638
if (_allNavigationSourcePaths.TryGetValue(bindingEntityType, out IList<ODataPath> value))
639639
{
@@ -658,6 +658,7 @@ secondLastPathSegment is not ODataKeySegment &&
658658
((isCollection && subPath.Kind == ODataPathKind.EntitySet) ||
659659
(!isCollection && !_oDataPathKindsToSkipForOperationsWhenSingle.Contains(subPath.Kind))))
660660
{
661+
if (lastPathSegment is ODataTypeCastSegment && !convertSettings.AppendBoundOperationsOnDerivedTypeCastSegments) continue;
661662
ODataPath newPath = subPath.Clone();
662663
newPath.Push(new ODataOperationSegment(edmOperation, isEscapedFunction));
663664
AppendPath(newPath);
@@ -718,6 +719,7 @@ private void AppendBoundOperationOnDerived(
718719
IEdmEntityType bindingEntityType,
719720
OpenApiConvertSettings convertSettings)
720721
{
722+
if (!convertSettings.AppendBoundOperationsOnDerivedTypeCastSegments) return;
721723
bool isEscapedFunction = _model.IsUrlEscapeFunction(edmOperation);
722724
foreach (var baseType in bindingEntityType.FindAllBaseTypes())
723725
{
@@ -781,6 +783,7 @@ private void AppendBoundOperationOnDerivedNavigationPropertyPath(
781783
IEdmEntityType bindingEntityType,
782784
OpenApiConvertSettings convertSettings)
783785
{
786+
if (!convertSettings.AppendBoundOperationsOnDerivedTypeCastSegments) return;
784787
bool isEscapedFunction = _model.IsUrlEscapeFunction(edmOperation);
785788

786789
foreach (var baseType in bindingEntityType.FindAllBaseTypes())

src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<PackageReleaseNotes>
2424
- Adds list of all derived types for discriminator mapping #219
2525
- Fixes reading restriction annotations for entity types defining navigation properties #220
26+
- Enables configuring appending bound operations on derived types #221
2627
</PackageReleaseNotes>
2728
<AssemblyName>Microsoft.OpenApi.OData.Reader</AssemblyName>
2829
<AssemblyOriginatorKeyFile>..\..\tool\Microsoft.OpenApi.OData.snk</AssemblyOriginatorKeyFile>

src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ public string PathPrefix
248248
/// </summary>
249249
public Dictionary<string, string> CustomXMLAttributesMapping { get; set; } = new();
250250

251+
/// <summary>
252+
/// Gets/sets a value indicating whether or not to append bound operations on derived type cast segments.
253+
/// </summary>
254+
public bool AppendBoundOperationsOnDerivedTypeCastSegments { get; set; } = false;
255+
251256
internal OpenApiConvertSettings Clone()
252257
{
253258
var newSettings = new OpenApiConvertSettings
@@ -288,7 +293,8 @@ internal OpenApiConvertSettings Clone()
288293
InnerErrorComplexTypeName = this.InnerErrorComplexTypeName,
289294
RequireRestrictionAnnotationsToGenerateComplexPropertyPaths = this.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths,
290295
ExpandDerivedTypesNavigationProperties = this.ExpandDerivedTypesNavigationProperties,
291-
CustomXMLAttributesMapping = this.CustomXMLAttributesMapping
296+
CustomXMLAttributesMapping = this.CustomXMLAttributesMapping,
297+
AppendBoundOperationsOnDerivedTypeCastSegments = this.AppendBoundOperationsOnDerivedTypeCastSegments
292298
};
293299

294300
return newSettings;

src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ abstract Microsoft.OpenApi.OData.Edm.ODataSegment.GetAnnotables() -> System.Coll
55
Microsoft.OpenApi.OData.Common.Utils
66
Microsoft.OpenApi.OData.Edm.EdmModelExtensions
77
Microsoft.OpenApi.OData.Edm.EdmTypeExtensions
8+
Microsoft.OpenApi.OData.OpenApiConvertSettings.AppendBoundOperationsOnDerivedTypeCastSegments.get -> bool
9+
Microsoft.OpenApi.OData.OpenApiConvertSettings.AppendBoundOperationsOnDerivedTypeCastSegments.set -> void
810
Microsoft.OpenApi.OData.OpenApiConvertSettings.ExpandDerivedTypesNavigationProperties.get -> bool
911
Microsoft.OpenApi.OData.OpenApiConvertSettings.ExpandDerivedTypesNavigationProperties.set -> void
1012
Microsoft.OpenApi.OData.OpenApiConvertSettings.CustomXMLAttributesMapping.get -> System.Collections.Generic.Dictionary<string, string>

test/Microsoft.OpenAPI.OData.Reader.Tests/Edm/ODataPathProviderTests.cs

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public void GetPathsForGraphBetaModelReturnsAllPaths()
5151

5252
// Assert
5353
Assert.NotNull(paths);
54-
Assert.Equal(16354, paths.Count());
54+
Assert.Equal(13836, paths.Count());
5555
}
5656

5757
[Fact]
@@ -63,7 +63,8 @@ public void GetPathsForGraphBetaModelWithDerivedTypesConstraintReturnsAllPaths()
6363
var settings = new OpenApiConvertSettings
6464
{
6565
RequireDerivedTypesConstraintForBoundOperations = true,
66-
ExpandDerivedTypesNavigationProperties = false
66+
ExpandDerivedTypesNavigationProperties = false,
67+
AppendBoundOperationsOnDerivedTypeCastSegments = true
6768
};
6869

6970
// Act
@@ -81,7 +82,8 @@ public void GetPathsDoesntReturnPathsForCountWhenDisabled()
8182
IEdmModel model = GetInheritanceModel(string.Empty);
8283
ODataPathProvider provider = new ODataPathProvider();
8384
var settings = new OpenApiConvertSettings {
84-
EnableDollarCountPath = false,
85+
EnableDollarCountPath = false,
86+
AppendBoundOperationsOnDerivedTypeCastSegments = true
8587
};
8688

8789
// Act
@@ -100,23 +102,35 @@ public void GetPathsDoesntReturnPathsForCountWhenDisabled()
100102
</Annotation>";
101103

102104
[Theory]
103-
[InlineData(false, false, true, 3)]
104-
[InlineData(false, false, false, 4)]
105-
[InlineData(true, false, true, 7)]
106-
[InlineData(true, false, false, 7)]
107-
[InlineData(false, true, false, 5)]
108-
[InlineData(false, true, true, 4)]
109-
[InlineData(true, true, true, 8)]
110-
[InlineData(true, true, false, 8)]
111-
public void GetOperationPathsForModelWithDerivedTypesConstraint(bool addAnnotation, bool getNavPropModel, bool requireConstraint, int expectedCount)
105+
[InlineData(false, false, true, true, 3)]
106+
[InlineData(false, false, false, true, 4)]
107+
[InlineData(false, false, false, false, 3)]
108+
[InlineData(true, false, true, true, 7)]
109+
[InlineData(true, false, true, false, 6)]
110+
[InlineData(true, false, false, true, 7)]
111+
[InlineData(true, false, false, false, 6)]
112+
[InlineData(false, true, false, true, 5)]
113+
[InlineData(false, true, false, false, 4)]
114+
[InlineData(false, true, true, true, 4)]
115+
[InlineData(true, true, true, true, 8)]
116+
[InlineData(true, true, true, false, 7)]
117+
[InlineData(true, true, false, true, 8)]
118+
[InlineData(true, true, false, false, 7)]
119+
public void GetOperationPathsForModelWithDerivedTypesConstraint(
120+
bool addAnnotation,
121+
bool getNavPropModel,
122+
bool requireConstraint,
123+
bool appendBoundOperationsOnDerivedTypes,
124+
int expectedCount)
112125
{
113126
// Arrange
114127
var annotation = addAnnotation ? derivedTypeAnnotation : string.Empty;
115128
IEdmModel model = getNavPropModel ? GetNavPropModel(annotation) : GetInheritanceModel(annotation);
116129
ODataPathProvider provider = new();
117130
var settings = new OpenApiConvertSettings
118131
{
119-
RequireDerivedTypesConstraintForBoundOperations = requireConstraint
132+
RequireDerivedTypesConstraintForBoundOperations = requireConstraint,
133+
AppendBoundOperationsOnDerivedTypeCastSegments = appendBoundOperationsOnDerivedTypes
120134
};
121135

122136
// Act
@@ -130,23 +144,36 @@ public void GetOperationPathsForModelWithDerivedTypesConstraint(bool addAnnotati
130144
Assert.Single(dollarCountPathsWithCastSegment);
131145
}
132146
[Theory]
133-
[InlineData(false, false, true, 4)]
134-
[InlineData(false, false, false, 7)]
135-
[InlineData(true, false, true, 7)]
136-
[InlineData(true, false, false, 7)]
137-
[InlineData(false, true, false, 8)]
138-
[InlineData(false, true, true, 5)]
139-
[InlineData(true, true, true, 8)]
140-
[InlineData(true, true, false, 8)]
141-
public void GetTypeCastPathsForModelWithDerivedTypesConstraint(bool addAnnotation, bool getNavPropModel, bool requireConstraint, int expectedCount)
147+
[InlineData(false, false, true, true, 4)]
148+
[InlineData(false, false, true, false, 3)]
149+
[InlineData(false, false, false, true, 7)]
150+
[InlineData(false, false, false, false, 6)]
151+
[InlineData(true, false, true, true, 7)]
152+
[InlineData(true, false, true, false, 6)]
153+
[InlineData(true, false, false, true, 7)]
154+
[InlineData(false, true, false, true, 8)]
155+
[InlineData(false, true, false, false, 7)]
156+
[InlineData(false, true, true, true, 5)]
157+
[InlineData(false, true, true, false, 4)]
158+
[InlineData(true, true, true, true, 8)]
159+
[InlineData(true, true, true, false, 7)]
160+
[InlineData(true, true, false, true, 8)]
161+
[InlineData(true, true, false, false, 7)]
162+
public void GetTypeCastPathsForModelWithDerivedTypesConstraint(
163+
bool addAnnotation,
164+
bool getNavPropModel,
165+
bool requireConstraint,
166+
bool appendBoundOperationsOnDerivedTypes,
167+
int expectedCount)
142168
{
143169
// Arrange
144170
var annotation = addAnnotation ? derivedTypeAnnotation : string.Empty;
145171
IEdmModel model = getNavPropModel ? GetNavPropModel(annotation) : GetInheritanceModel(annotation);
146172
ODataPathProvider provider = new();
147173
var settings = new OpenApiConvertSettings
148174
{
149-
RequireDerivedTypesConstraintForODataTypeCastSegments = requireConstraint
175+
RequireDerivedTypesConstraintForODataTypeCastSegments = requireConstraint,
176+
AppendBoundOperationsOnDerivedTypeCastSegments = appendBoundOperationsOnDerivedTypes
150177
};
151178

152179
// Act

test/Microsoft.OpenAPI.OData.Reader.Tests/EdmModelOpenApiExtensionsTest.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ public void TripServiceMetadataToOpenApiJsonWorks(OpenApiSpecVersion specVersion
211211
OpenApiSpecVersion = specVersion,
212212
AddSingleQuotesForStringParameters = true,
213213
AddEnumDescriptionExtension = true,
214+
AppendBoundOperationsOnDerivedTypeCastSegments = true
214215
};
215216
// Act
216217
string json = WriteEdmModelAsOpenApi(model, OpenApiFormat.Json, settings);
@@ -244,6 +245,7 @@ public void TripServiceMetadataToOpenApiYamlWorks(OpenApiSpecVersion specVersion
244245
OpenApiSpecVersion = specVersion,
245246
AddSingleQuotesForStringParameters = true,
246247
AddEnumDescriptionExtension = true,
248+
AppendBoundOperationsOnDerivedTypeCastSegments = true
247249
};
248250

249251
// Act

0 commit comments

Comments
 (0)