Skip to content

Commit 050dd51

Browse files
authored
Merge pull request #1246 from elize-vdr/ISSUE-#1228-Path-as-reference-to-external
Issue #1228 path as reference to external
2 parents b1c42fe + e833d1b commit 050dd51

File tree

6 files changed

+54
-3
lines changed

6 files changed

+54
-3
lines changed

src/Microsoft.OpenApi.Readers/V3/OpenApiPathItemDeserializer.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ public static OpenApiPathItem LoadPathItem(ParseNode node)
5656
{
5757
var mapNode = node.CheckMapNode("PathItem");
5858

59+
var pointer = mapNode.GetReferencePointer();
60+
if (pointer != null)
61+
{
62+
var refObject = mapNode.GetReferencedObject<OpenApiPathItem>(ReferenceType.Path, pointer);
63+
return refObject;
64+
}
65+
5966
var pathItem = new OpenApiPathItem();
6067

6168
ParseMap(mapNode, pathItem, _pathItemFixedFields, _pathItemPatternFields);

src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ internal class OpenApiV3VersionService : IOpenApiVersionService
2121
{
2222
public OpenApiDiagnostic Diagnostic { get; }
2323

24+
private static readonly char[] _pathSeparator = new char[] { '/' };
25+
2426
/// <summary>
2527
/// Create Parsing Context
2628
/// </summary>
@@ -129,6 +131,20 @@ public OpenApiReference ConvertToOpenApiReference(
129131
}
130132
id = localSegments[3];
131133
}
134+
else if (id.StartsWith("/paths/"))
135+
{
136+
var localSegments = segments[1].Split(_pathSeparator, StringSplitOptions.RemoveEmptyEntries);
137+
if (localSegments.Length == 2)
138+
{
139+
// The reference of a path may contain JSON escape character ~1 for the forward-slash character, replace this otherwise
140+
// the reference cannot be resolved.
141+
id = localSegments[1].Replace("~1", "/");
142+
}
143+
else
144+
{
145+
throw new OpenApiException("Referenced Path mismatch");
146+
}
147+
}
132148
else
133149
{
134150
openApiReference.IsFragrament = true;

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,9 @@ internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool
504504
case ReferenceType.Callback:
505505
return this.Components.Callbacks[reference.Id];
506506

507+
case ReferenceType.Path:
508+
return this.Paths[reference.Id];
509+
507510
default:
508511
throw new OpenApiException(Properties.SRResource.InvalidReferenceType);
509512
}

src/Microsoft.OpenApi/Models/ReferenceType.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public enum ReferenceType
5858
/// <summary>
5959
/// Tags item.
6060
/// </summary>
61-
[Display("tags")] Tag
61+
[Display("tags")] Tag,
62+
63+
/// <summary>
64+
/// Paths item.
65+
/// </summary>
66+
[Display("paths")] Path
6267
}
6368
}

src/Microsoft.OpenApi/Services/OpenApiWalker.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

44
using System;
@@ -447,7 +447,8 @@ internal void Walk(OpenApiPathItem pathItem)
447447

448448
_visitor.Visit(pathItem);
449449

450-
if (pathItem != null)
450+
// The path may be a reference
451+
if (pathItem != null && !ProcessAsReference(pathItem))
451452
{
452453
Walk(OpenApiConstants.Parameters, () => Walk(pathItem.Parameters));
453454
Walk(pathItem.Operations);

test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,5 +124,24 @@ public void ParseLocalFileReference()
124124
reference.Type.Should().Be(referenceType);
125125
reference.ExternalResource.Should().Be(input);
126126
}
127+
128+
[Fact]
129+
public void ParseExternalPathReference()
130+
{
131+
// Arrange
132+
var versionService = new OpenApiV3VersionService(Diagnostic);
133+
var externalResource = "externalSchema.json";
134+
var referenceJsonEscaped = "/paths/~1applications~1{AppUUID}~1services~1{ServiceName}";
135+
var input = $"{externalResource}#{referenceJsonEscaped}";
136+
var id = "/applications/{AppUUID}/services/{ServiceName}";
137+
138+
// Act
139+
var reference = versionService.ConvertToOpenApiReference(input, null);
140+
141+
// Assert
142+
reference.Type.Should().BeNull();
143+
reference.ExternalResource.Should().Be(externalResource);
144+
reference.Id.Should().Be(id);
145+
}
127146
}
128147
}

0 commit comments

Comments
 (0)