diff --git a/src/Microsoft.OpenApi.Readers/Exceptions/OpenApiReaderException.cs b/src/Microsoft.OpenApi.Readers/Exceptions/OpenApiReaderException.cs new file mode 100644 index 000000000..25aac4978 --- /dev/null +++ b/src/Microsoft.OpenApi.Readers/Exceptions/OpenApiReaderException.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; + +namespace Microsoft.OpenApi.Readers.Exceptions +{ + /// + /// Defines an exception indicating OpenAPI Reader encountered an issue while reading. + /// + [Serializable] + public class OpenApiReaderException : Exception + { + /// + /// Initializes the class. + /// + public OpenApiReaderException() { } + + /// + /// Initializes the class with a custom message. + /// + /// Plain text error message for this exception. + public OpenApiReaderException(string message) : base(message) { } + + /// + /// Initializes the class with a custom message and inner exception. + /// + /// Plain text error message for this exception. + /// Inner exception that caused this exception to be thrown. + public OpenApiReaderException(string message, Exception innerException) : base(message, innerException) { } + } +} \ No newline at end of file diff --git a/src/Microsoft.OpenApi.Readers/Exceptions/OpenApiUnsupportedSpecVersionException.cs b/src/Microsoft.OpenApi.Readers/Exceptions/OpenApiUnsupportedSpecVersionException.cs new file mode 100644 index 000000000..84faf9d4e --- /dev/null +++ b/src/Microsoft.OpenApi.Readers/Exceptions/OpenApiUnsupportedSpecVersionException.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using System; +using System.Globalization; + +namespace Microsoft.OpenApi.Readers.Exceptions +{ + /// + /// Defines an exception indicating OpenAPI Reader encountered an unsupported specification version while reading. + /// + [Serializable] + public class OpenApiUnsupportedSpecVersionException : OpenApiReaderException + { + const string messagePattern = "OpenAPI specification version {0} is not supported."; + + /// + /// Initializes the class with a specification version. + /// + /// Version that caused this exception to be thrown. + public OpenApiUnsupportedSpecVersionException(string specificationVersion) + : base(string.Format(CultureInfo.InvariantCulture, messagePattern, specificationVersion)) + { + if (string.IsNullOrWhiteSpace(specificationVersion)) + { + throw new ArgumentException("Value cannot be null or white space.", nameof(specificationVersion)); + } + + this.SpecificationVersion = specificationVersion; + } + + /// + /// Initializes the class with a specification version and + /// inner exception. + /// + /// Version that caused this exception to be thrown. + /// Inner exception that caused this exception to be thrown. + public OpenApiUnsupportedSpecVersionException(string specificationVersion, Exception innerException) + : base(string.Format(CultureInfo.InvariantCulture, messagePattern, specificationVersion), innerException) + { + if (string.IsNullOrWhiteSpace(specificationVersion)) + { + throw new ArgumentException("Value cannot be null or white space.", nameof(specificationVersion)); + } + + this.SpecificationVersion = specificationVersion; + } + + /// + /// The unsupported specification version. + /// + public string SpecificationVersion { get; } + } +} \ No newline at end of file diff --git a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj index 687ea1b5b..84edc097a 100644 --- a/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj +++ b/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj @@ -10,7 +10,7 @@ Microsoft Microsoft.OpenApi.Readers Microsoft.OpenApi.Readers - 1.0.0-beta010 + 1.0.0-beta011 OpenAPI.NET Readers for JSON and YAML documents © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/src/Microsoft.OpenApi.Readers/ParsingContext.cs b/src/Microsoft.OpenApi.Readers/ParsingContext.cs index f47112cdb..400aad511 100644 --- a/src/Microsoft.OpenApi.Readers/ParsingContext.cs +++ b/src/Microsoft.OpenApi.Readers/ParsingContext.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.OpenApi.Interfaces; using Microsoft.OpenApi.Models; +using Microsoft.OpenApi.Readers.Exceptions; using Microsoft.OpenApi.Readers.Interface; using Microsoft.OpenApi.Readers.ParseNodes; using Microsoft.OpenApi.Readers.V2; @@ -41,26 +42,24 @@ internal OpenApiDocument Parse(YamlDocument yamlDocument, OpenApiDiagnostic diag OpenApiDocument doc; - if (inputVersion == "2.0") + switch (inputVersion) { - VersionService = new OpenApiV2VersionService(); - doc = this.VersionService.LoadDocument(this.RootNode); - diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi2_0; - } - else if (inputVersion.StartsWith("3.0.")) - { - this.VersionService = new OpenApiV3VersionService(); - doc = this.VersionService.LoadDocument(this.RootNode); - diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi3_0; - } - else - { - // If version number is not recognizable, - // our best effort will try to deserialize the document to V3. - this.VersionService = new OpenApiV3VersionService(); - doc = this.VersionService.LoadDocument(this.RootNode); - diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi3_0; + case string version when version == "2.0": + VersionService = new OpenApiV2VersionService(); + doc = this.VersionService.LoadDocument(this.RootNode); + diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi2_0; + break; + + case string version when version.StartsWith("3.0"): + this.VersionService = new OpenApiV3VersionService(); + doc = this.VersionService.LoadDocument(this.RootNode); + diagnostic.SpecificationVersion = OpenApiSpecVersion.OpenApi3_0; + break; + + default: + throw new OpenApiUnsupportedSpecVersionException(inputVersion); } + return doc; } @@ -81,7 +80,7 @@ private static string GetVersion(RootNode rootNode) return versionNode?.GetScalarValue(); } - private void ComputeTags(List tags, Func loadTag ) + private void ComputeTags(List tags, Func loadTag) { // Precompute the tags array so that each tag reference does not require a new deserialization. var tagListPointer = new JsonPointer("#/tags"); diff --git a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj index e7a5e7f68..e44c3ca0e 100644 --- a/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj +++ b/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj @@ -10,7 +10,7 @@ Microsoft Microsoft.OpenApi Microsoft.OpenApi - 1.0.0-beta010 + 1.0.0-beta011 .NET models with JSON and YAML writers for OpenAPI specification © Microsoft Corporation. All rights reserved. OpenAPI .NET diff --git a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj index f4b89b493..0c14da164 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj +++ b/test/Microsoft.OpenApi.Readers.Tests/Microsoft.OpenApi.Readers.Tests.csproj @@ -13,6 +13,9 @@ ..\..\src\Microsoft.OpenApi.snk + + Never + Never diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/Samples/unsupported.v1.yaml b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/Samples/unsupported.v1.yaml new file mode 100644 index 000000000..f205f2d2b --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/Samples/unsupported.v1.yaml @@ -0,0 +1,8 @@ +swagger: 1.0.0 +info: + title: This is a simple example + version: 1.0.0 +host: example.org +basePath: /api +schemes: ["http", "https"] +paths: {} diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/UnsupportedSpecVersionTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/UnsupportedSpecVersionTests.cs new file mode 100644 index 000000000..f20529115 --- /dev/null +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/UnsupportedSpecVersionTests.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +using FluentAssertions; +using Microsoft.OpenApi.Readers.Exceptions; +using Xunit; + +namespace Microsoft.OpenApi.Readers.Tests.OpenApiReaderTests +{ + [Collection("DefaultSettings")] + public class UnsupportedSpecVersionTests + { + [Fact] + public void ThrowOpenApiUnsupportedSpecVersionException() + { + using (var stream = Resources.GetStream("OpenApiReaderTests/Samples/unsupported.v1.yaml")) + { + try + { + new OpenApiStreamReader().Read(stream, out var diagnostic); + } + catch (OpenApiUnsupportedSpecVersionException exception) + { + exception.SpecificationVersion.Should().Be("1.0.0"); + } + } + } + } +} \ No newline at end of file