Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #1228 path as reference to external #1246

Merged
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/"))
baywet marked this conversation as resolved.
Show resolved Hide resolved
{
var localSegments = segments[1].Split('/');
baywet marked this conversation as resolved.
Show resolved Hide resolved
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", "/");
baywet marked this conversation as resolved.
Show resolved Hide resolved
}
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))
baywet marked this conversation as resolved.
Show resolved Hide resolved
{
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);
}
}
}