From 8683e372ac7ff8402f2b776ed6d13e4491e59423 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Tue, 8 Feb 2022 14:50:08 +0300 Subject: [PATCH 1/3] Catch any OpenApiExceptions thrown during parsing and continue processing of schema components --- .../V3/OpenApiV3VersionService.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs index 2663b6a3b..3d4091b95 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.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; @@ -88,7 +88,14 @@ public OpenApiReference ConvertToOpenApiReference( if (reference.StartsWith("#")) { // "$ref": "#/components/schemas/Pet" - return ParseLocalReference(segments[1]); + try + { + return ParseLocalReference(segments[1]); + } + catch (OpenApiException) + { + return null; + } } // Where fragments point into a non-OpenAPI document, the id will be the complete fragment identifier string id = segments[1]; From 5984798377db70f3a0407818747a0f5f0529a30a Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Tue, 15 Feb 2022 18:15:25 +0300 Subject: [PATCH 2/3] Initialize a diagnostics object in the constructor and use it to append the exceptions caught --- .../V2/OpenApiV2VersionService.cs | 21 ++++++++++++++++++- .../V3/OpenApiV3VersionService.cs | 14 ++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs index 5baa580af..fbd4dbb85 100644 --- a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs +++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2VersionService.cs @@ -20,6 +20,17 @@ namespace Microsoft.OpenApi.Readers.V2 /// internal class OpenApiV2VersionService : IOpenApiVersionService { + public OpenApiDiagnostic Diagnostic { get; } + + /// + /// Create Parsing Context + /// + /// Provide instance for diagnotic object for collecting and accessing information about the parsing. + public OpenApiV2VersionService(OpenApiDiagnostic diagnostic) + { + Diagnostic = diagnostic; + } + private IDictionary> _loaders = new Dictionary> { [typeof(IOpenApiAny)] = OpenApiV2Deserializer.LoadAny, @@ -154,7 +165,15 @@ public OpenApiReference ConvertToOpenApiReference(string reference, ReferenceTyp if (reference.StartsWith("#")) { // "$ref": "#/definitions/Pet" - return ParseLocalReference(segments[1]); + try + { + return ParseLocalReference(segments[1]); + } + catch (OpenApiException ex) + { + Diagnostic.Errors.Add(new OpenApiError(ex)); + return null; + } } // $ref: externalSource.yaml#/Pet diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs index 3d4091b95..bdaedf560 100644 --- a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs +++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3VersionService.cs @@ -19,6 +19,17 @@ namespace Microsoft.OpenApi.Readers.V3 /// internal class OpenApiV3VersionService : IOpenApiVersionService { + public OpenApiDiagnostic Diagnostic { get; } + + /// + /// Create Parsing Context + /// + /// Provide instance for diagnotic object for collecting and accessing information about the parsing. + public OpenApiV3VersionService(OpenApiDiagnostic diagnostic) + { + Diagnostic = diagnostic; + } + private IDictionary> _loaders = new Dictionary> { [typeof(IOpenApiAny)] = OpenApiV3Deserializer.LoadAny, @@ -92,8 +103,9 @@ public OpenApiReference ConvertToOpenApiReference( { return ParseLocalReference(segments[1]); } - catch (OpenApiException) + catch (OpenApiException ex) { + Diagnostic.Errors.Add(new OpenApiError(ex)); return null; } } From a7b1e1e37175a7702ee3d772b72c6398f25ceea7 Mon Sep 17 00:00:00 2001 From: Maggie Kimani Date: Tue, 15 Feb 2022 18:16:36 +0300 Subject: [PATCH 3/3] Pass the Diagnostic object to the class instances --- .../ParsingContext.cs | 8 ++++---- .../ConvertToOpenApiReferenceV2Tests.cs | 16 +++++++++++----- .../ConvertToOpenApiReferenceV3Tests.cs | 18 +++++++++++++----- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.OpenApi.Readers/ParsingContext.cs b/src/Microsoft.OpenApi.Readers/ParsingContext.cs index b7cfb6acb..6c4dece2f 100644 --- a/src/Microsoft.OpenApi.Readers/ParsingContext.cs +++ b/src/Microsoft.OpenApi.Readers/ParsingContext.cs @@ -60,13 +60,13 @@ internal OpenApiDocument Parse(YamlDocument yamlDocument) switch (inputVersion) { case string version when version == "2.0": - VersionService = new OpenApiV2VersionService(); + VersionService = new OpenApiV2VersionService(Diagnostic); doc = VersionService.LoadDocument(RootNode); this.Diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi2_0; break; case string version when version.StartsWith("3.0"): - VersionService = new OpenApiV3VersionService(); + VersionService = new OpenApiV3VersionService(Diagnostic); doc = VersionService.LoadDocument(RootNode); this.Diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi3_0; break; @@ -93,12 +93,12 @@ internal T ParseFragment(YamlDocument yamlDocument, OpenApiSpecVersion versio switch (version) { case OpenApiSpecVersion.OpenApi2_0: - VersionService = new OpenApiV2VersionService(); + VersionService = new OpenApiV2VersionService(Diagnostic); element = this.VersionService.LoadElement(node); break; case OpenApiSpecVersion.OpenApi3_0: - this.VersionService = new OpenApiV3VersionService(); + this.VersionService = new OpenApiV3VersionService(Diagnostic); element = this.VersionService.LoadElement(node); break; } diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV2Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV2Tests.cs index e374dc205..ff6641f88 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV2Tests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV2Tests.cs @@ -10,12 +10,18 @@ namespace Microsoft.OpenApi.Readers.Tests { public class ConvertToOpenApiReferenceV2Tests { + public OpenApiDiagnostic Diagnostic{get;} + + public ConvertToOpenApiReferenceV2Tests() + { + Diagnostic = new OpenApiDiagnostic(); + } [Fact] public void ParseExternalReference() { // Arrange - var versionService = new OpenApiV2VersionService(); + var versionService = new OpenApiV2VersionService(Diagnostic); var externalResource = "externalSchema.json"; var id = "externalPathSegment1/externalPathSegment2/externalPathSegment3"; var input = $"{externalResource}#/{id}"; @@ -33,7 +39,7 @@ public void ParseExternalReference() public void ParseLocalParameterReference() { // Arrange - var versionService = new OpenApiV2VersionService(); + var versionService = new OpenApiV2VersionService(Diagnostic); var referenceType = ReferenceType.Parameter; var id = "parameterId"; var input = $"#/parameters/{id}"; @@ -51,7 +57,7 @@ public void ParseLocalParameterReference() public void ParseLocalSchemaReference() { // Arrange - var versionService = new OpenApiV2VersionService(); + var versionService = new OpenApiV2VersionService(Diagnostic); var referenceType = ReferenceType.Schema; var id = "parameterId"; var input = $"#/definitions/{id}"; @@ -69,7 +75,7 @@ public void ParseLocalSchemaReference() public void ParseTagReference() { // Arrange - var versionService = new OpenApiV2VersionService(); + var versionService = new OpenApiV2VersionService(Diagnostic); var referenceType = ReferenceType.Tag; var id = "tagId"; var input = $"{id}"; @@ -87,7 +93,7 @@ public void ParseTagReference() public void ParseSecuritySchemeReference() { // Arrange - var versionService = new OpenApiV2VersionService(); + var versionService = new OpenApiV2VersionService(Diagnostic); var referenceType = ReferenceType.SecurityScheme; var id = "securitySchemeId"; var input = $"{id}"; diff --git a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs index 04debfd7d..c4e88998e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/ReferenceService/ConvertToOpenApiReferenceV3Tests.cs @@ -10,12 +10,20 @@ namespace Microsoft.OpenApi.Readers.Tests { public class ConvertToOpenApiReferenceV3Tests { + public OpenApiDiagnostic Diagnostic { get; } + + public ConvertToOpenApiReferenceV3Tests() + { + Diagnostic = new OpenApiDiagnostic(); + } + + [Fact] public void ParseExternalReference() { // Arrange - var versionService = new OpenApiV3VersionService(); + var versionService = new OpenApiV3VersionService(Diagnostic); var externalResource = "externalSchema.json"; var id = "/externalPathSegment1/externalPathSegment2/externalPathSegment3"; var input = $"{externalResource}#{id}"; @@ -33,7 +41,7 @@ public void ParseExternalReference() public void ParseLocalParameterReference() { // Arrange - var versionService = new OpenApiV3VersionService(); + var versionService = new OpenApiV3VersionService(Diagnostic); var referenceType = ReferenceType.Parameter; var id = "parameterId"; var input = $"#/components/parameters/{id}"; @@ -51,7 +59,7 @@ public void ParseLocalParameterReference() public void ParseLocalSchemaReference() { // Arrange - var versionService = new OpenApiV3VersionService(); + var versionService = new OpenApiV3VersionService(Diagnostic); var referenceType = ReferenceType.Schema; var id = "schemaId"; var input = $"#/components/schemas/{id}"; @@ -69,7 +77,7 @@ public void ParseLocalSchemaReference() public void ParseTagReference() { // Arrange - var versionService = new OpenApiV3VersionService(); + var versionService = new OpenApiV3VersionService(Diagnostic); var referenceType = ReferenceType.Tag; var id = "tagId"; var input = $"{id}"; @@ -87,7 +95,7 @@ public void ParseTagReference() public void ParseSecuritySchemeReference() { // Arrange - var versionService = new OpenApiV3VersionService(); + var versionService = new OpenApiV3VersionService(Diagnostic); var referenceType = ReferenceType.SecurityScheme; var id = "securitySchemeId"; var input = $"{id}";