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 d8b32420..7ab181e8 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.7.2
+ 1.7.3
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
- - Adds action/function suffix to tag names for actions/functions operations in #642
+ - Fix regression in unique operation id generation at #462.
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 a9b5ebac..5fe1a590 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmOperationOperationHandler.cs
@@ -81,6 +81,7 @@ protected override void SetBasicInfo(OpenApiOperation operation)
// duplicates in entity vs entityset functions/actions
List identifiers = new();
+ string pathHash = string.Empty;
foreach (ODataSegment segment in Path.Segments)
{
if (segment is ODataKeySegment keySegment)
@@ -101,6 +102,18 @@ protected override void SetBasicInfo(OpenApiOperation operation)
identifiers.Add(keySegment.Identifier);
}
}
+ else if (segment is ODataOperationSegment opSegment)
+ {
+ if (opSegment.Operation is IEdmFunction function && Context.Model.IsOperationOverload(function))
+ {
+ // Hash the segment to avoid duplicate operationIds
+ pathHash = string.IsNullOrEmpty(pathHash)
+ ? opSegment.GetPathHash(Context.Settings)
+ : (pathHash + opSegment.GetPathHash(Context.Settings)).GetHashSHA256().Substring(0, 4);
+ }
+
+ identifiers.Add(segment.Identifier);
+ }
else
{
identifiers.Add(segment.Identifier);
@@ -109,21 +122,13 @@ protected override void SetBasicInfo(OpenApiOperation operation)
string operationId = string.Join(".", identifiers);
- if (EdmOperation.IsAction())
- {
- operation.OperationId = operationId;
- }
- else
- {
- if (Path.LastSegment is ODataOperationSegment operationSegment &&
- Context.Model.IsOperationOverload(operationSegment.Operation))
- {
- operation.OperationId = operationId + "-" + Path.LastSegment.GetPathHash(Context.Settings);
- }
- else
- {
- operation.OperationId = operationId;
- }
+ if (!string.IsNullOrEmpty(pathHash))
+ {
+ operation.OperationId = operationId + "-" + pathHash;
+ }
+ else
+ {
+ operation.OperationId = operationId;
}
}
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
index dd0fa6ba..5fe3d716 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
@@ -3,6 +3,7 @@
// 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 System.Xml.Linq;
@@ -378,10 +379,18 @@ public void CreateOperationForComposableOverloadEdmFunctionReturnsCorrectOperati
if (enableOperationId)
{
- Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-6b6d", operation1.OperationId);
- Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-2636", operation2.OperationId);
- Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-6b6d", operation3.OperationId);
- Assert.Equal("Customers.Customer.MyFunction1.MyFunction2-2636", operation4.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);
+ var operationIds = new HashSet(StringComparer.OrdinalIgnoreCase)
+ {
+ operation1.OperationId,
+ operation2.OperationId,
+ operation3.OperationId,
+ operation4.OperationId
+ };
+ Assert.Equal(4, operationIds.Count);// All are unique as the hashset size is unchanged!
}
else
{