Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public static OpenApiPathItem LoadPathItem(ParseNode node)
{
var mapNode = node.CheckMapNode("PathItem");

var pointer = mapNode.GetReferencePointer();
if (pointer != null)
{
var refObject = mapNode.GetReferencedObject<OpenApiPathItem>(ReferenceType.Path, pointer);
return refObject;
}

var pathItem = new OpenApiPathItem();

ParseMap(mapNode, pathItem, _pathItemFixedFields, _pathItemPatternFields);
Expand Down
14 changes: 14 additions & 0 deletions src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ public OpenApiReference ConvertToOpenApiReference(
}
id = localSegments[3];
}
else if (id.StartsWith("/paths/"))
{
var localSegments = segments[1].Split('/');
if (localSegments.Length == 3)
{
// The reference of a path may contain JSON escape character ~1 for the forward-slash character, replace this otherwise
// the reference cannot be resolved.
id = localSegments[2].Replace("~1", "/");
}
else
{
throw new OpenApiException("Referenced Path mismatch");
}
}
else
{
openApiReference.IsFragrament = true;
Expand Down
3 changes: 3 additions & 0 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,9 @@ internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool
case ReferenceType.Callback:
return this.Components.Callbacks[reference.Id];

case ReferenceType.Path:
return this.Paths[reference.Id];

default:
throw new OpenApiException(Properties.SRResource.InvalidReferenceType);
}
Expand Down
7 changes: 6 additions & 1 deletion src/Microsoft.OpenApi/Models/ReferenceType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public enum ReferenceType
/// <summary>
/// Tags item.
/// </summary>
[Display("tags")] Tag
[Display("tags")] Tag,

/// <summary>
/// Paths item.
/// </summary>
[Display("paths")] Path
}
}
10 changes: 7 additions & 3 deletions src/Microsoft.OpenApi/Services/OpenApiWalker.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
Expand Down Expand Up @@ -449,8 +449,12 @@ internal void Walk(OpenApiPathItem pathItem)

if (pathItem != null)
{
Walk(OpenApiConstants.Parameters, () => Walk(pathItem.Parameters));
Walk(pathItem.Operations);
// The path may be a reference
if (!ProcessAsReference(pathItem))
{
Walk(OpenApiConstants.Parameters, () => Walk(pathItem.Parameters));
Walk(pathItem.Operations);
}
}
_visitor.Visit(pathItem as IOpenApiExtensible);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,24 @@ public void ParseLocalFileReference()
reference.Type.Should().Be(referenceType);
reference.ExternalResource.Should().Be(input);
}

[Fact]
public void ParseExternalPathReference()
{
// Arrange
var versionService = new OpenApiV3VersionService(Diagnostic);
var externalResource = "externalSchema.json";
var referenceJsonEscaped = "/paths/~1applications~1{AppUUID}~1services~1{ServiceName}";
var input = $"{externalResource}#{referenceJsonEscaped}";
var id = "/applications/{AppUUID}/services/{ServiceName}";

// Act
var reference = versionService.ConvertToOpenApiReference(input, null);

// Assert
reference.Type.Should().BeNull();
reference.ExternalResource.Should().Be(externalResource);
reference.Id.Should().Be(id);
}
}
}