Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
ffa629b
Create a document instance and use it as the host document when calli…
MaggieKimani1 Feb 26, 2024
a59071d
Clean up and update class access modifier to expose the proxy referen…
MaggieKimani1 Feb 26, 2024
6eee973
Add a test to assert that references are resolved using the proxy pat…
MaggieKimani1 Feb 26, 2024
532fc11
Clean up code
MaggieKimani1 Feb 26, 2024
bd9f1b4
Checks whether a component is a proxy reference
irvinesunday Feb 28, 2024
37c9e74
Merge remote-tracking branch 'origin/is/skip-proxy-ref-validation' in…
MaggieKimani1 Feb 29, 2024
b2c70b0
Check settings to see if user explicitly wants the $refs to be inlined
MaggieKimani1 Feb 29, 2024
374af0c
Clean up tests
MaggieKimani1 Feb 29, 2024
3142bdc
Remove the ResolveReferences() step in favor of using proxy reference…
MaggieKimani1 Mar 5, 2024
eac5e7a
Append a leading slash for a path item key
MaggieKimani1 Mar 5, 2024
6b58df2
Clean up code and tests
MaggieKimani1 Mar 5, 2024
3511f0a
Initialize the Reference property with the value of the local _reference
MaggieKimani1 Mar 5, 2024
9bcacf5
If the reference pointer points to an external file, extract the path…
MaggieKimani1 Mar 5, 2024
1db34f5
Return the tag proxy reference object when loading the tag object as …
MaggieKimani1 Mar 7, 2024
2476236
Clean up code and tests
MaggieKimani1 Mar 18, 2024
c13f150
Return a proxy reference object when loading security scheme as refer…
MaggieKimani1 Mar 18, 2024
692c100
Extract external ref path segment if present and use it in the proxy …
MaggieKimani1 Mar 18, 2024
73ee166
Add a check to serialize the reference only if unresolved
MaggieKimani1 Mar 18, 2024
64c8627
Add an external resource property for externally referenced security …
MaggieKimani1 Mar 18, 2024
7ccf612
Add null conditional operator
MaggieKimani1 Mar 18, 2024
7ed5737
Refactor code
MaggieKimani1 Mar 21, 2024
3e625bc
Clean up tests
MaggieKimani1 Mar 21, 2024
0a7a7e0
Create a mapping of type <string, pathItem> for webhooks node
MaggieKimani1 Mar 21, 2024
ee83e1a
Update API surface
MaggieKimani1 Mar 21, 2024
f47721e
Rename param
MaggieKimani1 Mar 21, 2024
47c6f58
Add a reusable method to get the reference ID and external resource path
MaggieKimani1 Mar 25, 2024
de9e457
Remove static document initially being used as a host document
MaggieKimani1 Mar 25, 2024
436ad1f
Use conditional statement
MaggieKimani1 Mar 25, 2024
cdd6029
Adds a private field to track the document instance and set it as a h…
MaggieKimani1 Mar 25, 2024
2ed2f7c
Use the host document in the Reference object to do reference resolut…
MaggieKimani1 Mar 25, 2024
011517a
Fix failing tests
MaggieKimani1 Mar 25, 2024
b4d87b5
Update LoadXXX methods to accept an optional host document parameter …
MaggieKimani1 Mar 25, 2024
5955a51
Add test to validate that a parameter fragment with a $ref is resolved
MaggieKimani1 Mar 25, 2024
aa40a85
Add a visitor that walks through an OpenApi document and sets the hos…
MaggieKimani1 Mar 25, 2024
2601edb
Code cleanup
MaggieKimani1 Mar 25, 2024
6c2a95b
Remove unnecessary using
MaggieKimani1 Mar 25, 2024
c6168af
Update public API interface
MaggieKimani1 Mar 25, 2024
e6655cc
Update fields to be readonly
MaggieKimani1 Mar 25, 2024
d600825
Resolve merge conflicts
MaggieKimani1 Mar 27, 2024
991b309
Resolve bugs from resolving merge conflicts
MaggieKimani1 Mar 27, 2024
f3f286c
Code clean up
MaggieKimani1 Mar 27, 2024
89c274a
Remove unnecessary code
MaggieKimani1 Mar 27, 2024
c0332af
Clean up API interface
MaggieKimani1 Mar 27, 2024
11e5c63
Update output file extension and register the Yaml reader
MaggieKimani1 Apr 2, 2024
06fd1df
Clean up logic
MaggieKimani1 Apr 2, 2024
eb4f9c5
Clean up
MaggieKimani1 Apr 2, 2024
607751a
Register Yaml reader
MaggieKimani1 Apr 2, 2024
6525525
Clean up code and add virtual keyword in V2 serializers for the proxy…
MaggieKimani1 Apr 2, 2024
d99ffd6
Add an internal constructor for testing purposes
MaggieKimani1 Apr 2, 2024
670f641
Fix failing tests
MaggieKimani1 Apr 2, 2024
42f7213
Remove unnecessary interface
MaggieKimani1 Apr 2, 2024
d587137
Reusable pathItems only exist in v31
MaggieKimani1 Apr 2, 2024
d85a810
Clean up logic Update tests
MaggieKimani1 Apr 2, 2024
859d657
Update API interface
MaggieKimani1 Apr 2, 2024
604388c
Update API interface
MaggieKimani1 Apr 2, 2024
d628df8
Remove obsolete method
MaggieKimani1 Apr 2, 2024
012ed30
Fix tests
MaggieKimani1 Apr 2, 2024
e1f0cbf
Remove the inlining code and test
MaggieKimani1 Apr 3, 2024
27f4aa2
Remove unnecessary property
MaggieKimani1 Apr 3, 2024
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
6 changes: 4 additions & 2 deletions src/Microsoft.OpenApi.Hidi/OpenApiService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ public static async Task TransformOpenApiDocument(HidiOptions options, ILogger l
if (options.Output == null)
{
#pragma warning disable CA1308 // Normalize strings to uppercase
var inputExtension = string.Concat(".", options.OpenApiFormat?.GetDisplayName().ToLowerInvariant())
?? GetInputPathExtension(options.OpenApi, options.Csdl);
var extension = options.OpenApiFormat?.GetDisplayName().ToLowerInvariant();
var inputExtension = !string.IsNullOrEmpty(extension) ? string.Concat(".", extension)
: GetInputPathExtension(options.OpenApi, options.Csdl);

#pragma warning restore CA1308 // Normalize strings to uppercase
options.Output = new($"./output{inputExtension}");
};
Expand Down
23 changes: 0 additions & 23 deletions src/Microsoft.OpenApi/Interfaces/IEffective.cs

This file was deleted.

3 changes: 2 additions & 1 deletion src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ internal interface IOpenApiVersionService
/// </summary>
/// <typeparam name="T">Type of element to load</typeparam>
/// <param name="node">document fragment node</param>
/// <param name="doc">A host document instance.</param>
/// <returns>Instance of OpenAPIElement</returns>
T LoadElement<T>(ParseNode node) where T : IOpenApiElement;
T LoadElement<T>(ParseNode node, OpenApiDocument doc = null) where T : IOpenApiElement;

/// <summary>
/// Converts a generic RootNode instance into a strongly typed OpenApiDocument
Expand Down
38 changes: 2 additions & 36 deletions src/Microsoft.OpenApi/Models/OpenApiCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Callback Object: A map of possible out-of band callbacks related to the parent operation.
/// </summary>
public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiCallback>
public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible
{
/// <summary>
/// A Path Item Object used to define a callback request and expected responses.
Expand Down Expand Up @@ -61,10 +61,7 @@ public void AddPathItem(RuntimeExpression expression, OpenApiPathItem pathItem)
Utils.CheckArgumentNull(expression);
Utils.CheckArgumentNull(pathItem);

if (PathItems == null)
{
PathItems = new();
}
PathItems ??= new();

PathItems.Add(expression, pathItem);
}
Expand Down Expand Up @@ -102,40 +99,9 @@ private void SerializeInternal(IOpenApiWriter writer,
Utils.CheckArgumentNull(writer);

var target = this;

if (Reference != null)
{
if (!writer.GetSettings().ShouldInlineReference(Reference))
{
callback(writer, Reference);
return;
}
else
{
target = GetEffective(Reference.HostDocument);
}
}

action(writer, target);
}

/// <summary>
/// Returns an effective OpenApiCallback object based on the presence of a $ref
/// </summary>
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
/// <returns>OpenApiCallback</returns>
public OpenApiCallback GetEffective(OpenApiDocument doc)
{
if (Reference != null)
{
return doc.ResolveReferenceTo<OpenApiCallback>(Reference);
}
else
{
return this;
}
}

/// <summary>
/// Serialize to OpenAPI V31 document without using reference.
/// </summary>
Expand Down
53 changes: 25 additions & 28 deletions src/Microsoft.OpenApi/Models/OpenApiDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,16 @@ public IEnumerable<OpenApiError> ResolveReferences()
return resolver.Errors;
}

/// <summary>
/// Walks the OpenApiDocument and sets the host document for all referenceable objects
/// </summary>
public void SetHostDocument()
{
var resolver = new HostDocumentResolver(this);
var walker = new OpenApiWalker(resolver);
walker.Walk(this);
}

/// <summary>
/// Load the referenced <see cref="IOpenApiReferenceable"/> object from a <see cref="OpenApiReference"/> object
/// </summary>
Expand Down Expand Up @@ -562,49 +572,30 @@ internal IOpenApiReferenceable ResolveReference(OpenApiReference reference, bool
switch (reference.Type)
{
case ReferenceType.PathItem:
var resolvedPathItem = this.Components.PathItems[reference.Id];
resolvedPathItem.Description = reference.Description ?? resolvedPathItem.Description;
resolvedPathItem.Summary = reference.Summary ?? resolvedPathItem.Summary;
return resolvedPathItem;

return Components.PathItems[reference.Id];
case ReferenceType.Response:
var resolvedResponse = this.Components.Responses[reference.Id];
resolvedResponse.Description = reference.Description ?? resolvedResponse.Description;
return resolvedResponse;
return Components.Responses[reference.Id];

case ReferenceType.Parameter:
var resolvedParameter = this.Components.Parameters[reference.Id];
resolvedParameter.Description = reference.Description ?? resolvedParameter.Description;
return resolvedParameter;
return Components.Parameters[reference.Id];

case ReferenceType.Example:
var resolvedExample = this.Components.Examples[reference.Id];
resolvedExample.Summary = reference.Summary ?? resolvedExample.Summary;
resolvedExample.Description = reference.Description ?? resolvedExample.Description;
return resolvedExample;
return Components.Examples[reference.Id];

case ReferenceType.RequestBody:
var resolvedRequestBody = this.Components.RequestBodies[reference.Id];
resolvedRequestBody.Description = reference.Description ?? resolvedRequestBody.Description;
return resolvedRequestBody;
return Components.RequestBodies[reference.Id];

case ReferenceType.Header:
var resolvedHeader = this.Components.Headers[reference.Id];
resolvedHeader.Description = reference.Description ?? resolvedHeader.Description;
return resolvedHeader;
return Components.Headers[reference.Id];

case ReferenceType.SecurityScheme:
var resolvedSecurityScheme = this.Components.SecuritySchemes[reference.Id];
resolvedSecurityScheme.Description = reference.Description ?? resolvedSecurityScheme.Description;
return resolvedSecurityScheme;
return Components.SecuritySchemes[reference.Id];

case ReferenceType.Link:
var resolvedLink = this.Components.Links[reference.Id];
resolvedLink.Description = reference.Description ?? resolvedLink.Description;
return resolvedLink;
return Components.Links[reference.Id];

case ReferenceType.Callback:
return this.Components.Callbacks[reference.Id];
return Components.Callbacks[reference.Id];

default:
throw new OpenApiException(Properties.SRResource.InvalidReferenceType);
Expand Down Expand Up @@ -716,6 +707,12 @@ public JsonSchema FindSubschema(Json.Pointer.JsonPointer pointer, EvaluationOpti
{
throw new NotImplementedException();
}

internal JsonSchema ResolveJsonSchemaReference(Uri reference)
{
var referencePath = string.Concat("https://registry", reference.OriginalString.Split('#').Last());
return (JsonSchema)SchemaRegistry.Global.Get(new Uri(referencePath));
}
}

internal class FindSchemaReferences : OpenApiVisitorBase
Expand Down
32 changes: 1 addition & 31 deletions src/Microsoft.OpenApi/Models/OpenApiExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Example Object.
/// </summary>
public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiExample>
public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible
{
/// <summary>
/// Short description for the example.
Expand Down Expand Up @@ -101,39 +101,9 @@ internal virtual void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWr
Utils.CheckArgumentNull(writer);

var target = this;

if (Reference != null)
{
if (!writer.GetSettings().ShouldInlineReference(Reference))
{
callback(writer, Reference);
return;
}
else
{
target = GetEffective(Reference.HostDocument);
}
}
action(writer, target);
}

/// <summary>
/// Returns an effective OpenApiExample object based on the presence of a $ref
/// </summary>
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
/// <returns>OpenApiExample</returns>
public OpenApiExample GetEffective(OpenApiDocument doc)
{
if (Reference != null)
{
return doc.ResolveReferenceTo<OpenApiExample>(this.Reference);
}
else
{
return this;
}
}

/// <summary>
/// Serialize to OpenAPI V31 example without using reference.
/// </summary>
Expand Down
50 changes: 3 additions & 47 deletions src/Microsoft.OpenApi/Models/OpenApiHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.OpenApi.Models
/// Header Object.
/// The Header Object follows the structure of the Parameter Object.
/// </summary>
public class OpenApiHeader : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiHeader>
public class OpenApiHeader : IOpenApiReferenceable, IOpenApiExtensible
{
private JsonSchema _schema;

Expand Down Expand Up @@ -145,40 +145,9 @@ private void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, IOp
Utils.CheckArgumentNull(writer);;

var target = this;

if (Reference != null)
{
if (!writer.GetSettings().ShouldInlineReference(Reference))
{
callback(writer, Reference);
return;
}
else
{
target = GetEffective(Reference.HostDocument);
}
}

action(writer, target);
}

/// <summary>
/// Returns an effective OpenApiHeader object based on the presence of a $ref
/// </summary>
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
/// <returns>OpenApiHeader</returns>
public OpenApiHeader GetEffective(OpenApiDocument doc)
{
if (Reference != null)
{
return doc.ResolveReferenceTo<OpenApiHeader>(Reference);
}
else
{
return this;
}
}

/// <summary>
/// Serialize to OpenAPI V31 document without using reference.
/// </summary>
Expand Down Expand Up @@ -244,24 +213,11 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O
/// <summary>
/// Serialize <see cref="OpenApiHeader"/> to Open Api v2.0
/// </summary>
public void SerializeAsV2(IOpenApiWriter writer)
public virtual void SerializeAsV2(IOpenApiWriter writer)
{
Utils.CheckArgumentNull(writer);;
Utils.CheckArgumentNull(writer);

var target = this;

if (Reference != null)
{
if (!writer.GetSettings().ShouldInlineReference(Reference))
{
Reference.SerializeAsV2(writer);
return;
}
else
{
target = GetEffective(Reference.HostDocument);
}
}
target.SerializeAsV2WithoutReference(writer);
}

Expand Down
32 changes: 1 addition & 31 deletions src/Microsoft.OpenApi/Models/OpenApiLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// Link Object.
/// </summary>
public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IEffective<OpenApiLink>
public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible
{
/// <summary>
/// A relative or absolute reference to an OAS operation.
Expand Down Expand Up @@ -106,39 +106,9 @@ private void SerializeInternal(IOpenApiWriter writer, Action<IOpenApiWriter, IOp
Utils.CheckArgumentNull(writer);

var target = this;

if (Reference != null)
{
if (!writer.GetSettings().ShouldInlineReference(Reference))
{
callback(writer, Reference);
return;
}
else
{
target = GetEffective(Reference.HostDocument);
}
}
action(writer, target);
}

/// <summary>
/// Returns an effective OpenApiLink object based on the presence of a $ref
/// </summary>
/// <param name="doc">The host OpenApiDocument that contains the reference.</param>
/// <returns>OpenApiLink</returns>
public OpenApiLink GetEffective(OpenApiDocument doc)
{
if (Reference != null)
{
return doc.ResolveReferenceTo<OpenApiLink>(Reference);
}
else
{
return this;
}
}

/// <summary>
/// Serialize to OpenAPI V31 document without using reference.
/// </summary>
Expand Down
Loading