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 0f15949b..d0950ef2 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
+++ b/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
@@ -15,7 +15,7 @@
net8.0
Microsoft.OpenApi.OData
true
- 2.0.0-preview.4
+ 2.0.0-preview.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
@@ -28,8 +28,9 @@
- Adds nullable to double schema conversions #581
- Updates tag names for actions/functions operations #585
- Creates unique operation ids for paths with composable overloaded functions #580
- - Further fixes for double/decimal/float schema conversions #581
- - Replaced integer types by number types
+ - Further fixes for double/decimal/float schema conversions #581
+ - Replaced integer types by number types
+ - Further fix for generating unique operation ids for paths with composable overloaded functions where all functions in path are overloaded #594
Microsoft.OpenApi.OData.Reader
..\..\tool\Microsoft.OpenApi.OData.snk
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
index ad6217e9..e1f05f39 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
@@ -107,7 +107,9 @@ protected override void SetBasicInfo(OpenApiOperation operation)
if (opSegment.Operation is IEdmFunction function && Context.Model.IsOperationOverload(function))
{
// Hash the segment to avoid duplicate operationIds
- pathHash = segment.GetPathHash(Context.Settings);
+ pathHash = string.IsNullOrEmpty(pathHash)
+ ? opSegment.GetPathHash(Context.Settings)
+ : (pathHash + opSegment.GetPathHash(Context.Settings)).GetHashSHA256()[..4];
}
identifiers.Add(segment.Identifier);
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
index 5f225a81..f92a2383 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
@@ -310,22 +310,29 @@ public void CreateOperationForComposableOverloadEdmFunctionReturnsCorrectOperati
customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
model.AddElement(customer);
- EdmFunction function = new("NS", "MyFunction", EdmCoreModel.Instance.GetString(false), true, null, false);
- function.AddParameter("entity", new EdmEntityTypeReference(customer, false));
- function.AddParameter("param", EdmCoreModel.Instance.GetString(false));
- model.AddElement(function);
+ // Overloaded function 1
+ EdmFunction function1 = new("NS", "MyFunction1", EdmCoreModel.Instance.GetString(false), true, null, false);
+ function1.AddParameter("entity", new EdmEntityTypeReference(customer, false));
+ model.AddElement(function1);
- function = new EdmFunction("NS", "MyFunction", EdmCoreModel.Instance.GetString(false), true, null, false);
- function.AddParameter("entity", new EdmEntityTypeReference(customer, false));
- function.AddParameter("param", EdmCoreModel.Instance.GetString(false));
- function.AddParameter("param2", EdmCoreModel.Instance.GetString(false));
- model.AddElement(function);
+ // Overloaded function 1
+ EdmFunction function2 = new("NS", "MyFunction1", EdmCoreModel.Instance.GetString(false), true, null, false);
+ function2.AddParameter("entity", new EdmEntityTypeReference(customer, false));
+ function2.AddParameter("param", EdmCoreModel.Instance.GetString(false));
- EdmFunction function2 = new("NS", "MyFunction2", EdmCoreModel.Instance.GetString(false), true, null, false);
- function2.AddParameter("entity2", new EdmEntityTypeReference(customer, false));
- function2.AddParameter("param3", EdmCoreModel.Instance.GetString(false));
model.AddElement(function2);
+ // Overloaded function 2
+ EdmFunction function3 = new("NS", "MyFunction2", EdmCoreModel.Instance.GetString(false), true, null, false);
+ function3.AddParameter("entity2", new EdmEntityTypeReference(customer, false));
+ model.AddElement(function3);
+
+ // Overloaded function 2
+ EdmFunction function4 = new("NS", "MyFunction2", EdmCoreModel.Instance.GetString(false), true, null, false);
+ function4.AddParameter("entity2", new EdmEntityTypeReference(customer, false));
+ function4.AddParameter("param", EdmCoreModel.Instance.GetString(false));
+ model.AddElement(function4);
+
EdmEntityContainer container = new("NS", "Default");
EdmEntitySet customers = new(container, "Customers", customer);
model.AddElement(container);
@@ -337,24 +344,51 @@ public void CreateOperationForComposableOverloadEdmFunctionReturnsCorrectOperati
};
ODataContext context = new(model, settings);
- ODataPath path = new(new ODataNavigationSourceSegment(customers),
+ ODataPath path1 = new(new ODataNavigationSourceSegment(customers),
new ODataKeySegment(customer),
- new ODataOperationSegment(function),
- new ODataOperationSegment(function2));
+ new ODataOperationSegment(function1),
+ new ODataOperationSegment(function3));
+
+ ODataPath path2 = new(new ODataNavigationSourceSegment(customers),
+ new ODataKeySegment(customer),
+ new ODataOperationSegment(function1),
+ new ODataOperationSegment(function4));
+
+ ODataPath path3 = new(new ODataNavigationSourceSegment(customers),
+ new ODataKeySegment(customer),
+ new ODataOperationSegment(function2),
+ new ODataOperationSegment(function3));
+
+ ODataPath path4 = new(new ODataNavigationSourceSegment(customers),
+ new ODataKeySegment(customer),
+ new ODataOperationSegment(function2),
+ new ODataOperationSegment(function4));
// Act
- var operation = _operationHandler.CreateOperation(context, path);
+ var operation1 = _operationHandler.CreateOperation(context, path1);
+ var operation2 = _operationHandler.CreateOperation(context, path2);
+ var operation3 = _operationHandler.CreateOperation(context, path3);
+ var operation4 = _operationHandler.CreateOperation(context, path4);
// Assert
- Assert.NotNull(operation);
+ Assert.NotNull(operation1);
+ Assert.NotNull(operation2);
+ Assert.NotNull(operation3);
+ Assert.NotNull(operation4);
if (enableOperationId)
{
- Assert.Equal("Customers.Customer.MyFunction.MyFunction2-df74", operation.OperationId);
+ Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-c53d", operation1.OperationId);
+ Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-4d93", operation2.OperationId);
+ Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-a2b2", operation3.OperationId);
+ Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-7bea", operation4.OperationId);
}
else
{
- Assert.Null(operation.OperationId);
+ Assert.Null(operation1.OperationId);
+ Assert.Null(operation2.OperationId);
+ Assert.Null(operation3.OperationId);
+ Assert.Null(operation4.OperationId);
}
}