diff --git a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs index 519de3503..be97e8dc3 100644 --- a/src/Microsoft.OpenApi.Hidi/OpenApiService.cs +++ b/src/Microsoft.OpenApi.Hidi/OpenApiService.cs @@ -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}"); }; diff --git a/src/Microsoft.OpenApi/Interfaces/IEffective.cs b/src/Microsoft.OpenApi/Interfaces/IEffective.cs deleted file mode 100644 index 23d7fdcf1..000000000 --- a/src/Microsoft.OpenApi/Interfaces/IEffective.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -using Microsoft.OpenApi.Models; - -namespace Microsoft.OpenApi.Interfaces -{ - /// - /// OpenApiElements that implement IEffective indicate that their description is not self-contained. - /// External elements affect the effective description. - /// - /// Currently this will only be used for accessing external references. - /// In the next major version, this will be the approach accessing all referenced elements. - /// This will enable us to support merging properties that are peers of the $ref - /// Type of OpenApi Element that is being referenced. - public interface IEffective where T : class, IOpenApiElement - { - /// - /// Returns a calculated and cloned version of the element. - /// - T GetEffective(OpenApiDocument document); - } -} diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs index c3df35972..97d1d3c9b 100644 --- a/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs +++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiVersionService.cs @@ -26,8 +26,9 @@ internal interface IOpenApiVersionService /// /// Type of element to load /// document fragment node + /// A host document instance. /// Instance of OpenAPIElement - T LoadElement(ParseNode node) where T : IOpenApiElement; + T LoadElement(ParseNode node, OpenApiDocument doc = null) where T : IOpenApiElement; /// /// Converts a generic RootNode instance into a strongly typed OpenApiDocument diff --git a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs index 23910545b..ce8342d67 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiCallback.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiCallback.cs @@ -12,7 +12,7 @@ namespace Microsoft.OpenApi.Models /// /// Callback Object: A map of possible out-of band callbacks related to the parent operation. /// - public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible, IEffective + public class OpenApiCallback : IOpenApiReferenceable, IOpenApiExtensible { /// /// A Path Item Object used to define a callback request and expected responses. @@ -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); } @@ -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); } - /// - /// Returns an effective OpenApiCallback object based on the presence of a $ref - /// - /// The host OpenApiDocument that contains the reference. - /// OpenApiCallback - public OpenApiCallback GetEffective(OpenApiDocument doc) - { - if (Reference != null) - { - return doc.ResolveReferenceTo(Reference); - } - else - { - return this; - } - } - /// /// Serialize to OpenAPI V31 document without using reference. /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs index d42f46638..292a9bf9a 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs @@ -455,6 +455,16 @@ public IEnumerable ResolveReferences() return resolver.Errors; } + /// + /// Walks the OpenApiDocument and sets the host document for all referenceable objects + /// + public void SetHostDocument() + { + var resolver = new HostDocumentResolver(this); + var walker = new OpenApiWalker(resolver); + walker.Walk(this); + } + /// /// Load the referenced object from a object /// @@ -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); @@ -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 diff --git a/src/Microsoft.OpenApi/Models/OpenApiExample.cs b/src/Microsoft.OpenApi/Models/OpenApiExample.cs index 8d101b129..d55c57daa 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiExample.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiExample.cs @@ -13,7 +13,7 @@ namespace Microsoft.OpenApi.Models /// /// Example Object. /// - public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible, IEffective + public class OpenApiExample : IOpenApiReferenceable, IOpenApiExtensible { /// /// Short description for the example. @@ -101,39 +101,9 @@ internal virtual void SerializeInternal(IOpenApiWriter writer, Action - /// Returns an effective OpenApiExample object based on the presence of a $ref - /// - /// The host OpenApiDocument that contains the reference. - /// OpenApiExample - public OpenApiExample GetEffective(OpenApiDocument doc) - { - if (Reference != null) - { - return doc.ResolveReferenceTo(this.Reference); - } - else - { - return this; - } - } - /// /// Serialize to OpenAPI V31 example without using reference. /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs index be10435dd..25d55f002 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiHeader.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiHeader.cs @@ -16,7 +16,7 @@ namespace Microsoft.OpenApi.Models /// Header Object. /// The Header Object follows the structure of the Parameter Object. /// - public class OpenApiHeader : IOpenApiReferenceable, IOpenApiExtensible, IEffective + public class OpenApiHeader : IOpenApiReferenceable, IOpenApiExtensible { private JsonSchema _schema; @@ -145,40 +145,9 @@ private void SerializeInternal(IOpenApiWriter writer, Action - /// Returns an effective OpenApiHeader object based on the presence of a $ref - /// - /// The host OpenApiDocument that contains the reference. - /// OpenApiHeader - public OpenApiHeader GetEffective(OpenApiDocument doc) - { - if (Reference != null) - { - return doc.ResolveReferenceTo(Reference); - } - else - { - return this; - } - } - /// /// Serialize to OpenAPI V31 document without using reference. /// @@ -244,24 +213,11 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O /// /// Serialize to Open Api v2.0 /// - 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); } diff --git a/src/Microsoft.OpenApi/Models/OpenApiLink.cs b/src/Microsoft.OpenApi/Models/OpenApiLink.cs index 794d1c15a..d9c9e343c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiLink.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiLink.cs @@ -11,7 +11,7 @@ namespace Microsoft.OpenApi.Models /// /// Link Object. /// - public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible, IEffective + public class OpenApiLink : IOpenApiReferenceable, IOpenApiExtensible { /// /// A relative or absolute reference to an OAS operation. @@ -106,39 +106,9 @@ private void SerializeInternal(IOpenApiWriter writer, Action - /// Returns an effective OpenApiLink object based on the presence of a $ref - /// - /// The host OpenApiDocument that contains the reference. - /// OpenApiLink - public OpenApiLink GetEffective(OpenApiDocument doc) - { - if (Reference != null) - { - return doc.ResolveReferenceTo(Reference); - } - else - { - return this; - } - } - /// /// Serialize to OpenAPI V31 document without using reference. /// diff --git a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs index 9f05669f0..498e93306 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiOperation.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiOperation.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models @@ -256,18 +257,13 @@ public void SerializeAsV2(IOpenApiWriter writer) } else if (RequestBody.Reference != null) { + var hostDocument = RequestBody.Reference.HostDocument; parameters.Add( - new() - { - UnresolvedReference = true, - Reference = RequestBody.Reference - }); + new OpenApiParameterReference(RequestBody.Reference.Id, hostDocument)); - if (RequestBody.Reference.HostDocument != null) - { - var effectiveRequestBody = RequestBody.GetEffective(RequestBody.Reference.HostDocument); - if (effectiveRequestBody != null) - consumes = effectiveRequestBody.Content.Keys.Distinct().ToList(); + if (hostDocument != null) + { + consumes = RequestBody.Content.Keys.Distinct().ToList(); } } @@ -291,7 +287,7 @@ public void SerializeAsV2(IOpenApiWriter writer) .Concat( Responses .Where(static r => r.Value.Reference is {HostDocument: not null}) - .SelectMany(static r => r.Value.GetEffective(r.Value.Reference.HostDocument)?.Content?.Keys)) + .SelectMany(static r => r.Value.Content?.Keys)) .Distinct() .ToList(); diff --git a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs index dab561d37..8c33a4412 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiParameter.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiParameter.cs @@ -15,7 +15,7 @@ namespace Microsoft.OpenApi.Models /// /// Parameter Object. /// - public class OpenApiParameter : IOpenApiReferenceable, IEffective, IOpenApiExtensible + public class OpenApiParameter : IOpenApiReferenceable, IOpenApiExtensible { private bool? _explode; private ParameterStyle? _style; @@ -199,40 +199,10 @@ private void SerializeInternal(IOpenApiWriter writer, Action - /// Returns an effective OpenApiParameter object based on the presence of a $ref - /// - /// The host OpenApiDocument that contains the reference. - /// OpenApiParameter - public OpenApiParameter GetEffective(OpenApiDocument doc) - { - if (Reference != null) - { - return doc.ResolveReferenceTo(Reference); - } - else - { - return this; - } - } - /// /// Serialize to OpenAPI V3 document without using reference. /// @@ -311,24 +281,11 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O /// /// Serialize to Open Api v2.0 /// - public void SerializeAsV2(IOpenApiWriter writer) + public virtual void SerializeAsV2(IOpenApiWriter writer) { Utils.CheckArgumentNull(writer);; var target = this; - if (Reference != null) - { - if (!writer.GetSettings().ShouldInlineReference(Reference)) - { - Reference.SerializeAsV2(writer); - return; - } - else - { - target = this.GetEffective(Reference.HostDocument); - } - } - target.SerializeAsV2WithoutReference(writer); } diff --git a/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs b/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs index 18a56a94b..fa2db1705 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiPathItem.cs @@ -12,7 +12,7 @@ namespace Microsoft.OpenApi.Models /// /// Path Item Object: to describe the operations available on a single path. /// - public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable, IEffective + public class OpenApiPathItem : IOpenApiExtensible, IOpenApiReferenceable { /// /// An optional, string summary, intended to apply to all operations in this path. @@ -112,61 +112,17 @@ private void SerializeInternal(IOpenApiWriter writer, Action - /// Returns an effective OpenApiPathItem object based on the presence of a $ref - /// - /// The host OpenApiDocument that contains the reference. - /// OpenApiPathItem - public OpenApiPathItem GetEffective(OpenApiDocument doc) - { - if (Reference != null) - { - return doc.ResolveReferenceTo(Reference); - } - else - { - return this; - } - } - /// /// Serialize to Open Api v2.0 /// - public void SerializeAsV2(IOpenApiWriter writer) + public virtual void SerializeAsV2(IOpenApiWriter 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); } diff --git a/src/Microsoft.OpenApi/Models/OpenApiReference.cs b/src/Microsoft.OpenApi/Models/OpenApiReference.cs index 130f5fd7d..da69e5004 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiReference.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiReference.cs @@ -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; @@ -174,7 +174,7 @@ public void SerializeAsV3(IOpenApiWriter writer) /// private void SerializeInternal(IOpenApiWriter writer) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); if (Type == ReferenceType.Tag) { diff --git a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs index 70abaf5ff..2ff1d6fd2 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiRequestBody.cs @@ -14,7 +14,7 @@ namespace Microsoft.OpenApi.Models /// /// Request Body Object /// - public class OpenApiRequestBody : IOpenApiReferenceable, IOpenApiExtensible, IEffective + public class OpenApiRequestBody : IOpenApiReferenceable, IOpenApiExtensible { /// /// Indicates if object is populated with data or is just a reference to the data @@ -90,19 +90,6 @@ private void SerializeInternal(IOpenApiWriter writer, Action /// Response object. /// - public class OpenApiResponse : IOpenApiReferenceable, IOpenApiExtensible, IEffective + public class OpenApiResponse : IOpenApiReferenceable, IOpenApiExtensible { /// /// REQUIRED. A short description of the response. @@ -95,39 +95,9 @@ private void SerializeInternal(IOpenApiWriter writer, Action - /// Returns an effective OpenApiRequestBody object based on the presence of a $ref - /// - /// The host OpenApiDocument that contains the reference. - /// OpenApiResponse - public OpenApiResponse GetEffective(OpenApiDocument doc) - { - if (Reference != null) - { - return doc.ResolveReferenceTo(Reference); - } - else - { - return this; - } - } - /// /// Serialize to OpenAPI V3 document without using reference. /// @@ -172,24 +142,11 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O /// /// Serialize to Open Api v2.0. /// - 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); } diff --git a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs index 2f2f7fa5f..964c9dc3c 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs @@ -118,13 +118,6 @@ private void SerializeInternal(IOpenApiWriter writer, Action action) { Utils.CheckArgumentNull(writer);; - - if (Reference != null) - { - callback(writer, Reference); - return; - } - action(writer); } @@ -194,16 +187,9 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O /// /// Serialize to Open Api v2.0 /// - public void SerializeAsV2(IOpenApiWriter writer) + public virtual void SerializeAsV2(IOpenApiWriter writer) { Utils.CheckArgumentNull(writer);; - - if (Reference != null) - { - Reference.SerializeAsV2(writer); - return; - } - SerializeAsV2WithoutReference(writer); } diff --git a/src/Microsoft.OpenApi/Models/OpenApiTag.cs b/src/Microsoft.OpenApi/Models/OpenApiTag.cs index 0feeb685c..6f79e0999 100644 --- a/src/Microsoft.OpenApi/Models/OpenApiTag.cs +++ b/src/Microsoft.OpenApi/Models/OpenApiTag.cs @@ -82,14 +82,7 @@ public virtual void SerializeAsV3(IOpenApiWriter writer) /// private void SerializeInternal(IOpenApiWriter writer, Action callback) { - Utils.CheckArgumentNull(writer);; - - if (Reference != null) - { - callback(writer, Reference); - return; - } - + Utils.CheckArgumentNull(writer); writer.WriteValue(Name); } @@ -134,16 +127,9 @@ internal virtual void SerializeInternalWithoutReference(IOpenApiWriter writer, O /// /// Serialize to Open Api v2.0 /// - public void SerializeAsV2(IOpenApiWriter writer) + public virtual void SerializeAsV2(IOpenApiWriter writer) { - Utils.CheckArgumentNull(writer);; - - if (Reference != null) - { - Reference.SerializeAsV2(writer); - return; - } - + Utils.CheckArgumentNull(writer); writer.WriteValue(Name); } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs index 33c76d1c2..0a28deab4 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiCallbackReference.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -15,14 +14,14 @@ namespace Microsoft.OpenApi.Models.References /// public class OpenApiCallbackReference : OpenApiCallback { - private OpenApiCallback _target; + internal OpenApiCallback _target; private readonly OpenApiReference _reference; private OpenApiCallback Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -43,10 +42,6 @@ public OpenApiCallbackReference(string referenceId, OpenApiDocument hostDocument { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -55,6 +50,19 @@ public OpenApiCallbackReference(string referenceId, OpenApiDocument hostDocument Type = ReferenceType.Callback, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiCallbackReference(OpenApiCallback target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.Callback, + }; } /// @@ -66,27 +74,29 @@ public OpenApiCallbackReference(string referenceId, OpenApiDocument hostDocument /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV3WithoutReference(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV3WithoutReference(writer)); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV31WithoutReference(writer)); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, - (writer, element) => element.SerializeAsV3(writer)); - } - - /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, - (writer, element) => element.SerializeAsV31(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV31WithoutReference(writer)); + } } /// diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs index 1fe4178f7..bf1de88e1 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiExampleReference.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -13,9 +12,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Example Object Reference. /// - internal class OpenApiExampleReference : OpenApiExample + public class OpenApiExampleReference : OpenApiExample { - private OpenApiExample _target; + internal OpenApiExample _target; private readonly OpenApiReference _reference; private string _summary; private string _description; @@ -24,7 +23,7 @@ private OpenApiExample Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -45,10 +44,6 @@ public OpenApiExampleReference(string referenceId, OpenApiDocument hostDocument, { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -57,6 +52,19 @@ public OpenApiExampleReference(string referenceId, OpenApiDocument hostDocument, Type = ReferenceType.Example, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiExampleReference(OpenApiExample target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.Example, + }; } /// @@ -85,25 +93,29 @@ public override string Summary /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV3WithoutReference(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV3WithoutReference(writer)); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV31WithoutReference(writer)); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0); - } - - /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, referenceElement) => referenceElement.SerializeAsV31WithoutReference(writer)); + } } /// diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs index 1a596d8e5..e934e3269 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiHeaderReference.cs @@ -6,14 +6,16 @@ using Json.Schema; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References { - internal class OpenApiHeaderReference : OpenApiHeader + /// + /// Header Object Reference. + /// + public class OpenApiHeaderReference : OpenApiHeader { - private OpenApiHeader _target; + internal OpenApiHeader _target; private readonly OpenApiReference _reference; private string _description; @@ -21,7 +23,7 @@ private OpenApiHeader Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -42,10 +44,6 @@ public OpenApiHeaderReference(string referenceId, OpenApiDocument hostDocument, { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -54,6 +52,19 @@ public OpenApiHeaderReference(string referenceId, OpenApiDocument hostDocument, Type = ReferenceType.Header, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiHeaderReference(OpenApiHeader target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.Header, + }; } /// @@ -99,27 +110,43 @@ public override string Description /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); + } } /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); - } - - /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, - (writer, element) => element.SerializeAsV31(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + } } /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) + public override void SerializeAsV2(IOpenApiWriter writer) { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, - (writer, element) => element.SerializeAsV3(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV2(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV2WithoutReference(writer)); + } } /// diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs index 9cba74124..15c48c96e 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiLinkReference.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -12,9 +11,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Link Object Reference. /// - internal class OpenApiLinkReference : OpenApiLink + public class OpenApiLinkReference : OpenApiLink { - private OpenApiLink _target; + internal OpenApiLink _target; private readonly OpenApiReference _reference; private string _description; @@ -22,7 +21,7 @@ private OpenApiLink Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -43,10 +42,6 @@ public OpenApiLinkReference(string referenceId, OpenApiDocument hostDocument, st { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -55,6 +50,19 @@ public OpenApiLinkReference(string referenceId, OpenApiDocument hostDocument, st Type = ReferenceType.Link, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiLinkReference(OpenApiLink target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.Link, + }; } /// @@ -85,26 +93,30 @@ public override string Description /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, (writer, element) => element.SerializeAsV3(writer)); - } - - /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, (writer, element) => element.SerializeAsV31(writer)); - } + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); + } + } /// private void SerializeInternal(IOpenApiWriter writer, diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs index 12bb3b774..73f126b9e 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiParameterReference.cs @@ -6,7 +6,6 @@ using Json.Schema; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -14,9 +13,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Parameter Object Reference. /// - internal class OpenApiParameterReference : OpenApiParameter + public class OpenApiParameterReference : OpenApiParameter { - private OpenApiParameter _target; + internal OpenApiParameter _target; private readonly OpenApiReference _reference; private string _description; private bool? _explode; @@ -26,7 +25,7 @@ private OpenApiParameter Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -47,10 +46,6 @@ public OpenApiParameterReference(string referenceId, OpenApiDocument hostDocumen { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -59,6 +54,19 @@ public OpenApiParameterReference(string referenceId, OpenApiDocument hostDocumen Type = ReferenceType.Parameter, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiParameterReference(OpenApiParameter target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.Parameter, + }; } /// @@ -118,34 +126,50 @@ public override bool Explode /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, - (writer, element) => element.SerializeAsV3(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); + } } /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) + public override void SerializeAsV2(IOpenApiWriter writer) { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, - (writer, element) => element.SerializeAsV31(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV2(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV2WithoutReference(writer)); + } } /// private void SerializeInternal(IOpenApiWriter writer, Action action) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); action(writer, Target); } } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs index a4270f8e4..ffd241118 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiPathItemReference.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -12,9 +11,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Path Item Object Reference: to describe the operations available on a single path. /// - internal class OpenApiPathItemReference : OpenApiPathItem + public class OpenApiPathItemReference : OpenApiPathItem { - private OpenApiPathItem _target; + internal OpenApiPathItem _target; private readonly OpenApiReference _reference; private string _description; private string _summary; @@ -23,7 +22,7 @@ private OpenApiPathItem Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -44,10 +43,6 @@ public OpenApiPathItemReference(string referenceId, OpenApiDocument hostDocument { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -56,6 +51,19 @@ public OpenApiPathItemReference(string referenceId, OpenApiDocument hostDocument Type = ReferenceType.PathItem, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiPathItemReference(OpenApiPathItem target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.PathItem, + }; } /// @@ -83,30 +91,20 @@ public override string Description /// public override IDictionary Extensions { get => Target.Extensions; set => Target.Extensions = value; } - - /// - public override void SerializeAsV3(IOpenApiWriter writer) - { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); - } - + /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, (writer, element) => element.SerializeAsV3(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); + } } - - /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, (writer, element) => element.SerializeAsV31(writer)); - } /// private void SerializeInternal(IOpenApiWriter writer, diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs index 57f7d9350..4dec5c246 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiRequestBodyReference.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -12,9 +11,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Request Body Object Reference. /// - internal class OpenApiRequestBodyReference : OpenApiRequestBody + public class OpenApiRequestBodyReference : OpenApiRequestBody { - private OpenApiRequestBody _target; + internal OpenApiRequestBody _target; private readonly OpenApiReference _reference; private string _description; @@ -22,7 +21,7 @@ private OpenApiRequestBody Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -43,10 +42,6 @@ public OpenApiRequestBodyReference(string referenceId, OpenApiDocument hostDocum { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -55,6 +50,19 @@ public OpenApiRequestBodyReference(string referenceId, OpenApiDocument hostDocum Type = ReferenceType.RequestBody, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiRequestBodyReference(OpenApiRequestBody target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.RequestBody, + }; } /// @@ -76,34 +84,36 @@ public override string Description /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, - (writer, element) => element.SerializeAsV3(writer)); - } - - /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, - (writer, element) => element.SerializeAsV31(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); + } } /// private void SerializeInternal(IOpenApiWriter writer, Action action) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); action(writer, Target); } } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs index 13a399662..538b7d05d 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiResponseReference.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -12,9 +11,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Response Object Reference. /// - internal class OpenApiResponseReference : OpenApiResponse + public class OpenApiResponseReference : OpenApiResponse { - private OpenApiResponse _target; + internal OpenApiResponse _target; private readonly OpenApiReference _reference; private string _description; @@ -22,7 +21,7 @@ private OpenApiResponse Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument?.ResolveReferenceTo(_reference); return _target; } } @@ -43,10 +42,6 @@ public OpenApiResponseReference(string referenceId, OpenApiDocument hostDocument { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -55,6 +50,21 @@ public OpenApiResponseReference(string referenceId, OpenApiDocument hostDocument Type = ReferenceType.Response, ExternalResource = externalResource }; + + Reference = _reference; + } + + internal OpenApiResponseReference(string referenceId, OpenApiResponse target) + { + _target ??= target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.Response, + }; + + Reference = _reference; } /// @@ -65,7 +75,7 @@ public override string Description } /// - public override IDictionary Content { get => Target.Content; set => Target.Content = value; } + public override IDictionary Content { get => Target?.Content; set => Target.Content = value; } /// public override IDictionary Headers { get => Target.Headers; set => Target.Headers = value; } @@ -79,34 +89,50 @@ public override string Description /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV3WithoutReference(writer)); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, - (writer, element) => element.SerializeAsV3(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV31WithoutReference(writer)); + } } /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) + public override void SerializeAsV2(IOpenApiWriter writer) { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, - (writer, element) => element.SerializeAsV31(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV2(writer); + return; + } + else + { + SerializeInternal(writer, (writer, element) => element.SerializeAsV2WithoutReference(writer)); + } } /// private void SerializeInternal(IOpenApiWriter writer, Action action) { - Utils.CheckArgumentNull(writer);; + Utils.CheckArgumentNull(writer); action(writer, this); } } diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs index 447b39486..21473f9ff 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiSecuritySchemeReference.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -12,9 +11,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Security Scheme Object Reference. /// - internal class OpenApiSecuritySchemeReference : OpenApiSecurityScheme + public class OpenApiSecuritySchemeReference : OpenApiSecurityScheme { - private OpenApiSecurityScheme _target; + internal OpenApiSecurityScheme _target; private readonly OpenApiReference _reference; private string _description; @@ -22,7 +21,7 @@ private OpenApiSecurityScheme Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument.ResolveReferenceTo(_reference); return _target; } } @@ -32,22 +31,33 @@ private OpenApiSecurityScheme Target /// /// The reference Id. /// The host OpenAPI document. - public OpenApiSecuritySchemeReference(string referenceId, OpenApiDocument hostDocument) + /// The externally referenced file. + public OpenApiSecuritySchemeReference(string referenceId, OpenApiDocument hostDocument, string externalResource = null) { if (string.IsNullOrEmpty(referenceId)) { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { Id = referenceId, HostDocument = hostDocument, - Type = ReferenceType.SecurityScheme + Type = ReferenceType.SecurityScheme, + ExternalResource = externalResource + }; + + Reference = _reference; + } + + internal OpenApiSecuritySchemeReference(string referenceId, OpenApiSecurityScheme target) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.SecurityScheme, }; } @@ -85,28 +95,44 @@ public override string Description /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer, SerializeAsV3WithoutReference); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer, SerializeAsV3WithoutReference); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer, SerializeAsV31WithoutReference); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer, SerializeAsV31WithoutReference); + } } /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) + public override void SerializeAsV2(IOpenApiWriter writer) { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, - (writer, element) => element.SerializeAsV3(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV2(writer); + return; + } + else + { + SerializeInternal(writer, SerializeAsV2WithoutReference); + } } - - /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, - (writer, element) => element.SerializeAsV31(writer)); - } /// private void SerializeInternal(IOpenApiWriter writer, diff --git a/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs b/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs index 2ce97cab1..0d9017de6 100644 --- a/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs +++ b/src/Microsoft.OpenApi/Models/References/OpenApiTagReference.cs @@ -1,10 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -using System; using System.Collections.Generic; using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Properties; using Microsoft.OpenApi.Writers; namespace Microsoft.OpenApi.Models.References @@ -12,9 +10,9 @@ namespace Microsoft.OpenApi.Models.References /// /// Tag Object Reference /// - internal class OpenApiTagReference : OpenApiTag + public class OpenApiTagReference : OpenApiTag { - private OpenApiTag _target; + internal OpenApiTag _target; private readonly OpenApiReference _reference; private string _description; @@ -22,7 +20,8 @@ private OpenApiTag Target { get { - _target ??= _reference.HostDocument.ResolveReferenceTo(_reference); + _target ??= Reference.HostDocument?.ResolveReferenceTo(_reference); + _target ??= new OpenApiTag() { Name = _reference.Id }; return _target; } } @@ -38,10 +37,6 @@ public OpenApiTagReference(string referenceId, OpenApiDocument hostDocument) { Utils.CheckArgumentNullOrEmpty(referenceId); } - if (hostDocument == null) - { - Utils.CheckArgumentNull(hostDocument); - } _reference = new OpenApiReference() { @@ -49,12 +44,25 @@ public OpenApiTagReference(string referenceId, OpenApiDocument hostDocument) HostDocument = hostDocument, Type = ReferenceType.Tag }; + + Reference = _reference; + } + + internal OpenApiTagReference(OpenApiTag target, string referenceId) + { + _target = target; + + _reference = new OpenApiReference() + { + Id = referenceId, + Type = ReferenceType.Tag, + }; } /// public override string Description { - get => string.IsNullOrEmpty(_description) ? Target.Description : _description; + get => string.IsNullOrEmpty(_description) ? Target?.Description : _description; set => _description = value; } @@ -70,27 +78,43 @@ public override string Description /// public override void SerializeAsV3(IOpenApiWriter writer) { - SerializeInternal(writer); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV3(writer); + return; + } + else + { + SerializeInternal(writer); + } } /// public override void SerializeAsV31(IOpenApiWriter writer) { - SerializeInternal(writer); - } - - /// - public override void SerializeAsV3WithoutReference(IOpenApiWriter writer) - { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_0, - (writer, element) => element.SerializeAsV3(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV31(writer); + return; + } + else + { + SerializeInternal(writer); + } } /// - public override void SerializeAsV31WithoutReference(IOpenApiWriter writer) + public override void SerializeAsV2(IOpenApiWriter writer) { - SerializeInternalWithoutReference(writer, OpenApiSpecVersion.OpenApi3_1, - (writer, element) => element.SerializeAsV31(writer)); + if (!writer.GetSettings().ShouldInlineReference(_reference)) + { + _reference.SerializeAsV2(writer); + return; + } + else + { + SerializeInternal(writer); + } } /// diff --git a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs index 4673c7df2..bbf928441 100644 --- a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs +++ b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. -using System; using System.IO; using System.Text.Json.Nodes; using System.Text.Json; @@ -12,7 +11,6 @@ using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Validations; using System.Linq; -using System.Collections.Generic; using Microsoft.OpenApi.Services; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Reader.Services; @@ -95,7 +93,7 @@ public async Task ReadAsync(JsonNode jsonNode, } } - ResolveReferences(diagnostic, document, settings); + SetHostDocument(document); } catch (OpenApiException ex) { @@ -189,28 +187,6 @@ private JsonNode LoadJsonNodes(TextReader input) return nodes; } - private void ResolveReferences(OpenApiDiagnostic diagnostic, OpenApiDocument document, OpenApiReaderSettings settings) - { - List errors = new(); - - // Resolve References if requested - switch (settings.ReferenceResolution) - { - case ReferenceResolutionSetting.ResolveAllReferences: - throw new ArgumentException("Resolving external references is not supported"); - case ReferenceResolutionSetting.ResolveLocalReferences: - errors.AddRange(document.ResolveReferences()); - break; - case ReferenceResolutionSetting.DoNotResolveReferences: - break; - } - - foreach (var item in errors) - { - diagnostic.Errors.Add(item); - } - } - private async Task LoadExternalRefs(OpenApiDocument document, CancellationToken cancellationToken, OpenApiReaderSettings settings, string format = null) { // Create workspace for all documents to live in. @@ -221,5 +197,10 @@ private async Task LoadExternalRefs(OpenApiDocument document, var workspaceLoader = new OpenApiWorkspaceLoader(openApiWorkSpace, settings.CustomExternalLoader ?? streamLoader, settings); return await workspaceLoader.LoadAsync(new OpenApiReference() { ExternalResource = "/" }, document, format ?? OpenApiConstants.Json, null, cancellationToken); } + + private void SetHostDocument(OpenApiDocument document) + { + document.SetHostDocument(); + } } } diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs index ae98b851a..e5646a359 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/ListNode.cs @@ -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; @@ -8,6 +8,7 @@ using System.Text.Json.Nodes; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Exceptions; +using Microsoft.OpenApi.Models; namespace Microsoft.OpenApi.Reader.ParseNodes { @@ -21,14 +22,14 @@ public ListNode(ParsingContext context, JsonArray jsonArray) : base( _nodeList = jsonArray; } - public override List CreateList(Func map) + public override List CreateList(Func map) { if (_nodeList == null) { throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}", _nodeList); } - return _nodeList?.Select(n => map(new MapNode(Context, n as JsonObject))) + return _nodeList?.Select(n => map(new MapNode(Context, n as JsonObject), null)) .Where(i => i != null) .ToList(); } @@ -43,14 +44,14 @@ public override List CreateListOfAny() return list; } - public override List CreateSimpleList(Func map) + public override List CreateSimpleList(Func map) { if (_nodeList == null) { throw new OpenApiReaderException($"Expected list while parsing {typeof(T).Name}", _nodeList); } - return _nodeList.Select(n => map(new(Context, n))).ToList(); + return _nodeList.Select(n => map(new(Context, n), null)).ToList(); } public IEnumerator GetEnumerator() diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs index 1420e756b..620f648a3 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/MapNode.cs @@ -49,7 +49,7 @@ public PropertyNode this[string key] } } - public override Dictionary CreateMap(Func map) + public override Dictionary CreateMap(Func map) { var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", Context); var nodes = jsonMap.Select( @@ -62,11 +62,11 @@ public override Dictionary CreateMap(Func map) { Context.StartObject(key); value = n.Value is JsonObject jsonObject - ? map(new MapNode(Context, jsonObject)) + ? map(new MapNode(Context, jsonObject), null) : default; } finally - { + { Context.EndObject(); } return new @@ -79,50 +79,9 @@ public override Dictionary CreateMap(Func map) return nodes.ToDictionary(k => k.key, v => v.value); } - public override Dictionary CreateMapWithReference( - ReferenceType referenceType, - Func map) - { - var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(T).Name}", Context); - - var nodes = jsonMap.Select( - n => - { - var key = n.Key; - (string key, T value) entry; - try - { - Context.StartObject(key); - entry = (key, - value: map(new MapNode(Context, (JsonObject)n.Value)) - ); - if (entry.value == null) - { - return default; // Body Parameters shouldn't be converted to Parameters - } - // If the component isn't a reference to another component, then point it to itself. - if (entry.value.Reference == null) - { - entry.value.Reference = new() - { - Type = referenceType, - Id = entry.key - }; - } - } - finally - { - Context.EndObject(); - } - return entry; - } - ); - return nodes.Where(n => n != default).ToDictionary(k => k.key, v => v.value); - } - public override Dictionary CreateJsonSchemaMapWithReference( ReferenceType referenceType, - Func map, + Func map, OpenApiSpecVersion version) { var jsonMap = _node ?? throw new OpenApiReaderException($"Expected map while parsing {typeof(JsonSchema).Name}", Context); @@ -136,7 +95,7 @@ public override Dictionary CreateJsonSchemaMapWithReference( { Context.StartObject(key); entry = (key, - value: map(new MapNode(Context, (JsonObject)n.Value)) + value: map(new MapNode(Context, (JsonObject)n.Value), null) ); if (entry.value == null) { diff --git a/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs b/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs index 48073b5e1..a28989227 100644 --- a/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs +++ b/src/Microsoft.OpenApi/Reader/ParseNodes/ParseNode.cs @@ -49,33 +49,25 @@ public static ParseNode Create(ParsingContext context, JsonNode node) return new ValueNode(context, node as JsonValue); } - public virtual List CreateList(Func map) + public virtual List CreateList(Func map) { throw new OpenApiReaderException("Cannot create list from this type of node.", Context); } - public virtual Dictionary CreateMap(Func map) + public virtual Dictionary CreateMap(Func map) { throw new OpenApiReaderException("Cannot create map from this type of node.", Context); } - public virtual Dictionary CreateMapWithReference( - ReferenceType referenceType, - Func map) - where T : class, IOpenApiReferenceable - { - throw new OpenApiReaderException("Cannot create map from this reference.", Context); - } - public virtual Dictionary CreateJsonSchemaMapWithReference( ReferenceType referenceType, - Func map, + Func map, OpenApiSpecVersion version) { throw new OpenApiReaderException("Cannot create map from this reference.", Context); } - public virtual List CreateSimpleList(Func map) + public virtual List CreateSimpleList(Func map) { throw new OpenApiReaderException("Cannot create simple list from this type of node.", Context); } diff --git a/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs b/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs index d6389d2fb..d80ffd714 100644 --- a/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs +++ b/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using System.Threading.Tasks; using Microsoft.OpenApi.Interfaces; diff --git a/src/Microsoft.OpenApi/Reader/V2/JsonSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/JsonSchemaDeserializer.cs index 359f7673a..17309527c 100644 --- a/src/Microsoft.OpenApi/Reader/V2/JsonSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/JsonSchemaDeserializer.cs @@ -108,7 +108,7 @@ internal static partial class OpenApiV2Deserializer { "required", (o, n) => { - o.Required(new HashSet(n.CreateSimpleList(n2 => n2.GetScalarValue()))); + o.Required(new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue()))); } }, { @@ -122,7 +122,7 @@ internal static partial class OpenApiV2Deserializer { if(n is ListNode) { - o.Type(n.CreateSimpleList(s => SchemaTypeConverter.ConvertToSchemaValueType(s.GetScalarValue()))); + o.Type(n.CreateSimpleList((s, p) => SchemaTypeConverter.ConvertToSchemaValueType(s.GetScalarValue()))); } else { @@ -225,7 +225,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.Extensions(LoadExtensions(p, LoadExtension(p, n)))} }; - public static JsonSchema LoadSchema(ParseNode node) + public static JsonSchema LoadSchema(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode(OpenApiConstants.Schema); var schemaBuilder = new JsonSchemaBuilder(); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs index a42a5bbda..2d92ca97d 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiContactDeserializer.cs @@ -35,7 +35,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiContact LoadContact(ParseNode node) + public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node as MapNode; var contact = new OpenApiContact(); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs index fd91d0a8b..477f05f0d 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs @@ -32,13 +32,13 @@ internal static partial class OpenApiV2Deserializer "schemes", (_, n) => n.Context.SetTempStorage( "schemes", n.CreateSimpleList( - s => s.GetScalarValue())) + (s, p) => s.GetScalarValue())) }, { "consumes", (_, n) => { - var consumes = n.CreateSimpleList(s => s.GetScalarValue()); + var consumes = n.CreateSimpleList((s, p) => s.GetScalarValue()); if (consumes.Count > 0) { n.Context.SetTempStorage(TempStorageKeys.GlobalConsumes, consumes); @@ -47,7 +47,7 @@ internal static partial class OpenApiV2Deserializer }, { "produces", (_, n) => { - var produces = n.CreateSimpleList(s => s.GetScalarValue()); + var produces = n.CreateSimpleList((s, p) => s.GetScalarValue()); if (produces.Count > 0) { n.Context.SetTempStorage(TempStorageKeys.GlobalProduces, produces); @@ -72,19 +72,12 @@ internal static partial class OpenApiV2Deserializer o.Components = new(); } - o.Components.Parameters = n.CreateMapWithReference( - ReferenceType.Parameter, - LoadParameter); + o.Components.Parameters = n.CreateMap(LoadParameter); - o.Components.RequestBodies = n.CreateMapWithReference(ReferenceType.RequestBody, p => + o.Components.RequestBodies = n.CreateMap((p, d) => { - var parameter = LoadParameter(p, loadRequestBody: true); - if (parameter != null) - { - return CreateRequestBody(n.Context, parameter); - } - - return null; + var parameter = LoadParameter(node: p, loadRequestBody: true, hostDocument: d); + return parameter != null ? CreateRequestBody(p.Context, parameter) : null; } ); } @@ -97,9 +90,7 @@ internal static partial class OpenApiV2Deserializer o.Components = new(); } - o.Components.Responses = n.CreateMapWithReference( - ReferenceType.Response, - LoadResponse); + o.Components.Responses = n.CreateMap(LoadResponse); } }, { @@ -110,10 +101,7 @@ internal static partial class OpenApiV2Deserializer o.Components = new(); } - o.Components.SecuritySchemes = n.CreateMapWithReference( - ReferenceType.SecurityScheme, - LoadSecurityScheme - ); + o.Components.SecuritySchemes = n.CreateMap(LoadSecurityScheme); } }, {"security", (o, n) => o.SecurityRequirements = n.CreateList(LoadSecurityRequirement)}, diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs index 82f04650e..6a68640a6 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiExternalDocsDeserializer.cs @@ -33,7 +33,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiExternalDocs LoadExternalDocs(ParseNode node) + public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("externalDocs"); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs index 3a804905d..3f36a262c 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiHeaderDeserializer.cs @@ -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; @@ -137,7 +137,7 @@ private static JsonSchemaBuilder GetOrCreateHeaderSchemaBuilder() return _headerJsonSchemaBuilder; } - public static OpenApiHeader LoadHeader(ParseNode node) + public static OpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("header"); var header = new OpenApiHeader(); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs index 2622f862b..824aab028 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiInfoDeserializer.cs @@ -47,7 +47,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiInfo LoadInfo(ParseNode node) + public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Info"); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs index f646da522..46062dcef 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiLicenseDeserializer.cs @@ -31,7 +31,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiLicense LoadLicense(ParseNode node) + public static OpenApiLicense LoadLicense(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("OpenApiLicense"); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs index 9940888bb..ad6033a14 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiOperationDeserializer.cs @@ -8,6 +8,7 @@ using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; +using Microsoft.OpenApi.Models.References; namespace Microsoft.OpenApi.Reader.V2 { @@ -22,10 +23,10 @@ internal static partial class OpenApiV2Deserializer { { "tags", (o, n) => o.Tags = n.CreateSimpleList( - valueNode => + (valueNode, doc) => LoadTagByReference( valueNode.Context, - valueNode.GetScalarValue())) + valueNode.GetScalarValue(), doc)) }, { "summary", @@ -49,7 +50,7 @@ internal static partial class OpenApiV2Deserializer }, { "consumes", (_, n) => { - var consumes = n.CreateSimpleList(s => s.GetScalarValue()); + var consumes = n.CreateSimpleList((s, p) => s.GetScalarValue()); if (consumes.Count > 0) { n.Context.SetTempStorage(TempStorageKeys.OperationConsumes,consumes); } @@ -57,7 +58,7 @@ internal static partial class OpenApiV2Deserializer }, { "produces", (_, n) => { - var produces = n.CreateSimpleList(s => s.GetScalarValue()); + var produces = n.CreateSimpleList((s, p) => s.GetScalarValue()); if (produces.Count > 0) { n.Context.SetTempStorage(TempStorageKeys.OperationProduces, produces); } @@ -92,7 +93,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - internal static OpenApiOperation LoadOperation(ParseNode node) + internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument hostDocument = null) { // Reset these temp storage parameters for each operation. node.Context.SetTempStorage(TempStorageKeys.BodyParameter, null); @@ -132,7 +133,7 @@ internal static OpenApiOperation LoadOperation(ParseNode node) return operation; } - public static OpenApiResponses LoadResponses(ParseNode node) + public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Responses"); @@ -209,15 +210,9 @@ internal static OpenApiRequestBody CreateRequestBody( private static OpenApiTag LoadTagByReference( ParsingContext context, - string tagName) + string tagName, OpenApiDocument hostDocument = null) { - var tagObject = new OpenApiTag - { - UnresolvedReference = true, - Reference = new() { Id = tagName, Type = ReferenceType.Tag } - }; - - return tagObject; + return new OpenApiTagReference(tagName, hostDocument); } } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs index 26a95c373..07634ddd4 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiParameterDeserializer.cs @@ -9,6 +9,7 @@ using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V2 @@ -195,12 +196,12 @@ private static void ProcessIn(OpenApiParameter o, ParseNode n) } } - public static OpenApiParameter LoadParameter(ParseNode node) + public static OpenApiParameter LoadParameter(ParseNode node, OpenApiDocument hostDocument = null) { - return LoadParameter(node, false); + return LoadParameter(node, false, hostDocument); } - public static OpenApiParameter LoadParameter(ParseNode node, bool loadRequestBody) + public static OpenApiParameter LoadParameter(ParseNode node, bool loadRequestBody, OpenApiDocument hostDocument) { // Reset the local variables every time this method is called. node.Context.SetTempStorage(TempStorageKeys.ParameterIsBodyOrFormData, false); @@ -211,7 +212,8 @@ public static OpenApiParameter LoadParameter(ParseNode node, bool loadRequestBod if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Parameter, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiParameterReference(reference.Item1, hostDocument, reference.Item2); } var parameter = new OpenApiParameter(); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs index c597e9eee..574ce8619 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathItemDeserializer.cs @@ -43,7 +43,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))}, }; - public static OpenApiPathItem LoadPathItem(ParseNode node) + public static OpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("PathItem"); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs index d97052129..6d23aef0b 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiPathsDeserializer.cs @@ -21,7 +21,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiPaths LoadPaths(ParseNode node) + public static OpenApiPaths LoadPaths(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Paths"); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs index 59e719756..8078f7ff6 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiResponseDeserializer.cs @@ -1,10 +1,11 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System.Collections.Generic; using Json.Schema; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V2 @@ -131,14 +132,15 @@ private static void LoadExample(OpenApiResponse response, string mediaType, Pars mediaTypeObject.Example = exampleNode; } - public static OpenApiResponse LoadResponse(ParseNode node) + public static OpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("response"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Response, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiResponseReference(reference.Item1, hostDocument, reference.Item2); } var response = new OpenApiResponse(); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs index 0938fe6fd..5e430206c 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecurityRequirementDeserializer.cs @@ -12,7 +12,7 @@ namespace Microsoft.OpenApi.Reader.V2 /// internal static partial class OpenApiV2Deserializer { - public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) + public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("security"); @@ -24,7 +24,7 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) mapNode.Context, property.Name); - var scopes = property.Value.CreateSimpleList(n2 => n2.GetScalarValue()); + var scopes = property.Value.CreateSimpleList((n2, p) => n2.GetScalarValue()); if (scheme != null) { diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs index c1da81fd2..9223ecc3f 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiSecuritySchemeDeserializer.cs @@ -68,7 +68,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node) + public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiDocument hostDocument = null) { // Reset the local variables every time this method is called. // TODO: Change _flow to a tempStorage variable to make the deserializer thread-safe. diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs index d1857eef6..2eccdb929 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiTagDeserializer.cs @@ -34,7 +34,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiTag LoadTag(ParseNode n) + public static OpenApiTag LoadTag(ParseNode n, OpenApiDocument hostDocument = null) { var mapNode = n.CheckMapNode("tag"); diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs index 39a4a87cb..34dac28ea 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2Deserializer.cs @@ -71,7 +71,7 @@ private static void ProcessAnyFields( } } - public static OpenApiAny LoadAny(ParseNode node) + public static OpenApiAny LoadAny(ParseNode node, OpenApiDocument hostDocument = null) { return node.CreateAny(); } @@ -92,5 +92,16 @@ private static string LoadString(ParseNode node) { return node.GetScalarValue(); } + + private static (string, string) GetReferenceIdAndExternalResource(string pointer) + { + var refSegments = pointer.Split('/'); + var refId = refSegments.Last(); + var isExternalResource = !refSegments.First().StartsWith("#"); + + string externalResource = isExternalResource ? $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}" : null; + + return (refId, externalResource); + } } } diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs index 1be363b21..ea5e66f0a 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiV2VersionService.cs @@ -30,7 +30,7 @@ public OpenApiV2VersionService(OpenApiDiagnostic diagnostic) Diagnostic = diagnostic; } - private Dictionary> _loaders = new() + private readonly Dictionary> _loaders = new() { [typeof(OpenApiAny)] = OpenApiV2Deserializer.LoadAny, [typeof(OpenApiContact)] = OpenApiV2Deserializer.LoadContact, @@ -215,9 +215,9 @@ public OpenApiDocument LoadDocument(RootNode rootNode) return OpenApiV2Deserializer.LoadOpenApi(rootNode); } - public T LoadElement(ParseNode node) where T : IOpenApiElement + public T LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement { - return (T)_loaders[typeof(T)](node); + return (T)_loaders[typeof(T)](node, doc); } /// diff --git a/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs index 72375b74b..9e0728e87 100644 --- a/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V2/OpenApiXmlDeserializer.cs @@ -54,7 +54,7 @@ internal static partial class OpenApiV2Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiXml LoadXml(ParseNode node) + public static OpenApiXml LoadXml(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("xml"); diff --git a/src/Microsoft.OpenApi/Reader/V3/JsonSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/JsonSchemaDeserializer.cs index 5d4c5b67f..90c1f5984 100644 --- a/src/Microsoft.OpenApi/Reader/V3/JsonSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/JsonSchemaDeserializer.cs @@ -109,7 +109,7 @@ internal static partial class OpenApiV3Deserializer { "required", (o, n) => { - o.Required(new HashSet(n.CreateSimpleList(n2 => n2.GetScalarValue()))); + o.Required(new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue()))); } }, { @@ -123,7 +123,7 @@ internal static partial class OpenApiV3Deserializer { if(n is ListNode) { - o.Type(n.CreateSimpleList(s => SchemaTypeConverter.ConvertToSchemaValueType(s.GetScalarValue()))); + o.Type(n.CreateSimpleList((s, p) => SchemaTypeConverter.ConvertToSchemaValueType(s.GetScalarValue()))); } else { @@ -244,7 +244,7 @@ internal static partial class OpenApiV3Deserializer { if(n is ListNode) { - o.Examples(n.CreateSimpleList(s => (JsonNode)s.GetScalarValue())); + o.Examples(n.CreateSimpleList((s, p) => (JsonNode)s.GetScalarValue())); } else { @@ -265,7 +265,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.Extensions(LoadExtensions(p, LoadExtension(p, n)))} }; - public static JsonSchema LoadSchema(ParseNode node) + public static JsonSchema LoadSchema(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode(OpenApiConstants.Schema); var builder = new JsonSchemaBuilder(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs index 2c5905d67..fe6db9646 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiCallbackDeserializer.cs @@ -1,9 +1,11 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -23,14 +25,16 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiCallback LoadCallback(ParseNode node) + public static OpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("callback"); var pointer = mapNode.GetReferencePointer(); + if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Callback, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiCallbackReference(reference.Item1, hostDocument, reference.Item2); } var domainObject = new OpenApiCallback(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs index 1b6590adc..1474c81a1 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiComponentsDeserializer.cs @@ -21,15 +21,14 @@ internal static partial class OpenApiV3Deserializer private static readonly FixedFieldMap _componentsFixedFields = new() { {"schemas", (o, n) => o.Schemas = n.CreateJsonSchemaMapWithReference(ReferenceType.Schema, LoadSchema, OpenApiSpecVersion.OpenApi3_0)}, - {"responses", (o, n) => o.Responses = n.CreateMapWithReference(ReferenceType.Response, LoadResponse)}, - {"parameters", (o, n) => o.Parameters = n.CreateMapWithReference(ReferenceType.Parameter, LoadParameter)}, - {"examples", (o, n) => o.Examples = n.CreateMapWithReference(ReferenceType.Example, LoadExample)}, - {"requestBodies", (o, n) => o.RequestBodies = n.CreateMapWithReference(ReferenceType.RequestBody, LoadRequestBody)}, - {"headers", (o, n) => o.Headers = n.CreateMapWithReference(ReferenceType.Header, LoadHeader)}, - {"securitySchemes", (o, n) => o.SecuritySchemes = n.CreateMapWithReference(ReferenceType.SecurityScheme, LoadSecurityScheme)}, - {"links", (o, n) => o.Links = n.CreateMapWithReference(ReferenceType.Link, LoadLink)}, - {"callbacks", (o, n) => o.Callbacks = n.CreateMapWithReference(ReferenceType.Callback, LoadCallback)}, - {"pathItems", (o, n) => o.PathItems = n.CreateMapWithReference(ReferenceType.PathItem, LoadPathItem)} + {"responses", (o, n) => o.Responses = n.CreateMap(LoadResponse)}, + {"parameters", (o, n) => o.Parameters = n.CreateMap(LoadParameter)}, + {"examples", (o, n) => o.Examples = n.CreateMap(LoadExample)}, + {"requestBodies", (o, n) => o.RequestBodies = n.CreateMap(LoadRequestBody)}, + {"headers", (o, n) => o.Headers = n.CreateMap(LoadHeader)}, + {"securitySchemes", (o, n) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme)}, + {"links", (o, n) => o.Links = n.CreateMap(LoadLink)}, + {"callbacks", (o, n) => o.Callbacks = n.CreateMap(LoadCallback)} }; private static readonly PatternFieldMap _componentsPatternFields = @@ -38,7 +37,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiComponents LoadComponents(ParseNode node) + public static OpenApiComponents LoadComponents(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("components"); var components = new OpenApiComponents(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs index 42cb64877..10a9893f7 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiContactDeserializer.cs @@ -35,7 +35,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiContact LoadContact(ParseNode node) + public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node as MapNode; var contact = new OpenApiContact(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs index 8bc56f7dc..e542534bc 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDiscriminatorDeserializer.cs @@ -27,7 +27,7 @@ internal static partial class OpenApiV3Deserializer private static readonly PatternFieldMap _discriminatorPatternFields = new(); - public static OpenApiDiscriminator LoadDiscriminator(ParseNode node) + public static OpenApiDiscriminator LoadDiscriminator(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("discriminator"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs index 232dbdaf9..55174f34e 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiDocumentDeserializer.cs @@ -13,6 +13,7 @@ namespace Microsoft.OpenApi.Reader.V3 /// internal static partial class OpenApiV3Deserializer { + private static readonly FixedFieldMap _openApiFixedFields = new() { { @@ -46,12 +47,12 @@ internal static partial class OpenApiV3Deserializer public static OpenApiDocument LoadOpenApi(RootNode rootNode) { - var openApidoc = new OpenApiDocument(); var openApiNode = rootNode.GetMap(); + var openApiDoc = new OpenApiDocument(); - ParseMap(openApiNode, openApidoc, _openApiFixedFields, _openApiPatternFields); + ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields); - return openApidoc; + return openApiDoc; } } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs index 4228e339c..6ceae13e3 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiEncodingDeserializer.cs @@ -43,7 +43,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiEncoding LoadEncoding(ParseNode node) + public static OpenApiEncoding LoadEncoding(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("encoding"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs index 6a7b0305f..95d9584f3 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiExampleDeserializer.cs @@ -1,8 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -39,14 +41,15 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiExample LoadExample(ParseNode node) + public static OpenApiExample LoadExample(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("example"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Example, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiExampleReference(reference.Item1, hostDocument, reference.Item2); } var example = new OpenApiExample(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs index fc5b83e18..a4e52c35e 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiExternalDocsDeserializer.cs @@ -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; @@ -34,7 +34,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiExternalDocs LoadExternalDocs(ParseNode node) + public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("externalDocs"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs index 809226b4a..d83f791f9 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiHeaderDeserializer.cs @@ -1,8 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -62,14 +64,15 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiHeader LoadHeader(ParseNode node) + public static OpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("header"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Header, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiHeaderReference(reference.Item1, hostDocument, reference.Item2); } var header = new OpenApiHeader(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs index 9573d69c0..fe44291f8 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiInfoDeserializer.cs @@ -47,7 +47,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, k, n) => o.AddExtension(k,LoadExtension(k, n))} }; - public static OpenApiInfo LoadInfo(ParseNode node) + public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Info"); var info = new OpenApiInfo(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs index 380c8b8fa..ab48c2b9e 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiLicenseDeserializer.cs @@ -31,7 +31,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - internal static OpenApiLicense LoadLicense(ParseNode node) + internal static OpenApiLicense LoadLicense(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("License"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs index 3f3694339..02c696de4 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiLinkDeserializer.cs @@ -1,8 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -43,7 +45,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiLink LoadLink(ParseNode node) + public static OpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("link"); var link = new OpenApiLink(); @@ -51,7 +53,8 @@ public static OpenApiLink LoadLink(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Link, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiLinkReference(reference.Item1, hostDocument, reference.Item2); } ParseMap(mapNode, link, _linkFixedFields, _linkPatternFields); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs index bd0f8ac56..8e19f753b 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiMediaTypeDeserializer.cs @@ -64,7 +64,7 @@ internal static partial class OpenApiV3Deserializer } }; - public static OpenApiMediaType LoadMediaType(ParseNode node) + public static OpenApiMediaType LoadMediaType(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode(OpenApiConstants.Content); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs index 9d0c115f3..be6615e39 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowDeserializer.cs @@ -38,7 +38,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node) + public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("OAuthFlow"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs index 92e49b770..74bdc56df 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOAuthFlowsDeserializer.cs @@ -28,7 +28,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiOAuthFlows LoadOAuthFlows(ParseNode node) + public static OpenApiOAuthFlows LoadOAuthFlows(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("OAuthFlows"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs index dd1626df7..3d3933bba 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiOperationDeserializer.cs @@ -1,8 +1,9 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -18,10 +19,10 @@ internal static partial class OpenApiV3Deserializer { { "tags", (o, n) => o.Tags = n.CreateSimpleList( - valueNode => + (valueNode, doc) => LoadTagByReference( valueNode.Context, - valueNode.GetScalarValue())) + valueNode.GetScalarValue(), doc)) }, { "summary", @@ -75,7 +76,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))}, }; - internal static OpenApiOperation LoadOperation(ParseNode node) + internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Operation"); @@ -88,19 +89,9 @@ internal static OpenApiOperation LoadOperation(ParseNode node) private static OpenApiTag LoadTagByReference( ParsingContext context, - string tagName) + string tagName, OpenApiDocument hostDocument) { - var tagObject = new OpenApiTag - { - UnresolvedReference = true, - Reference = new() - { - Type = ReferenceType.Tag, - Id = tagName - } - }; - - return tagObject; + return new OpenApiTagReference(tagName, hostDocument); } } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs index fd4638273..6c8a7772b 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiParameterDeserializer.cs @@ -1,10 +1,11 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -108,14 +109,15 @@ internal static partial class OpenApiV3Deserializer } }; - public static OpenApiParameter LoadParameter(ParseNode node) + public static OpenApiParameter LoadParameter(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("parameter"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Parameter, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiParameterReference(reference.Item1, hostDocument, reference.Item2); } var parameter = new OpenApiParameter(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs index 115aedd9b..7593ae162 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathItemDeserializer.cs @@ -1,8 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -47,15 +49,15 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiPathItem LoadPathItem(ParseNode node) + public static OpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("PathItem"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - var refObject = mapNode.GetReferencedObject(ReferenceType.PathItem, pointer); - return refObject; + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiPathItemReference(reference.Item1, hostDocument, reference.Item2); } var pathItem = new OpenApiPathItem(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs index 7238c3711..92451fe39 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiPathsDeserializer.cs @@ -21,7 +21,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiPaths LoadPaths(ParseNode node) + public static OpenApiPaths LoadPaths(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Paths"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs index 2bf5f6963..c9ddfef61 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiRequestBodyDeserializer.cs @@ -1,8 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -36,14 +38,15 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiRequestBody LoadRequestBody(ParseNode node) + public static OpenApiRequestBody LoadRequestBody(ParseNode node, OpenApiDocument hostDocument= null) { var mapNode = node.CheckMapNode("requestBody"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.RequestBody, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiRequestBodyReference(reference.Item1, hostDocument, reference.Item2); } var requestBody = new OpenApiRequestBody(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs index 8362504d9..417f82dbd 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponseDeserializer.cs @@ -1,8 +1,10 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -39,14 +41,15 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiResponse LoadResponse(ParseNode node) + public static OpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("response"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.Response, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiResponseReference(reference.Item1, hostDocument, reference.Item2); } var response = new OpenApiResponse(); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs index b317f4d4a..e9c0d54f3 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiResponsesDeserializer.cs @@ -21,7 +21,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiResponses LoadResponses(ParseNode node) + public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Responses"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs index 837f98f8d..e1d4ddc2f 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecurityRequirementDeserializer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -12,7 +13,7 @@ namespace Microsoft.OpenApi.Reader.V3 /// internal static partial class OpenApiV3Deserializer { - public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) + public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("security"); @@ -22,7 +23,7 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) { var scheme = LoadSecuritySchemeByReference(mapNode.Context, property.Name); - var scopes = property.Value.CreateSimpleList(value => value.GetScalarValue()); + var scopes = property.Value.CreateSimpleList((value, p) => value.GetScalarValue()); if (scheme != null) { @@ -42,16 +43,7 @@ private static OpenApiSecurityScheme LoadSecuritySchemeByReference( ParsingContext context, string schemeName) { - var securitySchemeObject = new OpenApiSecurityScheme - { - UnresolvedReference = true, - Reference = new() - { - Id = schemeName, - Type = ReferenceType.SecurityScheme - } - }; - + var securitySchemeObject = new OpenApiSecuritySchemeReference(schemeName, hostDocument: null); return securitySchemeObject; } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs index a40f25680..1ae954e5f 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiSecuritySchemeDeserializer.cs @@ -1,9 +1,11 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V3 @@ -57,14 +59,16 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node) + public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("securityScheme"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - return mapNode.GetReferencedObject(ReferenceType.SecurityScheme, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiSecuritySchemeReference(reference.Item1, hostDocument, reference.Item2); } + var securityScheme = new OpenApiSecurityScheme(); foreach (var property in mapNode) { diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs index c58815f3a..80f7dbf49 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerDeserializer.cs @@ -34,7 +34,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiServer LoadServer(ParseNode node) + public static OpenApiServer LoadServer(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("server"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs index b5de9dd49..7ba5e79cd 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiServerVariableDeserializer.cs @@ -18,7 +18,7 @@ internal static partial class OpenApiV3Deserializer { { "enum", - (o, n) => o.Enum = n.CreateSimpleList(s => s.GetScalarValue()) + (o, n) => o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue()) }, { "default", @@ -36,7 +36,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiServerVariable LoadServerVariable(ParseNode node) + public static OpenApiServerVariable LoadServerVariable(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("serverVariable"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs index ff848ae27..5b56ab8ca 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiTagDeserializer.cs @@ -34,7 +34,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiTag LoadTag(ParseNode n) + public static OpenApiTag LoadTag(ParseNode n, OpenApiDocument hostDocument = null) { var mapNode = n.CheckMapNode("tag"); diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs index 6d32eaedb..24f900dcd 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3Deserializer.cs @@ -162,7 +162,7 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(Parse }; } - public static OpenApiAny LoadAny(ParseNode node) + public static OpenApiAny LoadAny(ParseNode node, OpenApiDocument hostDocument = null) { return node.CreateAny(); } @@ -183,5 +183,16 @@ private static string LoadString(ParseNode node) { return node.GetScalarValue(); } + + private static (string, string) GetReferenceIdAndExternalResource(string pointer) + { + var refSegments = pointer.Split('/'); + var refId = refSegments.Last(); + var isExternalResource = !refSegments.First().StartsWith("#"); + + string externalResource = isExternalResource ? $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}" : null; + + return (refId, externalResource); + } } } diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs index 80f0e71e4..789a6b9e5 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiV3VersionService.cs @@ -33,7 +33,7 @@ public OpenApiV3VersionService(OpenApiDiagnostic diagnostic) Diagnostic = diagnostic; } - private Dictionary> _loaders = new() + private readonly Dictionary> _loaders = new() { [typeof(OpenApiAny)] = OpenApiV3Deserializer.LoadAny, [typeof(OpenApiCallback)] = OpenApiV3Deserializer.LoadCallback, @@ -172,9 +172,9 @@ public OpenApiDocument LoadDocument(RootNode rootNode) return OpenApiV3Deserializer.LoadOpenApi(rootNode); } - public T LoadElement(ParseNode node) where T : IOpenApiElement + public T LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement { - return (T)_loaders[typeof(T)](node); + return (T)_loaders[typeof(T)](node, doc); } /// diff --git a/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs index 91f172707..e72753b68 100644 --- a/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V3/OpenApiXmlDeserializer.cs @@ -44,7 +44,7 @@ internal static partial class OpenApiV3Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiXml LoadXml(ParseNode node) + public static OpenApiXml LoadXml(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("xml"); diff --git a/src/Microsoft.OpenApi/Reader/V31/JsonSchemaDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/JsonSchemaDeserializer.cs index ca78ad9b6..df705a7c9 100644 --- a/src/Microsoft.OpenApi/Reader/V31/JsonSchemaDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/JsonSchemaDeserializer.cs @@ -109,7 +109,7 @@ internal static partial class OpenApiV31Deserializer { "required", (o, n) => { - o.Required(new HashSet(n.CreateSimpleList(n2 => n2.GetScalarValue()))); + o.Required(new HashSet(n.CreateSimpleList((n2, p) => n2.GetScalarValue()))); } }, { @@ -123,7 +123,7 @@ internal static partial class OpenApiV31Deserializer { if(n is ListNode) { - o.Type(n.CreateSimpleList(s => SchemaTypeConverter.ConvertToSchemaValueType(s.GetScalarValue()))); + o.Type(n.CreateSimpleList((s, p) => SchemaTypeConverter.ConvertToSchemaValueType(s.GetScalarValue()))); } else { @@ -248,7 +248,7 @@ internal static partial class OpenApiV31Deserializer { "examples", (o, n) => { - o.Examples(n.CreateSimpleList(s => (JsonNode)s.GetScalarValue())); + o.Examples(n.CreateSimpleList((s, p) =>(JsonNode) s.GetScalarValue())); } }, { @@ -264,7 +264,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.Extensions(LoadExtensions(p, LoadExtension(p, n)))} }; - public static JsonSchema LoadSchema(ParseNode node) + public static JsonSchema LoadSchema(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode(OpenApiConstants.Schema); var builder = new JsonSchemaBuilder(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs index faf89af69..4689bc837 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiCallbackDeserializer.cs @@ -1,8 +1,10 @@ -using Microsoft.OpenApi.Expressions; +using Microsoft.OpenApi.Expressions; using System; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader.ParseNodes; +using Microsoft.OpenApi.Models.References; +using System.Linq; namespace Microsoft.OpenApi.Reader.V31 { @@ -22,13 +24,14 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-", StringComparison.OrdinalIgnoreCase), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiCallback LoadCallback(ParseNode node) + public static OpenApiCallback LoadCallback(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("callback"); if (mapNode.GetReferencePointer() is {} pointer) { - return mapNode.GetReferencedObject(ReferenceType.Callback, pointer); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiCallbackReference(reference.Item1, hostDocument, reference.Item2); } var domainObject = new OpenApiCallback(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs index 904a494aa..a1a399bd2 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiComponentsDeserializer.cs @@ -18,15 +18,15 @@ internal static partial class OpenApiV31Deserializer private static readonly FixedFieldMap _componentsFixedFields = new() { {"schemas", (o, n) => o.Schemas = n.CreateMap(LoadSchema)}, - {"responses", (o, n) => o.Responses = n.CreateMapWithReference(ReferenceType.Response, LoadResponse)}, - {"parameters", (o, n) => o.Parameters = n.CreateMapWithReference(ReferenceType.Parameter, LoadParameter)}, - {"examples", (o, n) => o.Examples = n.CreateMapWithReference(ReferenceType.Example, LoadExample)}, - {"requestBodies", (o, n) => o.RequestBodies = n.CreateMapWithReference(ReferenceType.RequestBody, LoadRequestBody)}, - {"headers", (o, n) => o.Headers = n.CreateMapWithReference(ReferenceType.Header, LoadHeader)}, - {"securitySchemes", (o, n) => o.SecuritySchemes = n.CreateMapWithReference(ReferenceType.SecurityScheme, LoadSecurityScheme)}, - {"links", (o, n) => o.Links = n.CreateMapWithReference(ReferenceType.Link, LoadLink)}, - {"callbacks", (o, n) => o.Callbacks = n.CreateMapWithReference(ReferenceType.Callback, LoadCallback)}, - {"pathItems", (o, n) => o.PathItems = n.CreateMapWithReference(ReferenceType.PathItem, LoadPathItem)} + {"responses", (o, n) => o.Responses = n.CreateMap(LoadResponse)}, + {"parameters", (o, n) => o.Parameters = n.CreateMap(LoadParameter)}, + {"examples", (o, n) => o.Examples = n.CreateMap(LoadExample)}, + {"requestBodies", (o, n) => o.RequestBodies = n.CreateMap(LoadRequestBody)}, + {"headers", (o, n) => o.Headers = n.CreateMap(LoadHeader)}, + {"securitySchemes", (o, n) => o.SecuritySchemes = n.CreateMap(LoadSecurityScheme)}, + {"links", (o, n) => o.Links = n.CreateMap(LoadLink)}, + {"callbacks", (o, n) => o.Callbacks = n.CreateMap(LoadCallback)}, + {"pathItems", (o, n) => o.PathItems = n.CreateMap(LoadPathItem)} }; private static readonly PatternFieldMap _componentsPatternFields = @@ -35,7 +35,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-", StringComparison.OrdinalIgnoreCase), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiComponents LoadComponents(ParseNode node) + public static OpenApiComponents LoadComponents(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("components"); var components = new OpenApiComponents(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs index 2c1771d5a..71e673ee0 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiContactDeserializer.cs @@ -38,7 +38,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiContact LoadContact(ParseNode node) + public static OpenApiContact LoadContact(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node as MapNode; var contact = new OpenApiContact(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs index 9075b81d0..c868ab497 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiDocumentDeserializer.cs @@ -21,7 +21,7 @@ internal static partial class OpenApiV31Deserializer {"jsonSchemaDialect", (o, n) => o.JsonSchemaDialect = n.GetScalarValue() }, {"servers", (o, n) => o.Servers = n.CreateList(LoadServer)}, {"paths", (o, n) => o.Paths = LoadPaths(n)}, - {"webhooks", (o, n) => o.Webhooks = LoadPaths(n)}, + {"webhooks", (o, n) => o.Webhooks = n.CreateMap(LoadPathItem)}, {"components", (o, n) => o.Components = LoadComponents(n)}, {"tags", (o, n) => {o.Tags = n.CreateList(LoadTag); foreach (var tag in o.Tags) @@ -45,12 +45,12 @@ internal static partial class OpenApiV31Deserializer public static OpenApiDocument LoadOpenApi(RootNode rootNode) { - var openApidoc = new OpenApiDocument(); var openApiNode = rootNode.GetMap(); + var openApiDoc = new OpenApiDocument(); - ParseMap(openApiNode, openApidoc, _openApiFixedFields, _openApiPatternFields); + ParseMap(openApiNode, openApiDoc, _openApiFixedFields, _openApiPatternFields); - return openApidoc; + return openApiDoc; } } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs index 3007be502..c97057ded 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiEncodingDeserializer.cs @@ -50,7 +50,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiEncoding LoadEncoding(ParseNode node) + public static OpenApiEncoding LoadEncoding(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("encoding"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs index 7d6b89730..87b7f1e88 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiExampleDeserializer.cs @@ -1,5 +1,7 @@ -using Microsoft.OpenApi.Extensions; +using System.Linq; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -45,17 +47,15 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiExample LoadExample(ParseNode node) + public static OpenApiExample LoadExample(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("example"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); - var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); - - return mapNode.GetReferencedObject(ReferenceType.Example, pointer, summary, description); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiExampleReference(reference.Item1, hostDocument, reference.Item2); } var example = new OpenApiExample(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs index 1bed64623..825e9007d 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiExternalDocsDeserializer.cs @@ -36,7 +36,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p, n))} }; - public static OpenApiExternalDocs LoadExternalDocs(ParseNode node) + public static OpenApiExternalDocs LoadExternalDocs(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("externalDocs"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs index 64c5419ce..5d7130aa8 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiHeaderDeserializer.cs @@ -1,5 +1,7 @@ -using Microsoft.OpenApi.Extensions; +using System.Linq; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -79,17 +81,15 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiHeader LoadHeader(ParseNode node) + public static OpenApiHeader LoadHeader(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("header"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); - var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); - - return mapNode.GetReferencedObject(ReferenceType.Header, pointer, summary, description); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiHeaderReference(reference.Item1, hostDocument, reference.Item2); } var header = new OpenApiHeader(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs index 31237b40e..5b9a61029 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiInfoDeserializer.cs @@ -62,7 +62,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, k, n) => o.AddExtension(k,LoadExtension(k, n))} }; - public static OpenApiInfo LoadInfo(ParseNode node) + public static OpenApiInfo LoadInfo(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Info"); var info = new OpenApiInfo(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs index e2b50a5bd..52534f70a 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiLicenseDeserializer.cs @@ -38,7 +38,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - internal static OpenApiLicense LoadLicense(ParseNode node) + internal static OpenApiLicense LoadLicense(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("License"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs index 155e62725..05dc90ca9 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiLinkDeserializer.cs @@ -1,5 +1,7 @@ -using Microsoft.OpenApi.Extensions; +using System.Linq; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -50,7 +52,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))}, }; - public static OpenApiLink LoadLink(ParseNode node) + public static OpenApiLink LoadLink(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("link"); var link = new OpenApiLink(); @@ -58,10 +60,8 @@ public static OpenApiLink LoadLink(ParseNode node) var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); - var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); - - return mapNode.GetReferencedObject(ReferenceType.Link, pointer, summary, description); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiLinkReference(reference.Item1, hostDocument, reference.Item2); } ParseMap(mapNode, link, _linkFixedFields, _linkPatternFields); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs index 8725a1a0a..7645deead 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiMediaTypeDeserializer.cs @@ -70,7 +70,7 @@ internal static partial class OpenApiV31Deserializer } }; - public static OpenApiMediaType LoadMediaType(ParseNode node) + public static OpenApiMediaType LoadMediaType(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode(OpenApiConstants.Content); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs index f88654020..975e0272b 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowDeserializer.cs @@ -41,7 +41,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node) + public static OpenApiOAuthFlow LoadOAuthFlow(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("OAuthFlow"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs index 6cb78a9d1..6c0b16223 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiOAuthFlowsDeserializer.cs @@ -25,7 +25,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiOAuthFlows LoadOAuthFlows(ParseNode node) + public static OpenApiOAuthFlows LoadOAuthFlows(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("OAuthFlows"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs index 0130b2c4d..2143ffb65 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiOperationDeserializer.cs @@ -1,5 +1,6 @@ -using Microsoft.OpenApi.Extensions; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -15,8 +16,8 @@ internal static partial class OpenApiV31Deserializer { { "tags", (o, n) => o.Tags = n.CreateSimpleList( - valueNode => - LoadTagByReference(valueNode.GetScalarValue())) + (valueNode, doc) => + LoadTagByReference(valueNode.GetScalarValue(), doc)) }, { "summary", (o, n) => @@ -92,7 +93,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))}, }; - internal static OpenApiOperation LoadOperation(ParseNode node) + internal static OpenApiOperation LoadOperation(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Operation"); @@ -103,18 +104,9 @@ internal static OpenApiOperation LoadOperation(ParseNode node) return operation; } - private static OpenApiTag LoadTagByReference(string tagName) + private static OpenApiTag LoadTagByReference(string tagName, OpenApiDocument hostDocument = null) { - var tagObject = new OpenApiTag() - { - UnresolvedReference = true, - Reference = new OpenApiReference() - { - Type = ReferenceType.Tag, - Id = tagName - } - }; - + var tagObject = new OpenApiTagReference(tagName, hostDocument); return tagObject; } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs index b32d2f9a3..8c4c200d8 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiParameterDeserializer.cs @@ -1,7 +1,8 @@ -using System; +using System; using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -129,17 +130,15 @@ internal static partial class OpenApiV31Deserializer } }; - public static OpenApiParameter LoadParameter(ParseNode node) + public static OpenApiParameter LoadParameter(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("parameter"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); - var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); - - return mapNode.GetReferencedObject(ReferenceType.Parameter, pointer, summary, description); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiParameterReference(reference.Item1, hostDocument, reference.Item2); } var parameter = new OpenApiParameter(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs index d6c25ee52..2aadfb03e 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathItemDeserializer.cs @@ -1,5 +1,7 @@ -using Microsoft.OpenApi.Extensions; +using System.Linq; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -49,7 +51,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiPathItem LoadPathItem(ParseNode node) + public static OpenApiPathItem LoadPathItem(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("PathItem"); @@ -57,14 +59,8 @@ public static OpenApiPathItem LoadPathItem(ParseNode node) if (pointer != null) { - var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); - var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); - - return new OpenApiPathItem() - { - UnresolvedReference = true, - Reference = node.Context.VersionService.ConvertToOpenApiReference(pointer, ReferenceType.PathItem, summary, description) - }; + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiPathItemReference(reference.Item1, hostDocument, reference.Item2); } var pathItem = new OpenApiPathItem(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs index 8412e894f..640f6fc90 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiPathsDeserializer.cs @@ -18,7 +18,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiPaths LoadPaths(ParseNode node) + public static OpenApiPaths LoadPaths(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Paths"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs index de9e01c2b..22e5fedb4 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiRequestBodyDeserializer.cs @@ -1,5 +1,7 @@ -using Microsoft.OpenApi.Extensions; +using System.Linq; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -39,17 +41,15 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiRequestBody LoadRequestBody(ParseNode node) + public static OpenApiRequestBody LoadRequestBody(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("requestBody"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); - var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); - - return mapNode.GetReferencedObject(ReferenceType.RequestBody, pointer, summary, description); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiRequestBodyReference(reference.Item1, hostDocument, reference.Item2); } var requestBody = new OpenApiRequestBody(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs index e446ff89e..d1fba99be 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponseDeserializer.cs @@ -1,5 +1,7 @@ -using Microsoft.OpenApi.Extensions; +using System.Linq; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -44,18 +46,15 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiResponse LoadResponse(ParseNode node) + public static OpenApiResponse LoadResponse(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("response"); var pointer = mapNode.GetReferencePointer(); if (pointer != null) { - - var description = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Description); - var summary = node.Context.VersionService.GetReferenceScalarValues(mapNode, OpenApiConstants.Summary); - - return mapNode.GetReferencedObject(ReferenceType.Response, pointer, summary, description); + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiResponseReference(reference.Item1, hostDocument, reference.Item2); } var response = new OpenApiResponse(); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs index 9afc51455..ef1e9a3d2 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiResponsesDeserializer.cs @@ -21,7 +21,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiResponses LoadResponses(ParseNode node) + public static OpenApiResponses LoadResponses(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("Responses"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs index 8a03f880d..94753dafa 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecurityRequirementDeserializer.cs @@ -1,7 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -12,7 +13,7 @@ namespace Microsoft.OpenApi.Reader.V31 /// internal static partial class OpenApiV31Deserializer { - public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) + public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("security"); @@ -20,9 +21,9 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) foreach (var property in mapNode) { - var scheme = LoadSecuritySchemeByReference(property.Name); + var scheme = LoadSecuritySchemeByReference(property.Name, hostDocument); - var scopes = property.Value.CreateSimpleList(value => value.GetScalarValue()); + var scopes = property.Value.CreateSimpleList((value, p) => value.GetScalarValue()); if (scheme != null) { @@ -38,18 +39,9 @@ public static OpenApiSecurityRequirement LoadSecurityRequirement(ParseNode node) return securityRequirement; } - private static OpenApiSecurityScheme LoadSecuritySchemeByReference(string schemeName) + private static OpenApiSecurityScheme LoadSecuritySchemeByReference(string schemeName, OpenApiDocument hostDocument) { - var securitySchemeObject = new OpenApiSecurityScheme() - { - UnresolvedReference = true, - Reference = new OpenApiReference() - { - Id = schemeName, - Type = ReferenceType.SecurityScheme - } - }; - + var securitySchemeObject = new OpenApiSecuritySchemeReference(schemeName, hostDocument); return securitySchemeObject; } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs index 9966e085a..399eaf704 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiSecuritySchemeDeserializer.cs @@ -1,9 +1,11 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; +using System.Linq; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader.ParseNodes; namespace Microsoft.OpenApi.Reader.V31 @@ -73,10 +75,17 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node) + public static OpenApiSecurityScheme LoadSecurityScheme(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("securityScheme"); + var pointer = mapNode.GetReferencePointer(); + if (pointer != null) + { + var reference = GetReferenceIdAndExternalResource(pointer); + return new OpenApiSecuritySchemeReference(reference.Item1, hostDocument, reference.Item2); + } + var securityScheme = new OpenApiSecurityScheme(); foreach (var property in mapNode) { diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs index 0ace93c4d..a6c932dd9 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerDeserializer.cs @@ -40,7 +40,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiServer LoadServer(ParseNode node) + public static OpenApiServer LoadServer(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("server"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs index 4ce7dc188..aa3ce48d9 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiServerVariableDeserializer.cs @@ -19,7 +19,7 @@ internal static partial class OpenApiV31Deserializer { "enum", (o, n) => { - o.Enum = n.CreateSimpleList(s => s.GetScalarValue()); + o.Enum = n.CreateSimpleList((s, p) => s.GetScalarValue()); } }, { @@ -42,7 +42,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiServerVariable LoadServerVariable(ParseNode node) + public static OpenApiServerVariable LoadServerVariable(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("serverVariable"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs index f96ba7d48..76f3e674e 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiTagDeserializer.cs @@ -40,7 +40,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiTag LoadTag(ParseNode n) + public static OpenApiTag LoadTag(ParseNode n, OpenApiDocument hostDocument = null) { var mapNode = n.CheckMapNode("tag"); diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs index 256829cea..b65711e29 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31Deserializer.cs @@ -127,7 +127,7 @@ private static RuntimeExpressionAnyWrapper LoadRuntimeExpressionAnyWrapper(Parse }; } - public static OpenApiAny LoadAny(ParseNode node) + public static OpenApiAny LoadAny(ParseNode node, OpenApiDocument hostDocument = null) { return node.CreateAny(); } @@ -143,5 +143,16 @@ private static string LoadString(ParseNode node) { return node.GetScalarValue(); } + + private static (string, string) GetReferenceIdAndExternalResource(string pointer) + { + var refSegments = pointer.Split('/'); + var refId = refSegments.Last(); + var isExternalResource = !refSegments.First().StartsWith("#"); + + string externalResource = isExternalResource ? $"{refSegments.First()}/{refSegments[1].TrimEnd('#')}" : null; + + return (refId, externalResource); + } } } diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs index 1b977528a..202e4e905 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiV31VersionService.cs @@ -32,7 +32,7 @@ public OpenApiV31VersionService(OpenApiDiagnostic diagnostic) Diagnostic = diagnostic; } - private readonly IDictionary> _loaders = new Dictionary> + private readonly IDictionary> _loaders = new Dictionary> { [typeof(OpenApiAny)] = OpenApiV31Deserializer.LoadAny, [typeof(OpenApiCallback)] = OpenApiV31Deserializer.LoadCallback, @@ -159,9 +159,9 @@ public OpenApiDocument LoadDocument(RootNode rootNode) return OpenApiV31Deserializer.LoadOpenApi(rootNode); } - public T LoadElement(ParseNode node) where T : IOpenApiElement + public T LoadElement(ParseNode node, OpenApiDocument doc) where T : IOpenApiElement { - return (T)_loaders[typeof(T)](node); + return (T)_loaders[typeof(T)](node, doc); } /// diff --git a/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs b/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs index 6bbf97f6f..38b8b38fe 100644 --- a/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs +++ b/src/Microsoft.OpenApi/Reader/V31/OpenApiXmlDeserializer.cs @@ -54,7 +54,7 @@ internal static partial class OpenApiV31Deserializer {s => s.StartsWith("x-"), (o, p, n) => o.AddExtension(p, LoadExtension(p,n))} }; - public static OpenApiXml LoadXml(ParseNode node) + public static OpenApiXml LoadXml(ParseNode node, OpenApiDocument hostDocument = null) { var mapNode = node.CheckMapNode("xml"); diff --git a/src/Microsoft.OpenApi/Services/HostDocumentResolver.cs b/src/Microsoft.OpenApi/Services/HostDocumentResolver.cs new file mode 100644 index 000000000..c11d8fed3 --- /dev/null +++ b/src/Microsoft.OpenApi/Services/HostDocumentResolver.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using Microsoft.OpenApi.Interfaces; +using Microsoft.OpenApi.Models; + +namespace Microsoft.OpenApi.Services +{ + internal class HostDocumentResolver : OpenApiVisitorBase + { + private readonly OpenApiDocument _currentDocument; + + public HostDocumentResolver(OpenApiDocument currentDocument) + { + _currentDocument = currentDocument; + } + + /// + /// Visits the referenceable element in the host document + /// + /// The referenceable element in the doc. + public override void Visit(IOpenApiReferenceable referenceable) + { + if (referenceable.Reference != null) + { + referenceable.Reference.HostDocument = _currentDocument; + } + } + } +} diff --git a/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs b/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs index 839aafd28..3e04e5eb8 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiVisitorBase.cs @@ -279,7 +279,7 @@ public virtual void Visit(OpenApiTag tag) /// /// Visits /// - public virtual void Visit(OpenApiHeader tag) + public virtual void Visit(OpenApiHeader header) { } diff --git a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs index ddb92a952..ef3ea811d 100644 --- a/src/Microsoft.OpenApi/Services/OpenApiWalker.cs +++ b/src/Microsoft.OpenApi/Services/OpenApiWalker.cs @@ -9,6 +9,7 @@ using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; namespace Microsoft.OpenApi.Services { @@ -391,11 +392,17 @@ internal void Walk(OpenApiContact contact) /// internal void Walk(OpenApiCallback callback, bool isComponent = false) { - if (callback == null || ProcessAsReference(callback, isComponent)) + if (callback == null) { return; } + if (callback is OpenApiCallbackReference) + { + Walk(callback as IOpenApiReferenceable); + return; + } + _visitor.Visit(callback); if (callback != null) @@ -415,8 +422,14 @@ internal void Walk(OpenApiCallback callback, bool isComponent = false) /// internal void Walk(OpenApiTag tag) { - if (tag == null || ProcessAsReference(tag)) + if (tag == null) + { + return; + } + + if (tag is OpenApiTagReference) { + Walk(tag as IOpenApiReferenceable); return; } @@ -482,11 +495,17 @@ internal void Walk(OpenApiServerVariable serverVariable) /// internal void Walk(OpenApiPathItem pathItem, bool isComponent = false) { - if (pathItem == null || ProcessAsReference(pathItem, isComponent)) + if (pathItem == null) { return; } + if (pathItem is OpenApiPathItemReference) + { + Walk(pathItem as IOpenApiReferenceable); + return; + } + if (_pathItemLoop.Contains(pathItem)) { return; // Loop detected, this pathItem has already been walked. @@ -599,11 +618,17 @@ internal void Walk(IList parameters) /// internal void Walk(OpenApiParameter parameter, bool isComponent = false) { - if (parameter == null || ProcessAsReference(parameter, isComponent)) + if (parameter == null) { return; } + if (parameter is OpenApiParameterReference) + { + Walk(parameter as IOpenApiReferenceable); + return; + } + _visitor.Visit(parameter); Walk(OpenApiConstants.Schema, () => Walk(parameter.Schema)); Walk(OpenApiConstants.Content, () => Walk(parameter.Content)); @@ -641,11 +666,17 @@ internal void Walk(OpenApiResponses responses) /// internal void Walk(OpenApiResponse response, bool isComponent = false) { - if (response == null || ProcessAsReference(response, isComponent)) + if (response == null) { return; } + if (response is OpenApiResponseReference) + { + Walk(response as IOpenApiReferenceable); + return; + } + _visitor.Visit(response); Walk(OpenApiConstants.Content, () => Walk(response.Content)); Walk(OpenApiConstants.Links, () => Walk(response.Links)); @@ -658,11 +689,17 @@ internal void Walk(OpenApiResponse response, bool isComponent = false) /// internal void Walk(OpenApiRequestBody requestBody, bool isComponent = false) { - if (requestBody == null || ProcessAsReference(requestBody, isComponent)) + if (requestBody == null) { return; } + if (requestBody is OpenApiRequestBodyReference) + { + Walk(requestBody as IOpenApiReferenceable); + return; + } + _visitor.Visit(requestBody); if (requestBody is {Content: not null}) @@ -935,11 +972,17 @@ internal void Walk(OpenApiAny example) /// internal void Walk(OpenApiExample example, bool isComponent = false) { - if (example == null || ProcessAsReference(example, isComponent)) + if (example == null) { return; } + if (example is OpenApiExampleReference) + { + Walk(example as IOpenApiReferenceable); + return; + } + _visitor.Visit(example); Walk(example as IOpenApiExtensible); } @@ -1041,11 +1084,17 @@ internal void Walk(IDictionary links) /// internal void Walk(OpenApiLink link, bool isComponent = false) { - if (link == null || ProcessAsReference(link, isComponent)) + if (link == null) { return; } + if (link is OpenApiLinkReference) + { + Walk(link as IOpenApiReferenceable); + return; + } + _visitor.Visit(link); Walk(OpenApiConstants.Server, () => Walk(link.Server)); Walk(link as IOpenApiExtensible); @@ -1056,11 +1105,17 @@ internal void Walk(OpenApiLink link, bool isComponent = false) /// internal void Walk(OpenApiHeader header, bool isComponent = false) { - if (header == null || ProcessAsReference(header, isComponent)) + if (header == null) { return; } + if (header is OpenApiHeaderReference) + { + Walk(header as IOpenApiReferenceable); + return; + } + _visitor.Visit(header); Walk(OpenApiConstants.Content, () => Walk(header.Content)); Walk(OpenApiConstants.Example, () => Walk(header.Example)); @@ -1079,6 +1134,11 @@ internal void Walk(OpenApiSecurityRequirement securityRequirement) return; } + foreach(var securityScheme in securityRequirement.Keys) + { + Walk(securityScheme); + } + _visitor.Visit(securityRequirement); Walk(securityRequirement as IOpenApiExtensible); } @@ -1088,11 +1148,17 @@ internal void Walk(OpenApiSecurityRequirement securityRequirement) /// internal void Walk(OpenApiSecurityScheme securityScheme, bool isComponent = false) { - if (securityScheme == null || ProcessAsReference(securityScheme, isComponent)) + if (securityScheme == null) { return; } + if (securityScheme is OpenApiSecuritySchemeReference) + { + Walk(securityScheme as IOpenApiReferenceable); + return; + } + _visitor.Visit(securityScheme); Walk(securityScheme as IOpenApiExtensible); } @@ -1163,20 +1229,6 @@ private void Walk(string context, Action walk) _visitor.Exit(); } - /// - /// Identify if an element is just a reference to a component, or an actual component - /// - private bool ProcessAsReference(IOpenApiReferenceable referenceable, bool isComponent = false) - { - var isReference = referenceable.Reference != null && - (!isComponent || referenceable.UnresolvedReference); - if (isReference) - { - Walk(referenceable); - } - return isReference; - } - private bool ProcessSchemaAsReference(IBaseDocument baseDocument, bool isComponent = false) { var schema = baseDocument as JsonSchema; diff --git a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs index 05ab521ab..076869ad6 100644 --- a/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs +++ b/src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs @@ -1,7 +1,8 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; +using System.Linq; using System.Text.Json; using System.Text.Json.Nodes; using Json.Schema; @@ -52,6 +53,15 @@ public static void ValidateDataTypeMismatch( return; } + // Resolve the Json schema in memory before validating the data types. + var reference = schema.GetRef(); + if (reference != null) + { + var referencePath = string.Concat("https://registry", reference.OriginalString.Split('#').Last()); + var resolvedSchema = (JsonSchema)SchemaRegistry.Global.Get(new Uri(referencePath)); + schema = resolvedSchema ?? schema; + } + var type = schema.GetJsonType()?.GetDisplayName(); var format = schema.GetFormat()?.Key; var jsonElement = JsonSerializer.Deserialize(value); diff --git a/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs b/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs index f7d66e53d..542dc5cd4 100644 --- a/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs +++ b/src/Microsoft.OpenApi/Writers/OpenApiWriterBase.cs @@ -647,5 +647,12 @@ public static void ResolveJsonSchema(JsonSchema schema) var walker = new OpenApiWalker(visitor); walker.Walk(schema); } + + public static JsonSchema FetchSchemaFromRegistry(JsonSchema schema, Uri reference) + { + var referencePath = string.Concat("https://registry", reference.OriginalString.Split('#').Last()); + var resolvedSchema = (JsonSchema)SchemaRegistry.Global.Get(new Uri(referencePath)); + return resolvedSchema ?? schema; + } } } diff --git a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs index 4b61d3bd3..ad1c587f0 100644 --- a/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs +++ b/test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.cs @@ -242,7 +242,7 @@ public async Task TransformToPowerShellCompliantOpenApi() // create a dummy ILogger instance for testing await OpenApiService.TransformOpenApiDocument(options, _logger); - var output = await File.ReadAllTextAsync("output.yml"); + var output = await File.ReadAllTextAsync("output.yaml"); Assert.NotEmpty(output); } diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs index 05c40c21d..2eb86e4e6 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiDiagnosticTests.cs @@ -61,7 +61,6 @@ public async Task DiagnosticReportMergedForExternalReference() result.OpenApiDiagnostic.Errors.Should().BeEquivalentTo(new List { new OpenApiError("", "[File: ./TodoReference.yaml] Paths is a REQUIRED field at #/"), - new(new OpenApiException("[File: ./TodoReference.yaml] Invalid Reference identifier 'object-not-existing'.")) }); } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs index bf8c7c8a4..aa8013bc2 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiWorkspaceTests/OpenApiWorkspaceStreamTests.cs @@ -75,14 +75,10 @@ public async Task LoadDocumentWithExternalReferenceShouldLoadBothDocumentsIntoWo .Content["application/json"] .Schema; - var x = referencedSchema.GetProperties().TryGetValue("subject", out var schema); - Assert.Equal(SchemaValueType.Object, referencedSchema.GetJsonType()); - Assert.Equal(SchemaValueType.String, schema.GetJsonType()); - var referencedParameter = result.OpenApiDocument .Paths["/todos"] .Operations[OperationType.Get] - .Parameters.Select(p => p.GetEffective(result.OpenApiDocument)) + .Parameters.Select(p => p) .FirstOrDefault(p => p.Name == "filter"); Assert.Equal(SchemaValueType.String, referencedParameter.Schema.GetJsonType()); diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs index 398bbff42..99359881c 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/TryLoadReferenceV2Tests.cs @@ -3,9 +3,12 @@ using System.Collections.Generic; using System.IO; +using System.Linq; using FluentAssertions; using Json.Schema; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; +using Microsoft.OpenApi.Reader; using Xunit; namespace Microsoft.OpenApi.Readers.Tests.ReferenceService @@ -15,23 +18,20 @@ public class TryLoadReferenceV2Tests { private const string SampleFolderPath = "ReferenceService/Samples/"; + public TryLoadReferenceV2Tests() + { + OpenApiReaderRegistry.RegisterReader("yaml", new OpenApiYamlReader()); + } + [Fact] public void LoadParameterReference() { // Arrange var result = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml")); - - var reference = new OpenApiReference - { - Type = ReferenceType.Parameter, - Id = "skipParam" - }; - - // Act - var referencedObject = result.OpenApiDocument.ResolveReferenceTo(reference); + var reference = new OpenApiParameterReference("skipParam", result.OpenApiDocument); // Assert - referencedObject.Should().BeEquivalentTo( + reference.Should().BeEquivalentTo( new OpenApiParameter { Name = "skip", @@ -40,13 +40,8 @@ public void LoadParameterReference() Required = true, Schema = new JsonSchemaBuilder() .Type(SchemaValueType.Integer) - .Format("int32"), - Reference = new OpenApiReference - { - Type = ReferenceType.Parameter, - Id = "skipParam" - } - } + .Format("int32") + }, options => options.Excluding(x => x.Reference) ); } @@ -55,28 +50,16 @@ public void LoadSecuritySchemeReference() { var result = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml")); - var reference = new OpenApiReference - { - Type = ReferenceType.SecurityScheme, - Id = "api_key_sample" - }; - - // Act - var referencedObject = result.OpenApiDocument.ResolveReferenceTo(reference); + var reference = new OpenApiSecuritySchemeReference("api_key_sample", result.OpenApiDocument); // Assert - referencedObject.Should().BeEquivalentTo( + reference.Should().BeEquivalentTo( new OpenApiSecurityScheme { Type = SecuritySchemeType.ApiKey, Name = "api_key", - In = ParameterLocation.Header, - Reference = new() - { - Type = ReferenceType.SecurityScheme, - Id = "api_key_sample" - } - } + In = ParameterLocation.Header + }, options => options.Excluding(x => x.Reference) ); } @@ -85,30 +68,18 @@ public void LoadResponseReference() { var result = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml")); - var reference = new OpenApiReference - { - Type = ReferenceType.Response, - Id = "NotFound" - }; - - // Act - var referencedObject = result.OpenApiDocument.ResolveReferenceTo(reference); + var reference = new OpenApiResponseReference("NotFound", result.OpenApiDocument); // Assert - referencedObject.Should().BeEquivalentTo( + reference.Should().BeEquivalentTo( new OpenApiResponse { Description = "Entity not found.", - Reference = new() - { - Type = ReferenceType.Response, - Id = "NotFound" - }, Content = new Dictionary { ["application/json"] = new() } - } + }, options => options.Excluding(x => x.Reference) ); } @@ -116,19 +87,10 @@ public void LoadResponseReference() public void LoadResponseAndSchemaReference() { var result = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "multipleReferences.v2.yaml")); - - - var reference = new OpenApiReference - { - Type = ReferenceType.Response, - Id = "GeneralError" - }; - - // Act - var referencedObject = result.OpenApiDocument.ResolveReferenceTo(reference); + var reference = new OpenApiResponseReference("GeneralError", result.OpenApiDocument); // Assert - referencedObject.Should().BeEquivalentTo( + reference.Should().BeEquivalentTo( new OpenApiResponse { Description = "General Error", @@ -138,19 +100,9 @@ public void LoadResponseAndSchemaReference() { Schema = new JsonSchemaBuilder() .Ref("#/definitions/SampleObject2") - .Description("Sample description") - .Required("name") - .Properties( - ("name", new JsonSchemaBuilder().Type(SchemaValueType.String)), - ("tag", new JsonSchemaBuilder().Type(SchemaValueType.String))) } - }, - Reference = new() - { - Type = ReferenceType.Response, - Id = "GeneralError" } - } + }, options => options.Excluding(x => x.Reference) ); } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs index 5df1291bd..ee9e1f401 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/ComparisonTests.cs @@ -4,6 +4,7 @@ using System.IO; using FluentAssertions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Reader; using Xunit; namespace Microsoft.OpenApi.Readers.Tests.V2Tests @@ -19,6 +20,7 @@ public class ComparisonTests //[InlineData("definitions")] //Currently broken due to V3 references not behaving the same as V2 public void EquivalentV2AndV3DocumentsShouldProductEquivalentObjects(string fileName) { + OpenApiReaderRegistry.RegisterReader("yaml", new OpenApiYamlReader()); using var streamV2 = Resources.GetStream(Path.Combine(SampleFolderPath, $"{fileName}.v2.yaml")); using var streamV3 = Resources.GetStream(Path.Combine(SampleFolderPath, $"{fileName}.v3.yaml")); var result1 = OpenApiDocument.Load(Path.Combine(SampleFolderPath, $"{fileName}.v2.yaml")); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs index 754de9e5a..d864f597d 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiDocumentTests.cs @@ -32,18 +32,19 @@ public void ShouldParseProducesInAnyOrder() var errorSchema = new JsonSchemaBuilder() .Ref("#/definitions/Error") - .Properties(("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int32")), + .Properties( + ("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int32")), ("message", new JsonSchemaBuilder().Type(SchemaValueType.String)), ("fields", new JsonSchemaBuilder().Type(SchemaValueType.String))); var okMediaType = new OpenApiMediaType { - Schema = new JsonSchemaBuilder().Type(SchemaValueType.Array).Items(okSchema) + Schema = new JsonSchemaBuilder().Type(SchemaValueType.Array).Items(new JsonSchemaBuilder().Ref("#/definitions/Item")) }; var errorMediaType = new OpenApiMediaType { - Schema = errorSchema + Schema = new JsonSchemaBuilder().Ref("#/definitions/Error") }; result.OpenApiDocument.Should().BeEquivalentTo(new OpenApiDocument @@ -150,7 +151,6 @@ public void ShouldParseProducesInAnyOrder() }); } - [Fact] public void ShouldAssignSchemaToAllResponses() { @@ -162,29 +162,26 @@ public void ShouldAssignSchemaToAllResponses() var successSchema = new JsonSchemaBuilder() .Type(SchemaValueType.Array) .Items(new JsonSchemaBuilder() - .Ref("#/definitions/Item") - .Properties(("id", new JsonSchemaBuilder().Type(SchemaValueType.String).Description("Item identifier.")))) - .Build(); + .Properties(("id", new JsonSchemaBuilder().Type(SchemaValueType.String).Description("Item identifier.")))); var errorSchema = new JsonSchemaBuilder() - .Ref("#/definitions/Error") .Properties(("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int32")), ("message", new JsonSchemaBuilder().Type(SchemaValueType.String)), - ("fields", new JsonSchemaBuilder().Type(SchemaValueType.String))) - .Build(); + ("fields", new JsonSchemaBuilder().Type(SchemaValueType.String))); var responses = result.OpenApiDocument.Paths["/items"].Operations[OperationType.Get].Responses; foreach (var response in responses) { - var targetSchema = response.Key == "200" ? successSchema : errorSchema; + var targetSchema = response.Key == "200" ? successSchema.Build() : errorSchema.Build(); var json = response.Value.Content["application/json"]; Assert.NotNull(json); - json.Schema.Should().BeEquivalentTo(targetSchema); + + Assert.Equal(json.Schema.Keywords.Count, targetSchema.Keywords.Count); var xml = response.Value.Content["application/xml"]; Assert.NotNull(xml); - xml.Schema.Should().BeEquivalentTo(targetSchema); + Assert.Equal(xml.Schema.Keywords.Count, targetSchema.Keywords.Count); } } @@ -192,8 +189,10 @@ public void ShouldAssignSchemaToAllResponses() public void ShouldAllowComponentsThatJustContainAReference() { // Act - var actual = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "ComponentRootReference.json")); - JsonSchema schema = actual.OpenApiDocument.Components.Schemas["AllPets"]; + var actual = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "ComponentRootReference.json")).OpenApiDocument; + JsonSchema schema = actual.Components.Schemas["AllPets"]; + + schema = actual.ResolveJsonSchemaReference(schema.GetRef()) ?? schema; // Assert if (schema.Keywords.Count.Equals(1) && schema.GetRef() != null) diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs index 7f1f7545d..2e5779adb 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs @@ -8,6 +8,11 @@ namespace Microsoft.OpenApi.Readers.Tests.V2Tests { public class OpenApiServerTests { + public OpenApiServerTests() + { + OpenApiReaderRegistry.RegisterReader("yaml", new OpenApiYamlReader()); + } + [Fact] public void NoServer() { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs index 0bdfea92e..d11a87d7b 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs @@ -17,6 +17,11 @@ public class OpenApiDocumentTests { private const string SampleFolderPath = "V31Tests/Samples/OpenApiDocument/"; + public OpenApiDocumentTests() + { + OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader()); + } + public static T Clone(T element) where T : IOpenApiSerializable { using var stream = new MemoryStream(); @@ -85,7 +90,7 @@ public void ParseDocumentWithWebhooksShouldSucceed() }, Webhooks = new Dictionary { - ["/pets"] = new OpenApiPathItem + ["pets"] = new OpenApiPathItem { Operations = new Dictionary { @@ -128,14 +133,14 @@ public void ParseDocumentWithWebhooksShouldSucceed() { Schema = new JsonSchemaBuilder() .Type(SchemaValueType.Array) - .Items(petSchema) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/petSchema")) }, ["application/xml"] = new OpenApiMediaType { Schema = new JsonSchemaBuilder() .Type(SchemaValueType.Array) - .Items(petSchema) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/petSchema")) } } } @@ -151,7 +156,7 @@ public void ParseDocumentWithWebhooksShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = newPetSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/newPetSchema") } } }, @@ -164,7 +169,7 @@ public void ParseDocumentWithWebhooksShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/petSchema") } } } @@ -177,7 +182,7 @@ public void ParseDocumentWithWebhooksShouldSucceed() }; // Assert - var schema = actual.OpenApiDocument.Webhooks["/pets"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema; + var schema = actual.OpenApiDocument.Webhooks["pets"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema; actual.OpenApiDiagnostic.Should().BeEquivalentTo(new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_1 }); actual.OpenApiDocument.Should().BeEquivalentTo(expected); } @@ -215,7 +220,7 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds() components.PathItems = new Dictionary { - ["/pets"] = new OpenApiPathItem + ["pets"] = new OpenApiPathItem { Operations = new Dictionary { @@ -256,13 +261,13 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds() { Schema = new JsonSchemaBuilder() .Type(SchemaValueType.Array) - .Items(petSchema) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/petSchema")) }, ["application/xml"] = new OpenApiMediaType { Schema = new JsonSchemaBuilder() .Type(SchemaValueType.Array) - .Items(petSchema) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/petSchema")) } } } @@ -278,7 +283,7 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds() { ["application/json"] = new OpenApiMediaType { - Schema = newPetSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/newPetSchema") } } }, @@ -291,18 +296,12 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds() { ["application/json"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/petSchema") }, } } } } - }, - Reference = new OpenApiReference - { - Type = ReferenceType.PathItem, - Id = "/pets", - HostDocument = actual.OpenApiDocument } } }; @@ -315,29 +314,19 @@ public void ParseDocumentsWithReusablePathItemInWebhooksSucceeds() Version = "1.0.0" }, JsonSchemaDialect = "http://json-schema.org/draft-07/schema#", - Webhooks = components.PathItems, + Webhooks = new Dictionary + { + ["pets"] = components.PathItems["pets"] + }, Components = components }; // Assert - actual.OpenApiDocument.Should().BeEquivalentTo(expected); + actual.OpenApiDocument.Should().BeEquivalentTo(expected, options => options.Excluding(x => x.Webhooks["pets"].Reference)); actual.OpenApiDiagnostic.Should().BeEquivalentTo( new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_1 }); } - [Fact] - public void ParseDocumentWithDescriptionInDollarRefsShouldSucceed() - { - // Arrange - var actual = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "documentWithSummaryAndDescriptionInReference.yaml")); - - // Act - var header = actual.OpenApiDocument.Components.Responses["Test"].Headers["X-Test"]; - - // Assert - Assert.True(header.Description == "A referenced X-Test header"); /*response header #ref's description overrides the header's description*/ - } - [Fact] public void ParseDocumentWithExampleInSchemaShouldSucceed() { diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml index 33cf7301e..28fa04b19 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithReusablePaths.yaml @@ -4,7 +4,7 @@ info: version: 1.0.0 jsonSchemaDialect: "http://json-schema.org/draft-07/schema#" webhooks: - /pets: + pets: "$ref": '#/components/pathItems/pets' components: schemas: @@ -34,7 +34,7 @@ components: tag: type: string pathItems: - /pets: + pets: get: description: Returns all pets from the system that the user has access to operationId: findPets diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml index 37a05f101..bfa7ab627 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithSummaryAndDescriptionInReference.yaml @@ -26,8 +26,6 @@ components: headers: X-Test: $ref: '#/components/headers/X-Test' - summary: X-Test header - description: A referenced X-Test header schemas: pet: description: A referenced pet in a petstore diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml index 74dd1b473..aeadc3d69 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/Samples/OpenApiDocument/documentWithWebhooks.yaml @@ -3,7 +3,7 @@ info: title: Webhook Example version: 1.0.0 webhooks: - /pets: + pets: get: description: Returns all pets from the system that the user has access to operationId: findPets diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs index 50cadb81c..25871e25e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/JsonSchemaTests.cs @@ -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.Collections.Generic; @@ -220,7 +220,7 @@ public void ParseBasicSchemaWithReferenceShouldSucceed() SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, Errors = new List() { - new OpenApiError("", "Paths is a REQUIRED field at #/") + new OpenApiError("", "Paths is a REQUIRED field at #/") } }); @@ -228,27 +228,22 @@ public void ParseBasicSchemaWithReferenceShouldSucceed() { Schemas = { - ["ErrorModel"] = new JsonSchemaBuilder() - .Ref("#/components/schemas/ErrorModel") - .Type(SchemaValueType.Object) - .Required("message", "code") - .Properties( - ("message", new JsonSchemaBuilder().Type(SchemaValueType.String)), - ("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Minimum(100).Maximum(600))), - ["ExtendedErrorModel"] = new JsonSchemaBuilder() - .Ref("#/components/schemas/ExtendedErrorModel") - .AllOf( - new JsonSchemaBuilder() - .Ref("#/components/schemas/ErrorModel") - .Type(SchemaValueType.Object) - .Properties( - ("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Minimum(100).Maximum(600)), - ("message", new JsonSchemaBuilder().Type(SchemaValueType.String))) - .Required("message", "code"), - new JsonSchemaBuilder() - .Type(SchemaValueType.Object) - .Required("rootCause") - .Properties(("rootCause", new JsonSchemaBuilder().Type(SchemaValueType.String)))) + ["ErrorModel"] = new JsonSchemaBuilder() + .Ref("#/components/schemas/ErrorModel") + .Type(SchemaValueType.Object) + .Required("message", "code") + .Properties( + ("message", new JsonSchemaBuilder().Type(SchemaValueType.String)), + ("code", new JsonSchemaBuilder().Type(SchemaValueType.Integer).Minimum(100).Maximum(600))), + ["ExtendedErrorModel"] = new JsonSchemaBuilder() + .Ref("#/components/schemas/ExtendedErrorModel") + .AllOf( + new JsonSchemaBuilder() + .Ref("#/components/schemas/ErrorModel"), + new JsonSchemaBuilder() + .Type(SchemaValueType.Object) + .Required("rootCause") + .Properties(("rootCause", new JsonSchemaBuilder().Type(SchemaValueType.String)))) } }; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs index 9190744d7..5deea9e83 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs @@ -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.IO; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs index d7b038830..33bc1c0d5 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs @@ -9,9 +9,11 @@ using FluentAssertions; using Json.Schema; using Microsoft.OpenApi.Any; +using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; +using Microsoft.OpenApi.Tests; using Microsoft.OpenApi.Validations; using Microsoft.OpenApi.Validations.Rules; using Microsoft.OpenApi.Writers; @@ -205,8 +207,7 @@ public void ParseMinimalDocumentShouldSucceed() [Fact] public void ParseStandardPetStoreDocumentShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStore.yaml")); - var result = OpenApiDocument.Load(stream, OpenApiConstants.Yaml); + var result = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "petStore.yaml")); var components = new OpenApiComponents { @@ -237,11 +238,6 @@ public void ParseStandardPetStoreDocumentShouldSucceed() ("message", new JsonSchemaBuilder().Type(SchemaValueType.String))) } }; - var petSchema = components.Schemas["pet1"]; - - var newPetSchema = components.Schemas["newPet"]; - - var errorModelSchema = components.Schemas["errorModel"]; var expectedDoc = new OpenApiDocument { @@ -311,11 +307,13 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = new JsonSchemaBuilder().Type(SchemaValueType.Array).Items(petSchema) + Schema = new JsonSchemaBuilder().Type(SchemaValueType.Array) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/pet1")) }, ["application/xml"] = new OpenApiMediaType { - Schema = new JsonSchemaBuilder().Type(SchemaValueType.Array).Items(petSchema) + Schema = new JsonSchemaBuilder().Type(SchemaValueType.Array) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/pet1")) } } }, @@ -326,7 +324,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -337,7 +335,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } @@ -355,7 +353,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = newPetSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/newPet") } } }, @@ -368,7 +366,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/pet1") }, } }, @@ -379,7 +377,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -390,7 +388,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } @@ -427,11 +425,11 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/pet1") }, ["application/xml"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/pet1") } } }, @@ -442,7 +440,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -453,7 +451,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } @@ -487,7 +485,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -498,7 +496,7 @@ public void ParseStandardPetStoreDocumentShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } @@ -512,15 +510,14 @@ public void ParseStandardPetStoreDocumentShouldSucceed() result.OpenApiDocument.Should().BeEquivalentTo(expectedDoc); - result.OpenApiDiagnostic.Should().BeEquivalentTo( - new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }); + result.OpenApiDiagnostic.Should().BeEquivalentTo( + new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }); } [Fact] public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { - using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStoreWithTagAndSecurity.yaml")); - var actual = OpenApiDocument.Load(stream, OpenApiConstants.Yaml); + var actual = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "petStoreWithTagAndSecurity.yaml")); var components = new OpenApiComponents { @@ -556,35 +553,16 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { Type = SecuritySchemeType.ApiKey, Name = "apiKeyName1", - In = ParameterLocation.Header, - Reference = new OpenApiReference - { - Id = "securitySchemeName1", - Type = ReferenceType.SecurityScheme, - HostDocument = actual.OpenApiDocument - } - + In = ParameterLocation.Header }, ["securitySchemeName2"] = new OpenApiSecurityScheme { Type = SecuritySchemeType.OpenIdConnect, - OpenIdConnectUrl = new Uri("http://example.com"), - Reference = new OpenApiReference - { - Id = "securitySchemeName2", - Type = ReferenceType.SecurityScheme, - HostDocument = actual.OpenApiDocument - } + OpenIdConnectUrl = new Uri("http://example.com") } } }; - var petSchema = components.Schemas["pet1"]; - - var newPetSchema = components.Schemas["newPet"]; - - var errorModelSchema = components.Schemas["errorModel"]; - var tag1 = new OpenApiTag { Name = "tagName1", @@ -596,10 +574,14 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() } }; - var tag2 = new OpenApiTag { - Name = "tagName2" + Name = "tagName2", + Reference = new OpenApiReference + { + Id = "tagName2", + Type = ReferenceType.Tag + } }; var securityScheme1 = CloneSecurityScheme(components.SecuritySchemes["securitySchemeName1"]); @@ -640,12 +622,12 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() } }, Servers = new List + { + new OpenApiServer { - new OpenApiServer - { - Url = "http://petstore.swagger.io/api" - } - }, + Url = "http://petstore.swagger.io/api" + } + }, Paths = new OpenApiPaths { ["/pets"] = new OpenApiPathItem @@ -655,35 +637,35 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() [OperationType.Get] = new OpenApiOperation { Tags = new List - { - tag1, - tag2 - }, + { + tag1, + tag2 + }, Description = "Returns all pets from the system that the user has access to", OperationId = "findPets", Parameters = new List + { + new OpenApiParameter { - new OpenApiParameter - { - Name = "tags", - In = ParameterLocation.Query, - Description = "tags to filter by", - Required = false, - Schema = new JsonSchemaBuilder() - .Type(SchemaValueType.Array) - .Items(new JsonSchemaBuilder().Type(SchemaValueType.String)) - }, - new OpenApiParameter - { - Name = "limit", - In = ParameterLocation.Query, - Description = "maximum number of results to return", - Required = false, - Schema = new JsonSchemaBuilder() - .Type(SchemaValueType.Integer) - .Format("int32") - } + Name = "tags", + In = ParameterLocation.Query, + Description = "tags to filter by", + Required = false, + Schema = new JsonSchemaBuilder() + .Type(SchemaValueType.Array) + .Items(new JsonSchemaBuilder().Type(SchemaValueType.String)) }, + new OpenApiParameter + { + Name = "limit", + In = ParameterLocation.Query, + Description = "maximum number of results to return", + Required = false, + Schema = new JsonSchemaBuilder() + .Type(SchemaValueType.Integer) + .Format("int32") + } + }, Responses = new OpenApiResponses { ["200"] = new OpenApiResponse @@ -695,13 +677,13 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { Schema = new JsonSchemaBuilder() .Type(SchemaValueType.Array) - .Items(petSchema) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/pet1")) }, ["application/xml"] = new OpenApiMediaType { Schema = new JsonSchemaBuilder() .Type(SchemaValueType.Array) - .Items(petSchema) + .Items(new JsonSchemaBuilder().Ref("#/components/schemas/pet1")) } } }, @@ -712,7 +694,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -723,7 +705,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } @@ -732,10 +714,10 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() [OperationType.Post] = new OpenApiOperation { Tags = new List - { - tag1, - tag2 - }, + { + tag1, + tag2 + }, Description = "Creates a new pet in the store. Duplicates are allowed", OperationId = "addPet", RequestBody = new OpenApiRequestBody @@ -746,7 +728,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = newPetSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/newPet") } } }, @@ -759,7 +741,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/pet1") }, } }, @@ -770,7 +752,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -781,23 +763,23 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } }, Security = new List + { + new OpenApiSecurityRequirement { - new OpenApiSecurityRequirement + [securityScheme1] = new List(), + [securityScheme2] = new List { - [securityScheme1] = new List(), - [securityScheme2] = new List - { - "scope1", - "scope2" - } + "scope1", + "scope2" } } + } } } }, @@ -811,18 +793,18 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() "Returns a user based on a single ID, if the user does not have access to the pet", OperationId = "findPetById", Parameters = new List + { + new OpenApiParameter { - new OpenApiParameter - { - Name = "id", - In = ParameterLocation.Path, - Description = "ID of pet to fetch", - Required = true, - Schema = new JsonSchemaBuilder() - .Type(SchemaValueType.Integer) - .Format("int64") - } - }, + Name = "id", + In = ParameterLocation.Path, + Description = "ID of pet to fetch", + Required = true, + Schema = new JsonSchemaBuilder() + .Type(SchemaValueType.Integer) + .Format("int64") + } + }, Responses = new OpenApiResponses { ["200"] = new OpenApiResponse @@ -832,11 +814,11 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["application/json"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/pet1") }, ["application/xml"] = new OpenApiMediaType { - Schema = petSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/pet1") } } }, @@ -847,7 +829,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -858,7 +840,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } @@ -869,18 +851,18 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() Description = "deletes a single pet based on the ID supplied", OperationId = "deletePet", Parameters = new List + { + new OpenApiParameter { - new OpenApiParameter - { - Name = "id", - In = ParameterLocation.Path, - Description = "ID of pet to delete", - Required = true, - Schema = new JsonSchemaBuilder() - .Type(SchemaValueType.Integer) - .Format("int64") - } - }, + Name = "id", + In = ParameterLocation.Path, + Description = "ID of pet to delete", + Required = true, + Schema = new JsonSchemaBuilder() + .Type(SchemaValueType.Integer) + .Format("int64") + } + }, Responses = new OpenApiResponses { ["204"] = new OpenApiResponse @@ -894,7 +876,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } }, @@ -905,7 +887,7 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() { ["text/html"] = new OpenApiMediaType { - Schema = errorModelSchema + Schema = new JsonSchemaBuilder().Ref("#/components/schemas/errorModel") } } } @@ -916,39 +898,41 @@ public void ParseModifiedPetStoreDocumentWithTagAndSecurityShouldSucceed() }, Components = components, Tags = new List + { + new OpenApiTag { - new OpenApiTag - { - Name = "tagName1", - Description = "tagDescription1", - Reference = new OpenApiReference() - { - Id = "tagName1", - Type = ReferenceType.Tag - } - } - }, + Name = "tagName1", + Description = "tagDescription1" + } + }, SecurityRequirements = new List + { + new OpenApiSecurityRequirement { - new OpenApiSecurityRequirement + [securityScheme1] = new List(), + [securityScheme2] = new List { - [securityScheme1] = new List(), - [securityScheme2] = new List - { - "scope1", - "scope2", - "scope3" - } + "scope1", + "scope2", + "scope3" } } + } }; - actual.OpenApiDocument.Should().BeEquivalentTo(expected, options => options.Excluding(m => m.Name == "HostDocument")); + actual.OpenApiDocument.Should().BeEquivalentTo(expected, options => options + .Excluding(x => x.HashCode) + .Excluding(m => m.Tags[0].Reference) + .Excluding(x => x.Paths["/pets"].Operations[OperationType.Get].Tags[0].Reference) + .Excluding(x => x.Paths["/pets"].Operations[OperationType.Get].Tags[0].Reference.HostDocument) + .Excluding(x => x.Paths["/pets"].Operations[OperationType.Post].Tags[0].Reference.HostDocument) + .Excluding(x => x.Paths["/pets"].Operations[OperationType.Get].Tags[1].Reference.HostDocument) + .Excluding(x => x.Paths["/pets"].Operations[OperationType.Post].Tags[1].Reference.HostDocument)); + actual.OpenApiDiagnostic.Should().BeEquivalentTo( new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }); } - [Fact] public void ParsePetStoreExpandedShouldSucceed() { @@ -967,7 +951,8 @@ public void GlobalSecurityRequirementShouldReferenceSecurityScheme() var securityRequirement = result.OpenApiDocument.SecurityRequirements.First(); - Assert.Same(securityRequirement.Keys.First(), result.OpenApiDocument.Components.SecuritySchemes.First().Value); + securityRequirement.Keys.First().Should().BeEquivalentTo(result.OpenApiDocument.Components.SecuritySchemes.First().Value, + options => options.Excluding(x => x.Reference)); } [Fact] @@ -990,14 +975,10 @@ public void HeaderParameterShouldAllowExample() Example = new OpenApiAny("99391c7e-ad88-49ec-a2ad-99ddcb1f7721"), Schema = new JsonSchemaBuilder() .Type(SchemaValueType.String) - .Format(Formats.Uuid), - Reference = new OpenApiReference() - { - Type = ReferenceType.Header, - Id = "example-header" - } + .Format(Formats.Uuid) }, options => options.IgnoringCyclicReferences() - .Excluding(e => e.Example.Node.Parent)); + .Excluding(e => e.Example.Node.Parent) + .Excluding(x => x.Reference)); var examplesHeader = result.OpenApiDocument.Components?.Headers?["examples-header"]; Assert.NotNull(examplesHeader); @@ -1026,12 +1007,7 @@ public void HeaderParameterShouldAllowExample() }, Schema = new JsonSchemaBuilder() .Type(SchemaValueType.String) - .Format(Formats.Uuid), - Reference = new OpenApiReference() - { - Type = ReferenceType.Header, - Id = "examples-header" - } + .Format(Formats.Uuid) }, options => options.IgnoringCyclicReferences() .Excluding(e => e.Examples["uuid1"].Value.Node.Parent) .Excluding(e => e.Examples["uuid2"].Value.Node.Parent)); @@ -1070,17 +1046,109 @@ public void ParseDocumentWithJsonSchemaReferencesWorks() var actualSchema = result.OpenApiDocument.Paths["/users/{userId}"].Operations[OperationType.Get].Responses["200"].Content["application/json"].Schema; var expectedSchema = new JsonSchemaBuilder() - .Ref("#/components/schemas/User") - .Type(SchemaValueType.Object) - .Properties( - ("id", new JsonSchemaBuilder().Type(SchemaValueType.Integer)), - ("username", new JsonSchemaBuilder().Type(SchemaValueType.String)), - ("email", new JsonSchemaBuilder().Type(SchemaValueType.String))) - .Build(); + .Ref("#/components/schemas/User"); // Assert - actualSchema.Should().BeEquivalentTo(expectedSchema); + Assert.Equal(expectedSchema, actualSchema); } + [Fact] + public void ParseDocWithRefsUsingProxyReferencesSucceeds() + { + // Arrange + var expected = new OpenApiDocument + { + Info = new OpenApiInfo + { + Title = "Pet Store with Referenceable Parameter", + Version = "1.0.0" + }, + Paths = new OpenApiPaths + { + ["/pets"] = new OpenApiPathItem + { + Operations = new Dictionary + { + [OperationType.Get] = new OpenApiOperation + { + Summary = "Returns all pets", + Parameters = + [ + new OpenApiParameter + { + Name = "limit", + In = ParameterLocation.Query, + Description = "Limit the number of pets returned", + Required = false, + Schema = new JsonSchemaBuilder() + .Type(SchemaValueType.Integer) + .Format("int32") + .Default(10), + Reference = new OpenApiReference + { + Id = "LimitParameter", + Type = ReferenceType.Parameter + } + } + ], + Responses = new OpenApiResponses() + } + } + } + }, + Components = new OpenApiComponents + { + Parameters = new Dictionary + { + ["LimitParameter"] = new OpenApiParameter + { + Name = "limit", + In = ParameterLocation.Query, + Description = "Limit the number of pets returned", + Required = false, + Schema = new JsonSchemaBuilder() + .Type(SchemaValueType.Integer) + .Format("int32") + .Default(10) + } + } + } + }; + + var expectedSerializedDoc = @"openapi: 3.0.1 +info: + title: Pet Store with Referenceable Parameter + version: 1.0.0 +paths: + /pets: + get: + summary: Returns all pets + parameters: + - $ref: '#/components/parameters/LimitParameter' + responses: { } +components: + parameters: + LimitParameter: + name: limit + in: query + description: Limit the number of pets returned + schema: + type: integer + format: int32 + default: 10"; + + using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "minifiedPetStore.yaml")); + + // Act + var doc = OpenApiDocument.Load(stream, "yaml").OpenApiDocument; + var actualParam = doc.Paths["/pets"].Operations[OperationType.Get].Parameters.First(); + var outputDoc = doc.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_0).MakeLineBreaksEnvironmentNeutral(); + var output = actualParam.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_0); + var expectedParam = expected.Paths["/pets"].Operations[OperationType.Get].Parameters.First(); + + // Assert + actualParam.Should().BeEquivalentTo(expectedParam, options => options.Excluding(x => x.Reference.HostDocument)); + outputDoc.Should().BeEquivalentTo(expectedSerializedDoc.MakeLineBreaksEnvironmentNeutral()); + } } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs index d0a62062e..f8b0d1f1f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiExampleTests.cs @@ -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.IO; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs index 6d94ed88b..ff03c553f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiOperationTests.cs @@ -6,6 +6,7 @@ using FluentAssertions; using Json.Schema; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Reader; using Xunit; @@ -25,9 +26,10 @@ public void OperationWithSecurityRequirementShouldReferenceSecurityScheme() { var result = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "securedOperation.yaml")); - var securityRequirement = result.OpenApiDocument.Paths["/"].Operations[OperationType.Get].Security.First(); + var securityScheme = result.OpenApiDocument.Paths["/"].Operations[OperationType.Get].Security.First().Keys.First(); - Assert.Same(securityRequirement.Keys.First(), result.OpenApiDocument.Components.SecuritySchemes.First().Value); + securityScheme.Should().BeEquivalentTo(result.OpenApiDocument.Components.SecuritySchemes.First().Value, + options => options.Excluding(x => x.Reference)); } [Fact] @@ -35,21 +37,11 @@ public void ParseOperationWithParameterWithNoLocationShouldSucceed() { // Act var operation = OpenApiModelFactory.Load(Path.Combine(SampleFolderPath, "operationWithParameterWithNoLocation.json"), OpenApiSpecVersion.OpenApi3_0, out _); - - // Assert - operation.Should().BeEquivalentTo(new OpenApiOperation + var expectedOp = new OpenApiOperation { Tags = { - new OpenApiTag - { - UnresolvedReference = true, - Reference = new() - { - Id = "user", - Type = ReferenceType.Tag - } - } + new OpenApiTagReference("user", null) }, Summary = "Logs user into the system", Description = "", @@ -74,7 +66,12 @@ public void ParseOperationWithParameterWithNoLocationShouldSucceed() .Type(SchemaValueType.String) } } - }); + }; + + // Assert + expectedOp.Should().BeEquivalentTo(operation, + options => options.Excluding(x => x.Tags[0].Reference.HostDocument) + .Excluding(x => x.Tags[0].Extensions)); } } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs index b87f68375..ee3dfe97f 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiParameterTests.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using System.Collections.Generic; +using System; using System.IO; using FluentAssertions; using Json.Schema; @@ -8,6 +10,7 @@ using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; using Xunit; +using Microsoft.OpenApi.Reader.V3; namespace Microsoft.OpenApi.Readers.Tests.V3Tests { @@ -256,5 +259,82 @@ public void ParseParameterWithExamplesShouldSucceed() .Excluding(p => p.Examples["example1"].Value.Node.Parent) .Excluding(p => p.Examples["example2"].Value.Node.Parent)); } + + [Fact] + public void ParseParameterWithReferenceWorks() + { + // Arrange + var document = new OpenApiDocument + { + Info = new OpenApiInfo + { + Version = "1.0.0", + Title = "Swagger Petstore (Simple)" + }, + Servers = new List + { + new OpenApiServer + { + Url = "http://petstore.swagger.io/api" + } + }, + Paths = new OpenApiPaths + { + ["/pets"] = new OpenApiPathItem + { + Operations = new Dictionary + { + [OperationType.Get] = new OpenApiOperation + { + Description = "Returns all pets from the system that the user has access to", + OperationId = "findPets", + Parameters = new List + { + new() { + Reference = new OpenApiReference + { + Type = ReferenceType.Parameter, + Id = "tagsParameter" + } + } + }, + } + } + } + }, + Components = new OpenApiComponents + { + Parameters = new Dictionary() + { + ["tagsParameter"] = new OpenApiParameter + { + Name = "tags", + In = ParameterLocation.Query, + Description = "tags to filter by", + Required = false, + Schema = new JsonSchemaBuilder() + .Type(SchemaValueType.Array) + .Items(new JsonSchemaBuilder().Type(SchemaValueType.String)).Build(), + Reference = new OpenApiReference + { + Type = ReferenceType.Parameter, + Id = "tagsParameter" + } + } + } + } + }; + + using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "parameterWithRef.yaml")); + var node = TestHelper.CreateYamlMapNode(stream); + + var expected = document.Components.Parameters["tagsParameter"]; + + // Act + var param = OpenApiV3Deserializer.LoadParameter(node, document); + + // Assert + param.Should().BeEquivalentTo(expected, options => options.Excluding(p => p.Reference.HostDocument)); + } } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs index c2a939ade..09a1d00a1 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiResponseTests.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; +using FluentAssertions; using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Reader; using Xunit; @@ -25,8 +26,10 @@ public void ResponseWithReferencedHeaderShouldReferenceComponent() var result = OpenApiDocument.Load(Path.Combine(SampleFolderPath, "responseWithHeaderReference.yaml")); var response = result.OpenApiDocument.Components.Responses["Test"]; + var expected = response.Headers.First().Value; + var actual = result.OpenApiDocument.Components.Headers.First().Value; - Assert.Same(response.Headers.First().Value, result.OpenApiDocument.Components.Headers.First().Value); + actual.Description.Should().BeEquivalentTo(expected.Description); } } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/minifiedPetStore.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/minifiedPetStore.yaml new file mode 100644 index 000000000..6ebfc23fc --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/minifiedPetStore.yaml @@ -0,0 +1,22 @@ +openapi: 3.0.0 +info: + title: Pet Store with Referenceable Parameter + version: 1.0.0 +paths: + /pets: + get: + summary: Returns all pets + parameters: + - $ref: '#/components/parameters/LimitParameter' + responses: {} +components: + parameters: + LimitParameter: + name: limit + in: query + description: Limit the number of pets returned + required: false + schema: + type: integer + format: int32 + default: 10 diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiParameter/parameterWithRef.yaml b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiParameter/parameterWithRef.yaml new file mode 100644 index 000000000..63f38a94e --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiParameter/parameterWithRef.yaml @@ -0,0 +1 @@ +"$ref": '#/components/parameters/tagsParameter' \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj index a72a8f8cd..0f087c4aa 100644 --- a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj +++ b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj @@ -29,10 +29,10 @@ - Always + PreserveNewest - Always + PreserveNewest diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs index 34d857a94..c7935e768 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiCallbackTests.cs @@ -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.Globalization; @@ -7,6 +7,7 @@ using Json.Schema; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -52,13 +53,10 @@ public class OpenApiCallbackTests } }; + public static OpenApiCallbackReference CallbackProxy = new(ReferencedCallback, "simpleHook"); + public static OpenApiCallback ReferencedCallback = new() { - Reference = new() - { - Type = ReferenceType.Callback, - Id = "simpleHook", - }, PathItems = { [RuntimeExpression.Build("$request.body#/url")] @@ -119,7 +117,7 @@ public async Task SerializeReferencedCallbackAsV3JsonWorks(bool produceTerseOutp var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedCallback.SerializeAsV3(writer); + CallbackProxy.SerializeAsV3(writer); writer.Flush(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs index 3ecef6fcb..6da171ec3 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiExampleTests.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -58,13 +59,9 @@ public class OpenApiExampleTests }) }; + public static OpenApiExampleReference OpenApiExampleReference = new(ReferencedExample, "example1"); public static OpenApiExample ReferencedExample = new() { - Reference = new() - { - Type = ReferenceType.Example, - Id = "example1", - }, Value = new OpenApiAny(new JsonObject { ["versions"] = new JsonArray @@ -128,7 +125,7 @@ public async Task SerializeReferencedExampleAsV3JsonWorks(bool produceTerseOutpu var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedExample.SerializeAsV3(writer); + OpenApiExampleReference.SerializeAsV3(writer); writer.Flush(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs index a314012f1..4d120531b 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiHeaderTests.cs @@ -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.Globalization; @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Json.Schema; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -22,13 +23,10 @@ public class OpenApiHeaderTests Schema = new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int32").Build() }; + public static OpenApiHeaderReference OpenApiHeaderReference = new(ReferencedHeader, "example1"); + public static OpenApiHeader ReferencedHeader = new() { - Reference = new() - { - Type = ReferenceType.Header, - Id = "example1", - }, Description = "sampleHeader", Schema = new JsonSchemaBuilder().Type(SchemaValueType.Integer).Format("int32").Build() }; @@ -60,7 +58,7 @@ public async Task SerializeReferencedHeaderAsV3JsonWorks(bool produceTerseOutput var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedHeader.SerializeAsV3(writer); + OpenApiHeaderReference.SerializeAsV3(writer); writer.Flush(); // Assert @@ -79,7 +77,6 @@ public async Task SerializeReferencedHeaderAsV3JsonWithoutReferenceWorks(bool pr // Act ReferencedHeader.SerializeAsV3WithoutReference(writer); writer.Flush(); - var actual = outputStringWriter.GetStringBuilder().ToString(); // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); @@ -112,7 +109,7 @@ public async Task SerializeReferencedHeaderAsV2JsonWorks(bool produceTerseOutput var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedHeader.SerializeAsV2(writer); + OpenApiHeaderReference.SerializeAsV2(writer); writer.Flush(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs index baf4f3899..e930aacb9 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiLinkTests.cs @@ -8,6 +8,7 @@ using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Expressions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -42,6 +43,7 @@ public class OpenApiLinkTests } }; + public static readonly OpenApiLinkReference LinkReference = new(ReferencedLink, "example1"); public static readonly OpenApiLink ReferencedLink = new() { Reference = new() @@ -98,7 +100,7 @@ public async Task SerializeReferencedLinkAsV3JsonWorksAsync(bool produceTerseOut var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedLink.SerializeAsV3(writer); + LinkReference.SerializeAsV3(writer); writer.Flush(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs index 283b3d8d2..756b10514 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiOperationTests.cs @@ -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.Collections.Generic; @@ -6,6 +6,7 @@ using Json.Schema; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Xunit; namespace Microsoft.OpenApi.Tests.Models @@ -52,14 +53,7 @@ public class OpenApiOperationTests }, Responses = new() { - ["200"] = new() - { - Reference = new() - { - Id = "response1", - Type = ReferenceType.Response - } - }, + ["200"] = new OpenApiResponseReference("response1", hostDocument: null), ["400"] = new() { Content = new Dictionary @@ -90,14 +84,7 @@ public class OpenApiOperationTests Name = "tagName1", Description = "tagDescription1", }, - new() - { - Reference = new() - { - Id = "tagId1", - Type = ReferenceType.Tag - } - } + new OpenApiTagReference("tagId1", null) }, Summary = "summary1", Description = "operationDescription", @@ -134,14 +121,7 @@ public class OpenApiOperationTests }, Responses = new() { - ["200"] = new() - { - Reference = new() - { - Id = "response1", - Type = ReferenceType.Response - } - }, + ["200"] = new OpenApiResponseReference("response1", hostDocument: null), ["400"] = new() { Content = new Dictionary @@ -157,22 +137,8 @@ public class OpenApiOperationTests { new() { - [new() - { - Reference = new() - { - Id = "securitySchemeId1", - Type = ReferenceType.SecurityScheme - } - }] = new List(), - [new() - { - Reference = new() - { - Id = "securitySchemeId2", - Type = ReferenceType.SecurityScheme - } - }] = new List + [new OpenApiSecuritySchemeReference("securitySchemeId1", hostDocument: null)] = new List(), + [new OpenApiSecuritySchemeReference("securitySchemeId2", hostDocument: null)] = new List { "scopeName1", "scopeName2" diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs index d846f7a99..f861e0189 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiParameterTests.cs @@ -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.Collections.Generic; @@ -11,6 +11,7 @@ using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -27,15 +28,11 @@ public class OpenApiParameterTests In = ParameterLocation.Path }; + public static OpenApiParameterReference OpenApiParameterReference = new(ReferencedParameter, "example1"); public static OpenApiParameter ReferencedParameter = new() { Name = "name1", - In = ParameterLocation.Path, - Reference = new() - { - Type = ReferenceType.Parameter, - Id = "example1" - } + In = ParameterLocation.Path }; public static OpenApiParameter AdvancedPathParameterWithSchema = new() @@ -319,7 +316,7 @@ public async Task SerializeReferencedParameterAsV3JsonWorksAsync(bool produceTer var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedParameter.SerializeAsV3(writer); + OpenApiParameterReference.SerializeAsV3(writer); writer.Flush(); // Assert @@ -353,7 +350,7 @@ public async Task SerializeReferencedParameterAsV2JsonWorksAsync(bool produceTer var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedParameter.SerializeAsV2(writer); + OpenApiParameterReference.SerializeAsV2(writer); writer.Flush(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs index 12c911c57..0e205b71e 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiRequestBodyTests.cs @@ -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.Globalization; @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Json.Schema; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -29,13 +30,9 @@ public class OpenApiRequestBodyTests } }; + public static OpenApiRequestBodyReference OpenApiRequestBodyReference = new(ReferencedRequestBody, "example1"); public static OpenApiRequestBody ReferencedRequestBody = new() { - Reference = new() - { - Type = ReferenceType.RequestBody, - Id = "example1", - }, Description = "description", Required = true, Content = @@ -74,7 +71,7 @@ public async Task SerializeReferencedRequestBodyAsV3JsonWorksAsync(bool produceT var writer = new OpenApiJsonWriter(outputStringWriter, new() { Terse = produceTerseOutput }); // Act - ReferencedRequestBody.SerializeAsV3(writer); + OpenApiRequestBodyReference.SerializeAsV3(writer); writer.Flush(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs index c9bd5d56f..421505ee2 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiResponseTests.cs @@ -11,6 +11,7 @@ using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -86,13 +87,10 @@ public class OpenApiResponseTests }, } }; + + public static OpenApiResponseReference V2OpenApiResponseReference = new OpenApiResponseReference("example1", ReferencedV2Response); public static OpenApiResponse ReferencedV2Response = new OpenApiResponse { - Reference = new OpenApiReference - { - Type = ReferenceType.Response, - Id = "example1" - }, Description = "A complex object array response", Content = { @@ -117,13 +115,10 @@ public class OpenApiResponseTests }, } }; + public static OpenApiResponseReference V3OpenApiResponseReference = new OpenApiResponseReference("example1", ReferencedV3Response); + public static OpenApiResponse ReferencedV3Response = new OpenApiResponse { - Reference = new OpenApiReference - { - Type = ReferenceType.Response, - Id = "example1" - }, Description = "A complex object array response", Content = { @@ -332,7 +327,7 @@ public async Task SerializeReferencedResponseAsV3JsonWorksAsync(bool produceTers var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); // Act - ReferencedV3Response.SerializeAsV3(writer); + V3OpenApiResponseReference.SerializeAsV3(writer); writer.Flush(); // Assert @@ -366,7 +361,7 @@ public async Task SerializeReferencedResponseAsV2JsonWorksAsync(bool produceTers var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); // Act - ReferencedV2Response.SerializeAsV2(writer); + V2OpenApiResponseReference.SerializeAsV2(writer); writer.Flush(); // Assert diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs index 9aaa611f3..016938839 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecurityRequirementTests.cs @@ -6,6 +6,7 @@ using FluentAssertions; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Xunit; namespace Microsoft.OpenApi.Tests.Models @@ -19,10 +20,7 @@ public class OpenApiSecurityRequirementTests new() { [ - new() - { - Reference = new() { Type = ReferenceType.SecurityScheme, Id = "scheme1" } - } + new OpenApiSecuritySchemeReference("scheme1", hostDocument: null) ] = new List { "scope1", @@ -30,20 +28,14 @@ public class OpenApiSecurityRequirementTests "scope3", }, [ - new() - { - Reference = new() { Type = ReferenceType.SecurityScheme, Id = "scheme2" } - } + new OpenApiSecuritySchemeReference("scheme2", hostDocument: null) ] = new List { "scope4", "scope5", }, [ - new() - { - Reference = new() { Type = ReferenceType.SecurityScheme, Id = "scheme3" } - } + new OpenApiSecuritySchemeReference("scheme3", hostDocument: null) ] = new List() }; @@ -51,10 +43,7 @@ public class OpenApiSecurityRequirementTests new() { [ - new() - { - Reference = new() { Type = ReferenceType.SecurityScheme, Id = "scheme1" } - } + new OpenApiSecuritySchemeReference("scheme1", hostDocument: null) ] = new List { "scope1", @@ -73,10 +62,7 @@ public class OpenApiSecurityRequirementTests "scope5", }, [ - new() - { - Reference = new() { Type = ReferenceType.SecurityScheme, Id = "scheme3" } - } + new OpenApiSecuritySchemeReference("scheme3", hostDocument: null) ] = new List() }; diff --git a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs index b17f96f08..19bac6305 100644 --- a/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/OpenApiSecuritySchemeTests.cs @@ -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.Collections.Generic; @@ -8,6 +8,7 @@ using FluentAssertions; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Writers; using VerifyXunit; using Xunit; @@ -105,17 +106,13 @@ public class OpenApiSecuritySchemeTests OpenIdConnectUrl = new("https://example.com/openIdConnect") }; + public static OpenApiSecuritySchemeReference OpenApiSecuritySchemeReference = new(target: ReferencedSecurityScheme, referenceId: "sampleSecurityScheme"); public static OpenApiSecurityScheme ReferencedSecurityScheme = new() { Description = "description1", Type = SecuritySchemeType.OpenIdConnect, Scheme = OpenApiConstants.Bearer, - OpenIdConnectUrl = new("https://example.com/openIdConnect"), - Reference = new() - { - Type = ReferenceType.SecurityScheme, - Id = "sampleSecurityScheme" - } + OpenIdConnectUrl = new("https://example.com/openIdConnect") }; [Fact] @@ -318,7 +315,7 @@ public async Task SerializeReferencedSecuritySchemeAsV3JsonWorksAsync(bool produ // Add dummy start object, value, and end object to allow SerializeAsV3 to output security scheme // as property name. writer.WriteStartObject(); - ReferencedSecurityScheme.SerializeAsV3(writer); + OpenApiSecuritySchemeReference.SerializeAsV3(writer); writer.WriteNull(); writer.WriteEndObject(); writer.Flush(); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs index 02ee501e3..3e5917932 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiCallbackReferenceTests.cs @@ -153,7 +153,7 @@ public async Task SerializeCallbackReferenceAsV3JsonWorks(bool produceTerseOutpu { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localCallbackReference.SerializeAsV3(writer); @@ -170,7 +170,7 @@ public async Task SerializeCallbackReferenceAsV31JsonWorks(bool produceTerseOutp { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localCallbackReference.SerializeAsV31(writer); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs index 819c986de..0faedb3e7 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiExampleReferenceTests.cs @@ -130,7 +130,7 @@ public async Task SerializeExampleReferenceAsV3JsonWorks(bool produceTerseOutput { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localExampleReference.SerializeAsV3(writer); @@ -147,7 +147,7 @@ public async Task SerializeExampleReferenceAsV31JsonWorks(bool produceTerseOutpu { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localExampleReference.SerializeAsV31(writer); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt index 8b29b212e..8bd613186 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt @@ -1,4 +1,4 @@ { - "description": "Location of the locally created post", + "description": "The URL of the newly created post", "type": "string" } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt index 243908873..9d510cb80 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.SerializeHeaderReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"description":"Location of the locally created post","type":"string"} \ No newline at end of file +{"description":"The URL of the newly created post","type":"string"} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs index 7f699725b..46bfdcd39 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiHeaderReferenceTests.cs @@ -100,7 +100,7 @@ public async Task SerializeHeaderReferenceAsV3JsonWorks(bool produceTerseOutput) { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localHeaderReference.SerializeAsV3(writer); @@ -117,7 +117,7 @@ public async Task SerializeHeaderReferenceAsV31JsonWorks(bool produceTerseOutput { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localHeaderReference.SerializeAsV31(writer); @@ -134,7 +134,7 @@ public async Task SerializeHeaderReferenceAsV2JsonWorksAsync(bool produceTerseOu { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true}); // Act _localHeaderReference.SerializeAsV2(writer); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs index a54a47db1..93e31dc11 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiLinkReferenceTests.cs @@ -136,7 +136,7 @@ public async Task SerializeLinkReferenceAsV3JsonWorks(bool produceTerseOutput) { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localLinkReference.SerializeAsV3(writer); @@ -153,7 +153,7 @@ public async Task SerializeLinkReferenceAsV31JsonWorks(bool produceTerseOutput) { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localLinkReference.SerializeAsV31(writer); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt index 2a64ba6d9..992c2f047 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=False.verified.txt @@ -1,7 +1,7 @@ { "in": "query", "name": "limit", - "description": "Results to return", + "description": "Number of results to return", "type": "integer", "maximum": 100, "minimum": 1 diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt index 8d3cb1803..995eb077e 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.SerializeParameterReferenceAsV2JsonWorksAsync_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"in":"query","name":"limit","description":"Results to return","type":"integer","maximum":100,"minimum":1} \ No newline at end of file +{"in":"query","name":"limit","description":"Number of results to return","type":"integer","maximum":100,"minimum":1} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs index 8568f1c44..e3583b0bf 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiParameterReferenceTests.cs @@ -102,7 +102,7 @@ public async Task SerializeParameterReferenceAsV3JsonWorks(bool produceTerseOutp { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localParameterReference.SerializeAsV3(writer); @@ -119,7 +119,7 @@ public async Task SerializeParameterReferenceAsV31JsonWorks(bool produceTerseOut { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localParameterReference.SerializeAsV31(writer); @@ -136,7 +136,7 @@ public async Task SerializeParameterReferenceAsV2JsonWorksAsync(bool produceTers { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput , InlineLocalReferences = true }); // Act _localParameterReference.SerializeAsV2(writer); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs index 5d77bde1b..dea2313e5 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiPathItemReferenceTests.cs @@ -20,7 +20,7 @@ namespace Microsoft.OpenApi.Tests.Models.References public class OpenApiPathItemReferenceTests { private const string OpenApi = @" -openapi: 3.0.0 +openapi: 3.1.0 info: title: Sample API version: 1.0.0 @@ -51,7 +51,7 @@ public class OpenApiPathItemReferenceTests "; private const string OpenApi_2 = @" -openapi: 3.0.0 +openapi: 3.1.0 info: title: Sample API version: 1.0.0 @@ -104,23 +104,6 @@ public void PathItemReferenceResolutionWorks() Assert.Equal("User path item summary", _openApiDoc.Components.PathItems.First().Value.Summary); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task SerializePathItemReferenceAsV3JsonWorks(bool produceTerseOutput) - { - // Arrange - var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); - - // Act - _localPathItemReference.SerializeAsV3(writer); - writer.Flush(); - - // Assert - await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); - } - [Theory] [InlineData(true)] [InlineData(false)] @@ -128,7 +111,7 @@ public async Task SerializePathItemReferenceAsV31JsonWorks(bool produceTerseOutp { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _localPathItemReference.SerializeAsV31(writer); @@ -137,22 +120,5 @@ public async Task SerializePathItemReferenceAsV31JsonWorks(bool produceTerseOutp // Assert await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task SerializePathItemReferenceAsV2JsonWorksAsync(bool produceTerseOutput) - { - // Arrange - var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); - - // Act - _localPathItemReference.SerializeAsV2(writer); - writer.Flush(); - - // Assert - await Verifier.Verify(outputStringWriter).UseParameters(produceTerseOutput); - } } } diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt index cdbbe00d1..a9be81418 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt @@ -1,10 +1,3 @@ { - "description": "User creation request body", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserSchema" - } - } - } + "$ref": "#/components/requestBodies/UserRequest" } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt index e82312f67..04f67afdd 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"description":"User creation request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}} \ No newline at end of file +{"$ref":"#/components/requestBodies/UserRequest"} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt index cdbbe00d1..a9be81418 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt @@ -1,10 +1,3 @@ { - "description": "User creation request body", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UserSchema" - } - } - } + "$ref": "#/components/requestBodies/UserRequest" } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt index e82312f67..04f67afdd 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.SerializeRequestBodyReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"description":"User creation request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}} \ No newline at end of file +{"$ref":"#/components/requestBodies/UserRequest"} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs index c0ce9bcef..f443960e3 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiRequestBodyReferenceTests.cs @@ -97,26 +97,6 @@ public OpenApiRequestBodyReferenceTests() }; } - [Fact] - public void RequestBodyReferenceResolutionWorks() - { - // Assert - var expectedSchema = new JsonSchemaBuilder() - .Ref("#/components/schemas/UserSchema") - .Type(SchemaValueType.Object) - .Properties( - ("name", new JsonSchemaBuilder().Type(SchemaValueType.String)), - ("email", new JsonSchemaBuilder().Type(SchemaValueType.String))) - .Build(); - var actualSchema = _localRequestBodyReference.Content["application/json"].Schema; - - actualSchema.Should().BeEquivalentTo(expectedSchema); - Assert.Equal("User request body", _localRequestBodyReference.Description); - Assert.Equal("application/json", _localRequestBodyReference.Content.First().Key); - Assert.Equal("External Reference: User request body", _externalRequestBodyReference.Description); - Assert.Equal("User creation request body", _openApiDoc.Components.RequestBodies.First().Value.Description); - } - [Theory] [InlineData(true)] [InlineData(false)] @@ -124,7 +104,7 @@ public async Task SerializeRequestBodyReferenceAsV3JsonWorks(bool produceTerseOu { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput}); // Act _localRequestBodyReference.SerializeAsV3(writer); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt index 45fb2bb48..3b61b5a39 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=False.verified.txt @@ -1,10 +1,3 @@ { - "description": "OK response", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/Pong" - } - } - } + "$ref": "#/components/responses/OkResponse" } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt index 7477918b3..d4776f5df 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV31JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"description":"OK response","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/Pong"}}}} \ No newline at end of file +{"$ref":"#/components/responses/OkResponse"} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt index 45fb2bb48..3b61b5a39 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=False.verified.txt @@ -1,10 +1,3 @@ { - "description": "OK response", - "content": { - "text/plain": { - "schema": { - "$ref": "#/components/schemas/Pong" - } - } - } + "$ref": "#/components/responses/OkResponse" } \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt index 7477918b3..d4776f5df 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.SerializeResponseReferenceAsV3JsonWorks_produceTerseOutput=True.verified.txt @@ -1 +1 @@ -{"description":"OK response","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/Pong"}}}} \ No newline at end of file +{"$ref":"#/components/responses/OkResponse"} \ No newline at end of file diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs index 0fed16f31..a905a7b1b 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiResponseReferenceTest.cs @@ -99,7 +99,7 @@ public async Task SerializeResponseReferenceAsV3JsonWorks(bool produceTerseOutpu { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput}); // Act _localResponseReference.SerializeAsV3(writer); @@ -116,7 +116,7 @@ public async Task SerializeResponseReferenceAsV31JsonWorks(bool produceTerseOutp { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput}); // Act _localResponseReference.SerializeAsV31(writer); diff --git a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs index a74712829..a0bea6e39 100644 --- a/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Models/References/OpenApiSecuritySchemeReferenceTests.cs @@ -63,7 +63,7 @@ public async Task SerializeSecuritySchemeReferenceAsV3JsonWorks(bool produceTers { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _openApiSecuritySchemeReference.SerializeAsV3(writer); @@ -80,7 +80,7 @@ public async Task SerializeSecuritySchemeReferenceAsV31JsonWorks(bool produceTer { // Arrange var outputStringWriter = new StringWriter(CultureInfo.InvariantCulture); - var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput }); + var writer = new OpenApiJsonWriter(outputStringWriter, new OpenApiJsonWriterSettings { Terse = produceTerseOutput, InlineLocalReferences = true }); // Act _openApiSecuritySchemeReference.SerializeAsV31(writer); diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 88fb6b3c0..1455b29ca 100755 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -277,11 +277,6 @@ namespace Microsoft.OpenApi.Extensions namespace Microsoft.OpenApi.Interfaces { public interface IDiagnostic { } - public interface IEffective - where T : class, Microsoft.OpenApi.Interfaces.IOpenApiElement - { - T GetEffective(Microsoft.OpenApi.Models.OpenApiDocument document); - } public interface IOpenApiElement { } public interface IOpenApiExtensible : Microsoft.OpenApi.Interfaces.IOpenApiElement { @@ -408,7 +403,7 @@ namespace Microsoft.OpenApi.MicrosoftExtensions } namespace Microsoft.OpenApi.Models { - public class OpenApiCallback : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiCallback : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiCallback() { } public OpenApiCallback(Microsoft.OpenApi.Models.OpenApiCallback callback) { } @@ -417,7 +412,6 @@ namespace Microsoft.OpenApi.Models public virtual System.Collections.Generic.Dictionary PathItems { get; set; } public virtual bool UnresolvedReference { get; set; } public void AddPathItem(Microsoft.OpenApi.Expressions.RuntimeExpression expression, Microsoft.OpenApi.Models.OpenApiPathItem pathItem) { } - public Microsoft.OpenApi.Models.OpenApiCallback GetEffective(Microsoft.OpenApi.Models.OpenApiDocument doc) { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -628,6 +622,7 @@ namespace Microsoft.OpenApi.Models public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public void SetHostDocument() { } public static string GenerateHashValue(Microsoft.OpenApi.Models.OpenApiDocument doc) { } public static Microsoft.OpenApi.Reader.ReadResult Load(string url, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) { } public static Microsoft.OpenApi.Reader.ReadResult Load(System.IO.Stream stream, string format, Microsoft.OpenApi.Reader.OpenApiReaderSettings settings = null) { } @@ -660,7 +655,7 @@ namespace Microsoft.OpenApi.Models public string Pointer { get; set; } public override string ToString() { } } - public class OpenApiExample : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiExample : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiExample() { } public OpenApiExample(Microsoft.OpenApi.Models.OpenApiExample example) { } @@ -671,7 +666,6 @@ namespace Microsoft.OpenApi.Models public virtual string Summary { get; set; } public virtual bool UnresolvedReference { get; set; } public virtual Microsoft.OpenApi.Any.OpenApiAny Value { get; set; } - public Microsoft.OpenApi.Models.OpenApiExample GetEffective(Microsoft.OpenApi.Models.OpenApiDocument doc) { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -700,7 +694,7 @@ namespace Microsoft.OpenApi.Models public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiHeader : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiHeader : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiHeader() { } public OpenApiHeader(Microsoft.OpenApi.Models.OpenApiHeader header) { } @@ -718,8 +712,7 @@ namespace Microsoft.OpenApi.Models public virtual Json.Schema.JsonSchema Schema { get; set; } public virtual Microsoft.OpenApi.Models.ParameterStyle? Style { get; set; } public virtual bool UnresolvedReference { get; set; } - public Microsoft.OpenApi.Models.OpenApiHeader GetEffective(Microsoft.OpenApi.Models.OpenApiDocument doc) { } - public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -754,7 +747,7 @@ namespace Microsoft.OpenApi.Models public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiLink : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiLink : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiLink() { } public OpenApiLink(Microsoft.OpenApi.Models.OpenApiLink link) { } @@ -767,7 +760,6 @@ namespace Microsoft.OpenApi.Models public virtual Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; set; } public virtual Microsoft.OpenApi.Models.OpenApiServer Server { get; set; } public virtual bool UnresolvedReference { get; set; } - public Microsoft.OpenApi.Models.OpenApiLink GetEffective(Microsoft.OpenApi.Models.OpenApiDocument doc) { } public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -836,7 +828,7 @@ namespace Microsoft.OpenApi.Models public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiParameter : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiParameter : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiParameter() { } public OpenApiParameter(Microsoft.OpenApi.Models.OpenApiParameter parameter) { } @@ -856,15 +848,14 @@ namespace Microsoft.OpenApi.Models public virtual Json.Schema.JsonSchema Schema { get; set; } public virtual Microsoft.OpenApi.Models.ParameterStyle? Style { get; set; } public virtual bool UnresolvedReference { get; set; } - public Microsoft.OpenApi.Models.OpenApiParameter GetEffective(Microsoft.OpenApi.Models.OpenApiDocument doc) { } - public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiPathItem : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiPathItem : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiPathItem() { } public OpenApiPathItem(Microsoft.OpenApi.Models.OpenApiPathItem pathItem) { } @@ -877,8 +868,7 @@ namespace Microsoft.OpenApi.Models public virtual System.Collections.Generic.IList Servers { get; set; } public virtual string Summary { get; set; } public void AddOperation(Microsoft.OpenApi.Models.OperationType operationType, Microsoft.OpenApi.Models.OpenApiOperation operation) { } - public Microsoft.OpenApi.Models.OpenApiPathItem GetEffective(Microsoft.OpenApi.Models.OpenApiDocument doc) { } - public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -909,7 +899,7 @@ namespace Microsoft.OpenApi.Models public void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiRequestBody : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiRequestBody : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiRequestBody() { } public OpenApiRequestBody(Microsoft.OpenApi.Models.OpenApiRequestBody requestBody) { } @@ -927,7 +917,7 @@ namespace Microsoft.OpenApi.Models public virtual void SerializeAsV31WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } - public class OpenApiResponse : Microsoft.OpenApi.Interfaces.IEffective, Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable + public class OpenApiResponse : Microsoft.OpenApi.Interfaces.IOpenApiElement, Microsoft.OpenApi.Interfaces.IOpenApiExtensible, Microsoft.OpenApi.Interfaces.IOpenApiReferenceable, Microsoft.OpenApi.Interfaces.IOpenApiSerializable { public OpenApiResponse() { } public OpenApiResponse(Microsoft.OpenApi.Models.OpenApiResponse response) { } @@ -938,8 +928,7 @@ namespace Microsoft.OpenApi.Models public virtual System.Collections.Generic.IDictionary Extensions { get; set; } public virtual System.Collections.Generic.IDictionary Headers { get; set; } public virtual System.Collections.Generic.IDictionary Links { get; set; } - public Microsoft.OpenApi.Models.OpenApiResponse GetEffective(Microsoft.OpenApi.Models.OpenApiDocument doc) { } - public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -973,7 +962,7 @@ namespace Microsoft.OpenApi.Models public virtual System.Uri OpenIdConnectUrl { get; set; } public virtual string Scheme { get; set; } public virtual Microsoft.OpenApi.Models.SecuritySchemeType Type { get; set; } - public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1014,7 +1003,7 @@ namespace Microsoft.OpenApi.Models public virtual System.Collections.Generic.IDictionary Extensions { get; set; } public virtual Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; set; } public virtual string Name { get; set; } - public void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public virtual void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public void SerializeAsV2WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public virtual void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } @@ -1136,8 +1125,130 @@ namespace Microsoft.OpenApi.Models.References public override System.Collections.Generic.Dictionary PathItems { get; set; } public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public override void SerializeAsV31WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } - public override void SerializeAsV3WithoutReference(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiExampleReference : Microsoft.OpenApi.Models.OpenApiExample + { + public OpenApiExampleReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override string Description { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override string ExternalValue { get; set; } + public override string Summary { get; set; } + public override Microsoft.OpenApi.Any.OpenApiAny Value { get; set; } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiHeaderReference : Microsoft.OpenApi.Models.OpenApiHeader + { + public OpenApiHeaderReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override bool AllowEmptyValue { get; set; } + public override bool AllowReserved { get; set; } + public override System.Collections.Generic.IDictionary Content { get; set; } + public override bool Deprecated { get; set; } + public override string Description { get; set; } + public override Microsoft.OpenApi.Any.OpenApiAny Example { get; set; } + public override System.Collections.Generic.IDictionary Examples { get; set; } + public override bool Explode { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override bool Required { get; set; } + public override Json.Schema.JsonSchema Schema { get; set; } + public override Microsoft.OpenApi.Models.ParameterStyle? Style { get; set; } + public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiLinkReference : Microsoft.OpenApi.Models.OpenApiLink + { + public OpenApiLinkReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override string Description { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override string OperationId { get; set; } + public override string OperationRef { get; set; } + public override System.Collections.Generic.Dictionary Parameters { get; set; } + public override Microsoft.OpenApi.Models.RuntimeExpressionAnyWrapper RequestBody { get; set; } + public override Microsoft.OpenApi.Models.OpenApiServer Server { get; set; } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiParameterReference : Microsoft.OpenApi.Models.OpenApiParameter + { + public OpenApiParameterReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override bool AllowEmptyValue { get; set; } + public override bool AllowReserved { get; set; } + public override System.Collections.Generic.IDictionary Content { get; set; } + public override bool Deprecated { get; set; } + public override string Description { get; set; } + public override Microsoft.OpenApi.Any.OpenApiAny Example { get; set; } + public override System.Collections.Generic.IDictionary Examples { get; set; } + public override bool Explode { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override Microsoft.OpenApi.Models.ParameterLocation? In { get; set; } + public override string Name { get; set; } + public override bool Required { get; set; } + public override Json.Schema.JsonSchema Schema { get; set; } + public override Microsoft.OpenApi.Models.ParameterStyle? Style { get; set; } + public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiPathItemReference : Microsoft.OpenApi.Models.OpenApiPathItem + { + public OpenApiPathItemReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override string Description { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override System.Collections.Generic.IDictionary Operations { get; set; } + public override System.Collections.Generic.IList Parameters { get; set; } + public override System.Collections.Generic.IList Servers { get; set; } + public override string Summary { get; set; } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiRequestBodyReference : Microsoft.OpenApi.Models.OpenApiRequestBody + { + public OpenApiRequestBodyReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override System.Collections.Generic.IDictionary Content { get; set; } + public override string Description { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override bool Required { get; set; } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiResponseReference : Microsoft.OpenApi.Models.OpenApiResponse + { + public OpenApiResponseReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override System.Collections.Generic.IDictionary Content { get; set; } + public override string Description { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override System.Collections.Generic.IDictionary Headers { get; set; } + public override System.Collections.Generic.IDictionary Links { get; set; } + public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiSecuritySchemeReference : Microsoft.OpenApi.Models.OpenApiSecurityScheme + { + public OpenApiSecuritySchemeReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument, string externalResource = null) { } + public override string BearerFormat { get; set; } + public override string Description { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override Microsoft.OpenApi.Models.OpenApiOAuthFlows Flows { get; set; } + public override Microsoft.OpenApi.Models.ParameterLocation In { get; set; } + public override string Name { get; set; } + public override System.Uri OpenIdConnectUrl { get; set; } + public override string Scheme { get; set; } + public override Microsoft.OpenApi.Models.SecuritySchemeType Type { get; set; } + public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + } + public class OpenApiTagReference : Microsoft.OpenApi.Models.OpenApiTag + { + public OpenApiTagReference(string referenceId, Microsoft.OpenApi.Models.OpenApiDocument hostDocument) { } + public override string Description { get; set; } + public override System.Collections.Generic.IDictionary Extensions { get; set; } + public override Microsoft.OpenApi.Models.OpenApiExternalDocs ExternalDocs { get; set; } + public override string Name { get; set; } + public override void SerializeAsV2(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV3(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } + public override void SerializeAsV31(Microsoft.OpenApi.Writers.IOpenApiWriter writer) { } } } namespace Microsoft.OpenApi.Reader @@ -1350,7 +1461,7 @@ namespace Microsoft.OpenApi.Services public virtual void Visit(Microsoft.OpenApi.Models.OpenApiEncoding encoding) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiExample example) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiExternalDocs externalDocs) { } - public virtual void Visit(Microsoft.OpenApi.Models.OpenApiHeader tag) { } + public virtual void Visit(Microsoft.OpenApi.Models.OpenApiHeader header) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiInfo info) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiLicense license) { } public virtual void Visit(Microsoft.OpenApi.Models.OpenApiLink link) { } diff --git a/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs b/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs index 66af8fa51..208fd357c 100644 --- a/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs +++ b/test/Microsoft.OpenApi.Tests/Visitors/InheritanceTests.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using Json.Schema; @@ -262,10 +262,10 @@ public override void Visit(OpenApiTag tag) base.Visit(tag); } - public override void Visit(OpenApiHeader tag) + public override void Visit(OpenApiHeader header) { EncodeCall(); - base.Visit(tag); + base.Visit(header); } public override void Visit(OpenApiOAuthFlow openApiOAuthFlow) diff --git a/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs b/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs index 8631ac6a4..7878aaa4b 100644 --- a/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs +++ b/test/Microsoft.OpenApi.Tests/Walkers/WalkerLocationTests.cs @@ -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.Collections.Generic; @@ -7,6 +7,7 @@ using Json.Schema; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Models.References; using Microsoft.OpenApi.Services; using Xunit; @@ -213,15 +214,7 @@ public void LocateReferences() }, SecuritySchemes = new Dictionary { - ["test-secScheme"] = new OpenApiSecurityScheme - { - Reference = new OpenApiReference - { - Id = "reference-to-scheme", - Type = ReferenceType.SecurityScheme - }, - UnresolvedReference = true - } + ["test-secScheme"] = new OpenApiSecuritySchemeReference("reference-to-scheme", null, null) } } }; @@ -232,7 +225,7 @@ public void LocateReferences() locator.Locations.Where(l => l.StartsWith("referenceAt:")).Should().BeEquivalentTo(new List { "referenceAt: #/paths/~1/get/responses/200/content/application~1json/schema", - "referenceAt: #/paths/~1/get/responses/200/headers/test-header", + "referenceAt: #/paths/~1/get/responses/200/headers/test-header/schema", "referenceAt: #/components/schemas/derived", "referenceAt: #/components/schemas/derived/anyOf", "referenceAt: #/components/schemas/base", diff --git a/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs b/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs index ebbd78147..ea5442402 100644 --- a/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs +++ b/test/Microsoft.OpenApi.Tests/Writers/OpenApiYamlWriterTests.cs @@ -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; @@ -390,6 +390,8 @@ public void WriteInlineSchema() // Act doc.SerializeAsV3(writer); + var mediaType = doc.Paths["/"].Operations[OperationType.Get].Responses["200"].Content["application/json"]; + //mediaType.SerializeAsV3(writer); var actual = outputString.GetStringBuilder().ToString(); // Assert