Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Use loading pattern #1553

Merged
merged 48 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
90dc7fc
Move loading code to core lib and adjust namespaces
MaggieKimani1 Feb 5, 2024
ed1e02f
Create a static factory for loading/parsing an OpenAPI model object
MaggieKimani1 Feb 5, 2024
dee116c
Use static methods to call the factory and load up a document
MaggieKimani1 Feb 5, 2024
27755ec
Create a reader interface and the implementation for different Open A…
MaggieKimani1 Feb 5, 2024
9103bb8
Adjust namespaces and usings
MaggieKimani1 Feb 5, 2024
ce1c28d
Create a static registry class to register different format providers
MaggieKimani1 Feb 5, 2024
2e12d5d
Update constants
MaggieKimani1 Feb 5, 2024
5d89270
Clean up usings and namespaces
MaggieKimani1 Feb 5, 2024
96e914a
Remove unnecessary usings
MaggieKimani1 Feb 6, 2024
a507c95
copy output to directory
MaggieKimani1 Feb 6, 2024
7ecb9f2
Register reader
MaggieKimani1 Feb 7, 2024
4382dbb
Address CodeQL concerns
MaggieKimani1 Feb 7, 2024
67c3501
Create a static Http client instance for reuse
MaggieKimani1 Feb 7, 2024
3f8238c
More CodeQL fixes
MaggieKimani1 Feb 7, 2024
b3b458b
Refactor access modifier
MaggieKimani1 Feb 7, 2024
d3a1f2b
Add documentation
MaggieKimani1 Feb 7, 2024
2eb9852
Use default settings if none are passed
MaggieKimani1 Feb 8, 2024
36de7b8
Update API interface
MaggieKimani1 Feb 8, 2024
bcafdec
Update error message
MaggieKimani1 Feb 8, 2024
2f3b42c
Make format a required param when dealing with streams
MaggieKimani1 Feb 8, 2024
ba3e767
Add documentation and explicit error message
MaggieKimani1 Feb 8, 2024
12aec9a
More cleanup
MaggieKimani1 Feb 8, 2024
7151d66
Clean up
MaggieKimani1 Feb 8, 2024
5b17f37
Clean up
MaggieKimani1 Feb 8, 2024
ab906e3
Add support to enable direct loading of model objects
MaggieKimani1 Feb 12, 2024
c5533ff
Code cleanup and update public API interface
MaggieKimani1 Feb 12, 2024
25556cd
Adds a loader for the discriminator object
MaggieKimani1 Feb 12, 2024
70768e1
Update tests to validate the load pattern
MaggieKimani1 Feb 12, 2024
3724eeb
Implement PR feedback
MaggieKimani1 Feb 13, 2024
242428a
Return the media type without extracting the file format
MaggieKimani1 Feb 13, 2024
957ca8d
Remove the static load methods from the models to prevent expanding t…
MaggieKimani1 Feb 15, 2024
575a48a
Update hidi to use the Load/Parse methods
MaggieKimani1 Feb 15, 2024
18a152e
Simplifies code base by removing unnecessary code and delegating func…
MaggieKimani1 Feb 15, 2024
480310e
Set the JsonReader as the default reader and use it in the YamlReader…
MaggieKimani1 Feb 15, 2024
782b2ec
Remove depracated files
MaggieKimani1 Feb 15, 2024
298b3e9
Code refactoring
MaggieKimani1 Feb 19, 2024
487b1f9
Remove depracated interface
MaggieKimani1 Feb 19, 2024
374fe98
Fix failing tests
MaggieKimani1 Feb 19, 2024
895b48b
Update API interface
MaggieKimani1 Feb 19, 2024
77f45b0
Remove unnecessary usings
MaggieKimani1 Feb 19, 2024
085c1f1
Auto-register the YamlReader in Hidi
MaggieKimani1 Feb 20, 2024
889fcde
Remove unnecessary usings
MaggieKimani1 Feb 20, 2024
fcbabd4
Add the SpecVersionAttribute decorator to the custom Extensions keywo…
MaggieKimani1 Feb 28, 2024
538013d
Clean up
MaggieKimani1 Feb 28, 2024
2e5c5f8
If supplied, use the input OpenApi format as the output file extensio…
MaggieKimani1 Feb 28, 2024
951aadb
Update API interface
MaggieKimani1 Mar 26, 2024
c8acd59
Resolve merge conflicts
MaggieKimani1 Mar 26, 2024
2583b89
Clean up tests
MaggieKimani1 Mar 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions src/Microsoft.OpenApi.Hidi/OpenApiService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
Expand Down Expand Up @@ -29,6 +29,7 @@
using Microsoft.OpenApi.Hidi.Utilities;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.OData;
using Microsoft.OpenApi.Reader;
using Microsoft.OpenApi.Readers;
using Microsoft.OpenApi.Services;
using Microsoft.OpenApi.Writers;
Expand All @@ -38,6 +39,12 @@ namespace Microsoft.OpenApi.Hidi
{
internal static class OpenApiService
{
static OpenApiService()
{
OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader());
OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader());
}

/// <summary>
/// Implementation of the transform command
/// </summary>
Expand All @@ -52,7 +59,10 @@ public static async Task TransformOpenApiDocument(HidiOptions options, ILogger l
{
if (options.Output == null)
{
var inputExtension = GetInputPathExtension(options.OpenApi, options.Csdl);
#pragma warning disable CA1308 // Normalize strings to uppercase
var inputExtension = string.Concat(".", options.OpenApiFormat?.GetDisplayName().ToLowerInvariant())
?? GetInputPathExtension(options.OpenApi, options.Csdl);
#pragma warning restore CA1308 // Normalize strings to uppercase
options.Output = new($"./output{inputExtension}");
};

Expand Down Expand Up @@ -85,7 +95,8 @@ public static async Task TransformOpenApiDocument(HidiOptions options, ILogger l
}

// Load OpenAPI document
var document = await GetOpenApi(options, logger, options.MetadataVersion, cancellationToken).ConfigureAwait(false);
var format = OpenApiModelFactory.GetFormat(options.OpenApi);
var document = await GetOpenApi(options, format, logger, options.MetadataVersion, cancellationToken).ConfigureAwait(false);

if (options.FilterOptions != null)
{
Expand Down Expand Up @@ -212,7 +223,7 @@ private static void WriteOpenApi(HidiOptions options, OpenApiFormat openApiForma
}

// Get OpenAPI document either from OpenAPI or CSDL
private static async Task<OpenApiDocument> GetOpenApi(HidiOptions options, ILogger logger, string? metadataVersion = null, CancellationToken cancellationToken = default)
private static async Task<OpenApiDocument> GetOpenApi(HidiOptions options, string format, ILogger logger, string? metadataVersion = null, CancellationToken cancellationToken = default)
{
OpenApiDocument document;
Stream stream;
Expand All @@ -233,7 +244,7 @@ private static async Task<OpenApiDocument> GetOpenApi(HidiOptions options, ILogg
await stream.DisposeAsync().ConfigureAwait(false);
}

document = await ConvertCsdlToOpenApi(filteredStream ?? stream, metadataVersion, options.SettingsConfig, cancellationToken).ConfigureAwait(false);
document = await ConvertCsdlToOpenApi(filteredStream ?? stream, format, metadataVersion, options.SettingsConfig, cancellationToken).ConfigureAwait(false);
stopwatch.Stop();
logger.LogTrace("{Timestamp}ms: Generated OpenAPI with {Paths} paths.", stopwatch.ElapsedMilliseconds, document.Paths.Count);
}
Expand Down Expand Up @@ -368,14 +379,16 @@ private static async Task<ReadResult> ParseOpenApi(string openApiFile, bool inli
{
stopwatch.Start();

result = await new OpenApiStreamReader(new()
{
var settings = new OpenApiReaderSettings
{
LoadExternalRefs = inlineExternal,
BaseUrl = openApiFile.StartsWith("http", StringComparison.OrdinalIgnoreCase) ?
new(openApiFile) :
new Uri("file://" + new FileInfo(openApiFile).DirectoryName + Path.DirectorySeparatorChar)
}
).ReadAsync(stream, cancellationToken).ConfigureAwait(false);
};

var format = OpenApiModelFactory.GetFormat(openApiFile);
result = await OpenApiDocument.LoadAsync(stream, format, settings, cancellationToken).ConfigureAwait(false);

logger.LogTrace("{Timestamp}ms: Completed parsing.", stopwatch.ElapsedMilliseconds);

Expand All @@ -391,15 +404,15 @@ private static async Task<ReadResult> ParseOpenApi(string openApiFile, bool inli
/// </summary>
/// <param name="csdl">The CSDL stream.</param>
/// <returns>An OpenAPI document.</returns>
public static async Task<OpenApiDocument> ConvertCsdlToOpenApi(Stream csdl, string? metadataVersion = null, IConfiguration? settings = null, CancellationToken token = default)
public static async Task<OpenApiDocument> ConvertCsdlToOpenApi(Stream csdl, string format, string? metadataVersion = null, IConfiguration? settings = null, CancellationToken token = default)
{
using var reader = new StreamReader(csdl);
var csdlText = await reader.ReadToEndAsync(token).ConfigureAwait(false);
var edmModel = CsdlReader.Parse(XElement.Parse(csdlText).CreateReader());
settings ??= SettingsUtilities.GetConfiguration();

var document = edmModel.ConvertToOpenApi(SettingsUtilities.GetOpenApiConvertSettings(settings, metadataVersion));
document = FixReferences(document);
document = FixReferences(document, format);

return document;
}
Expand All @@ -409,14 +422,15 @@ public static async Task<OpenApiDocument> ConvertCsdlToOpenApi(Stream csdl, stri
/// </summary>
/// <param name="document"> The converted OpenApiDocument.</param>
/// <returns> A valid OpenApiDocument instance.</returns>
public static OpenApiDocument FixReferences(OpenApiDocument document)
public static OpenApiDocument FixReferences(OpenApiDocument document, string format)
{
// This method is only needed because the output of ConvertToOpenApi isn't quite a valid OpenApiDocument instance.
// So we write it out, and read it back in again to fix it up.

var sb = new StringBuilder();
document.SerializeAsV3(new OpenApiYamlWriter(new StringWriter(sb)));
var doc = new OpenApiStringReader().Read(sb.ToString(), out _);

var doc = OpenApiDocument.Parse(sb.ToString(), format).OpenApiDocument;

return doc;
}
Expand Down Expand Up @@ -564,7 +578,8 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl
throw new ArgumentException("Please input a file path or URL");
}

var document = await GetOpenApi(options, logger, null, cancellationToken).ConfigureAwait(false);
var format = OpenApiModelFactory.GetFormat(options.OpenApi);
var document = await GetOpenApi(options, format, logger, null, cancellationToken).ConfigureAwait(false);

using (logger.BeginScope("Creating diagram"))
{
Expand Down Expand Up @@ -725,7 +740,8 @@ internal static async Task PluginManifest(HidiOptions options, ILogger logger, C
}

// Load OpenAPI document
var document = await GetOpenApi(options, logger, options.MetadataVersion, cancellationToken).ConfigureAwait(false);
var format = OpenApiModelFactory.GetFormat(options.OpenApi);
var document = await GetOpenApi(options, format, logger, options.MetadataVersion, cancellationToken).ConfigureAwait(false);

cancellationToken.ThrowIfCancellationRequested();

Expand Down
23 changes: 0 additions & 23 deletions src/Microsoft.OpenApi.Readers/Interface/IOpenApiReader.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
<AssemblyOriginatorKeyFile>..\Microsoft.OpenApi.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
<Compile Remove="V31\**" />
<EmbeddedResource Remove="V31\**" />
<None Remove="V31\**" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="JsonSchema.Net" Version="4.1.5" />
<PackageReference Include="JsonSchema.Net.OpenApi" Version="1.1.0" />
Expand Down
93 changes: 0 additions & 93 deletions src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs

This file was deleted.

45 changes: 0 additions & 45 deletions src/Microsoft.OpenApi.Readers/OpenApiStringReader.cs

This file was deleted.

Loading
Loading