diff --git a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs
index 3bde8489..0c5a17fb 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Edm/ODataPathProvider.cs
@@ -888,11 +888,32 @@ private void RetrieveBoundOperationPaths(OpenApiConvertSettings convertSettings)
continue;
}
+ ODataSegment secondLastSeg = functionPath.ElementAt(functionPath.Count - 2);
+ if (convertSettings.ComposableFunctionsExpansionDepth < 2 &&
+ functionPath.LastSegment is ODataOperationSegment &&
+ secondLastSeg is ODataOperationSegment)
+ {
+ // Only one level of composable functions expansion allowed
+ continue;
+ }
+
foreach (var navProperty in returnBindingEntityType.NavigationProperties())
{
- ODataPath newNavigationPath = functionPath.Clone();
- newNavigationPath.Push(new ODataNavigationPropertySegment(navProperty));
- AppendPath(newNavigationPath);
+ /* Get number of segments already appended after the first composable function segment
+ */
+ int composableFuncSegIndex = functionPath.Segments.IndexOf(
+ functionPath.Segments.FirstOrDefault(
+ x => x is ODataOperationSegment operationSegment &&
+ operationSegment.Operation is IEdmFunction edmFunction &&
+ edmFunction.IsComposable));
+ int currentDepth = functionPath.Count - composableFuncSegIndex - 1;
+
+ if (currentDepth < convertSettings.ComposableFunctionsExpansionDepth)
+ {
+ ODataPath newNavigationPath = functionPath.Clone();
+ newNavigationPath.Push(new ODataNavigationPropertySegment(navProperty));
+ AppendPath(newNavigationPath);
+ }
}
}
}
@@ -1171,6 +1192,12 @@ private void AppendBoundOperationOnOperationPath(IEdmOperation edmOperation, boo
continue;
}
+ var segName = path.LastSegment as ODataOperationSegment;
+ if (edmOperation.Name.Equals(segName?.Identifier))
+ {
+ continue;
+ }
+
ODataPath newOperationPath = path.Clone();
newOperationPath.Push(new ODataOperationSegment(edmOperation, isEscapedFunction, _model));
AppendPath(newOperationPath);
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 cb79ac6c..bb5af0b3 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.7
+ 1.6.8
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
- - Fixes empty response objects for OData type cast paths. #546
+ - Adds support for configuring composable functions generations #551
Microsoft.OpenApi.OData.Reader
..\..\tool\Microsoft.OpenApi.OData.snk
diff --git a/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs b/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs
index 1e14f1f2..a6c538c8 100644
--- a/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/OpenApiConvertSettings.cs
@@ -362,6 +362,11 @@ public bool ExpandDerivedTypesNavigationProperties
///
public bool UseStringArrayForQueryOptionsSchema { get; set; } = true;
+ ///
+ /// Gets/Sets a value indicating the depth to expand composable functions.
+ ///
+ public int ComposableFunctionsExpansionDepth { get; set; } = 1;
+
internal OpenApiConvertSettings Clone()
{
var newSettings = new OpenApiConvertSettings
@@ -416,7 +421,8 @@ internal OpenApiConvertSettings Clone()
EnableAliasForTypeCastSegments = this.EnableAliasForTypeCastSegments,
SemVerVersion = this.SemVerVersion,
EnableAliasForOperationSegments = this.EnableAliasForOperationSegments,
- UseStringArrayForQueryOptionsSchema = this.UseStringArrayForQueryOptionsSchema
+ UseStringArrayForQueryOptionsSchema = this.UseStringArrayForQueryOptionsSchema,
+ ComposableFunctionsExpansionDepth = this.ComposableFunctionsExpansionDepth
};
return newSettings;
diff --git a/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt b/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt
index 0b13d3ba..f94e5952 100644
--- a/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt
+++ b/src/Microsoft.OpenApi.OData.Reader/PublicAPI.Unshipped.txt
@@ -21,6 +21,8 @@ Microsoft.OpenApi.OData.OpenApiConvertSettings.AddEnumFlagsExtension.get -> bool
Microsoft.OpenApi.OData.OpenApiConvertSettings.AddEnumFlagsExtension.set -> void
Microsoft.OpenApi.OData.OpenApiConvertSettings.AppendBoundOperationsOnDerivedTypeCastSegments.get -> bool
Microsoft.OpenApi.OData.OpenApiConvertSettings.AppendBoundOperationsOnDerivedTypeCastSegments.set -> void
+Microsoft.OpenApi.OData.OpenApiConvertSettings.ComposableFunctionsExpansionDepth.get -> int
+Microsoft.OpenApi.OData.OpenApiConvertSettings.ComposableFunctionsExpansionDepth.set -> void
Microsoft.OpenApi.OData.OpenApiConvertSettings.CustomHttpMethodLinkRelMapping.get -> System.Collections.Generic.Dictionary
Microsoft.OpenApi.OData.OpenApiConvertSettings.CustomHttpMethodLinkRelMapping.set -> void
Microsoft.OpenApi.OData.OpenApiConvertSettings.EnableAliasForOperationSegments.get -> bool
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Edm/ODataPathProviderTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Edm/ODataPathProviderTests.cs
index 2c01862f..a450bc04 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Edm/ODataPathProviderTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Edm/ODataPathProviderTests.cs
@@ -52,7 +52,7 @@ public void GetPathsForGraphBetaModelReturnsAllPaths()
// Assert
Assert.NotNull(paths);
- Assert.Equal(16980, paths.Count());
+ Assert.Equal(15210, paths.Count());
AssertGraphBetaModelPaths(paths);
}
@@ -117,7 +117,7 @@ public void GetPathsForGraphBetaModelWithDerivedTypesConstraintReturnsAllPaths()
// Assert
Assert.NotNull(paths);
- Assert.Equal(17631, paths.Count());
+ Assert.Equal(15861, paths.Count());
}
[Theory]
@@ -208,9 +208,9 @@ public void GetPathsForComposableFunctionsReturnsAllPaths()
// Assert
Assert.NotNull(paths);
- Assert.Equal(38, paths.Count());
- Assert.Equal(20, paths.Where(p => p.LastSegment is ODataOperationSegment).Count());
- Assert.Equal(12, paths.Where(p => p.Segments.Count > 1 && p.LastSegment is ODataNavigationPropertySegment && p.Segments[p.Segments.Count - 2] is ODataOperationSegment).Count());
+ Assert.Equal(26, paths.Count());
+ Assert.Equal(17, paths.Where(p => p.LastSegment is ODataOperationSegment).Count());
+ Assert.Equal(3, paths.Where(p => p.Segments.Count > 1 && p.LastSegment is ODataNavigationPropertySegment && p.Segments[p.Segments.Count - 2] is ODataOperationSegment).Count());
}
[Fact]