Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
MaggieKimani1 committed Oct 7, 2024
1 parent 19463dd commit 3c64451
Show file tree
Hide file tree
Showing 32 changed files with 917 additions and 283 deletions.
12 changes: 6 additions & 6 deletions src/Microsoft.OpenApi.Hidi/OpenApiService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static async Task TransformOpenApiDocumentAsync(HidiOptions options, ILog

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

if (options.FilterOptions != null)
{
Expand Down Expand Up @@ -225,7 +225,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, string format, ILogger logger, string? metadataVersion = null, CancellationToken cancellationToken = default)
private static async Task<OpenApiDocument> GetOpenApiAsync(HidiOptions options, string format, ILogger logger, string? metadataVersion = null, CancellationToken cancellationToken = default)
{
OpenApiDocument document;
Stream stream;
Expand All @@ -246,7 +246,7 @@ private static async Task<OpenApiDocument> GetOpenApi(HidiOptions options, strin
await stream.DisposeAsync().ConfigureAwait(false);
}

document = await ConvertCsdlToOpenApi(filteredStream ?? stream, format, metadataVersion, options.SettingsConfig, cancellationToken).ConfigureAwait(false);
document = await ConvertCsdlToOpenApiAsync(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 @@ -413,7 +413,7 @@ private static async Task<ReadResult> ParseOpenApiAsync(string openApiFile, bool
/// </summary>
/// <param name="csdl">The CSDL stream.</param>
/// <returns>An OpenAPI document.</returns>
public static async Task<OpenApiDocument> ConvertCsdlToOpenApi(Stream csdl, string format, string? metadataVersion = null, IConfiguration? settings = null, CancellationToken token = default)
public static async Task<OpenApiDocument> ConvertCsdlToOpenApiAsync(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);
Expand Down Expand Up @@ -588,7 +588,7 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl
}

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

using (logger.BeginScope("Creating diagram"))
{
Expand Down Expand Up @@ -750,7 +750,7 @@ internal static async Task PluginManifestAsync(HidiOptions options, ILogger logg

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

cancellationToken.ThrowIfCancellationRequested();

Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.OpenApi/Microsoft.OpenApi.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>Latest</LangVersion>
Expand All @@ -22,6 +22,7 @@
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="17.11.20" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>

Expand Down
5 changes: 3 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiMediaType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Nodes;
using Microsoft.OpenApi.Helpers;
using Microsoft.OpenApi.Interfaces;
Expand Down Expand Up @@ -129,14 +130,14 @@ private static void SerializeExamples(IOpenApiWriter writer, IDictionary<string,
* Check if there is any example with an empty array as its value and set the flag `hasEmptyArray` to true
* */
var hasEmptyArray = examples.Values.Any( static example =>
example.Value is OpenApiArray arr && arr.Count == 0
example.Value is JsonArray arr && arr.Count == 0
);

if (hasEmptyArray)
{
writer.WritePropertyName(OpenApiConstants.Examples);
writer.WriteStartObject();
foreach (var kvp in examples.Where(static kvp => kvp.Value.Value is OpenApiArray arr && arr.Count == 0))
foreach (var kvp in examples.Where(static kvp => kvp.Value.Value is JsonArray arr && arr.Count == 0))
{
writer.WritePropertyName(kvp.Key);
writer.WriteStartObject();
Expand Down
7 changes: 5 additions & 2 deletions src/Microsoft.OpenApi/Models/OpenApiSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.OpenApi.Models
/// <summary>
/// The Schema Object allows the definition of input and output data types.
/// </summary>
public class OpenApiSchema : IOpenApiExtensible, IOpenApiReferenceable, IOpenApiSerializable
public class OpenApiSchema : IOpenApiAnnotatable, IOpenApiExtensible, IOpenApiReferenceable, IOpenApiSerializable
{
private JsonNode _example;
private JsonNode _default;
Expand Down Expand Up @@ -888,7 +888,10 @@ private void DowncastTypeArrayToV2OrV3(string[] array, IOpenApiWriter writer, Op
// Find the non-null value and write it out
var nonNullValue = array.First(v => v != OpenApiConstants.Null);
writer.WriteProperty(OpenApiConstants.Type, nonNullValue);
writer.WriteProperty(nullableProp, true);
if (!Nullable)
{
writer.WriteProperty(nullableProp, true);
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public async Task<ReadResult> ReadAsync(JsonNode jsonNode,

if (settings.LoadExternalRefs)
{
var diagnosticExternalRefs = await LoadExternalRefs(document, cancellationToken, settings, format);
var diagnosticExternalRefs = await LoadExternalRefsAsync(document, cancellationToken, settings, format);
// Merge diagnostics of external reference
if (diagnosticExternalRefs != null)
{
Expand Down Expand Up @@ -189,7 +189,7 @@ private JsonNode LoadJsonNodes(TextReader input)
return nodes;
}

private async Task<OpenApiDiagnostic> LoadExternalRefs(OpenApiDocument document, CancellationToken cancellationToken, OpenApiReaderSettings settings, string format = null)
private async Task<OpenApiDiagnostic> LoadExternalRefsAsync(OpenApiDocument document, CancellationToken cancellationToken, OpenApiReaderSettings settings, string format = null)
{
// Create workspace for all documents to live in.
var baseUrl = settings.BaseUrl ?? new Uri(OpenApiConstants.BaseRegistryUri);
Expand Down
44 changes: 35 additions & 9 deletions src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading.Tasks;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Microsoft.VisualStudio.Threading;

namespace Microsoft.OpenApi.Reader
{
Expand All @@ -19,6 +20,8 @@ namespace Microsoft.OpenApi.Reader
public static class OpenApiModelFactory
{
private static readonly HttpClient _httpClient = new();
private static readonly JoinableTaskContext _joinableTaskContext = new();
private static readonly JoinableTaskFactory _joinableTaskFactory = new(_joinableTaskContext);

static OpenApiModelFactory()
{
Expand All @@ -33,7 +36,7 @@ static OpenApiModelFactory()
/// <returns>An OpenAPI document instance.</returns>
public static ReadResult Load(string url, OpenApiReaderSettings settings = null)
{
return LoadAsync(url, settings).GetAwaiter().GetResult();
return _joinableTaskFactory.Run(async () => await LoadAsync(url, settings));
}

/// <summary>
Expand All @@ -49,7 +52,9 @@ public static ReadResult Load(Stream stream,
{
settings ??= new OpenApiReaderSettings();

var result = LoadAsync(stream, format, settings).GetAwaiter().GetResult();
// Run the async method synchronously using JoinableTaskFactory
var result = _joinableTaskFactory.Run(async () => await LoadAsync(stream, format, settings));

if (!settings.LeaveStreamOpen)
{
stream.Dispose();
Expand All @@ -69,7 +74,9 @@ public static ReadResult Load(TextReader input,
string format,
OpenApiReaderSettings settings = null)
{
return LoadAsync(input, format, settings).GetAwaiter().GetResult();
// Run the async method synchronously using JoinableTaskFactory
var result = _joinableTaskFactory.Run(async () => await LoadAsync(input, format, settings));
return result;
}

/// <summary>
Expand All @@ -81,7 +88,7 @@ public static ReadResult Load(TextReader input,
public static async Task<ReadResult> LoadAsync(string url, OpenApiReaderSettings settings = null)
{
var format = GetFormat(url);
var stream = await GetStream(url);
var stream = await GetStreamAsync(url);
return await LoadAsync(stream, format, settings);
}

Expand Down Expand Up @@ -145,7 +152,24 @@ public static ReadResult Parse(string input,
format ??= OpenApiConstants.Json;
settings ??= new OpenApiReaderSettings();
using var reader = new StringReader(input);
return LoadAsync(reader, format, settings).GetAwaiter().GetResult();

return _joinableTaskFactory.Run(async () => await ParseAsync(input, reader, format, settings));
}

/// <summary>
/// An Async method to prevent synchornously blocking the calling thread.
/// </summary>
/// <param name="input"></param>
/// <param name="reader"></param>
/// <param name="format"></param>
/// <param name="settings"></param>
/// <returns></returns>
public static async Task<ReadResult> ParseAsync(string input,
StringReader reader,
string format = null,
OpenApiReaderSettings settings = null)
{
return await LoadAsync(reader, format, settings);
}

/// <summary>
Expand Down Expand Up @@ -183,7 +207,9 @@ public static T Load<T>(string url, OpenApiSpecVersion version, out OpenApiDiagn
{
var format = GetFormat(url);
settings ??= new OpenApiReaderSettings();
var stream = GetStream(url).GetAwaiter().GetResult();

var stream = _joinableTaskFactory.Run(async () => await GetStreamAsync(url));

return Load<T>(stream, version, format, out diagnostic, settings);
}

Expand Down Expand Up @@ -227,7 +253,8 @@ private static string GetContentType(string url)
{
if (!string.IsNullOrEmpty(url))
{
var response = _httpClient.GetAsync(url).GetAwaiter().GetResult();
var response = _joinableTaskFactory.Run(async () => await _httpClient.GetAsync(url));
//var response = _httpClient.GetAsync(url).GetAwaiter().GetResult();

Check warning on line 257 in src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs

View workflow job for this annotation

GitHub Actions / Build

Remove this commented out code. (https://rules.sonarsource.com/csharp/RSPEC-125)
var mediaType = response.Content.Headers.ContentType.MediaType;
return mediaType.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).First();
}
Expand Down Expand Up @@ -260,7 +287,7 @@ public static string GetFormat(string url)
return null;
}

private static async Task<Stream> GetStream(string url)
private static async Task<Stream> GetStreamAsync(string url)
{
Stream stream;
if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -297,6 +324,5 @@ SecurityException or

return stream;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public DefaultStreamLoader(Uri baseUrl)
{
this.baseUrl = baseUrl;
}
/// <inheritdoc/>

[Obsolete]
[EditorBrowsable(EditorBrowsableState.Never)]
Expand Down
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 Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -232,7 +232,7 @@ public void CopiesOverAllReferencedComponentsToTheSubsetDocumentCorrectly()

// Act
using var stream = File.OpenRead(filePath);
var doc = new OpenApiStreamReader().Read(stream, out var diagnostic);
var doc = OpenApiDocument.Load(stream, "yaml").OpenApiDocument;

var predicate = OpenApiFilterService.CreatePredicate(operationIds: operationIds);
var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(doc, predicate);
Expand Down
76 changes: 2 additions & 74 deletions test/Microsoft.OpenApi.Hidi.Tests/Services/OpenApiServiceTests.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.CommandLine;
Expand All @@ -13,6 +13,7 @@
using Microsoft.OpenApi.OData;
using Microsoft.OpenApi.Reader;
using Microsoft.OpenApi.Readers;
using Microsoft.OpenApi.Services;
using Xunit;

namespace Microsoft.OpenApi.Hidi.Tests
Expand All @@ -27,44 +28,6 @@ public OpenApiServiceTests()
_logger = new Logger<OpenApiServiceTests>(_loggerFactory);
OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yml, new OpenApiYamlReader());
OpenApiReaderRegistry.RegisterReader(OpenApiConstants.Yaml, new OpenApiYamlReader());

[Fact]
public async Task ReturnConvertedCSDLFileAsync()
{
// Arrange
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "Todo.xml");
var fileInput = new FileInfo(filePath);
var csdlStream = fileInput.OpenRead();
// Act
var openApiDoc = await OpenApiService.ConvertCsdlToOpenApiAsync(csdlStream);
var expectedPathCount = 5;

// Assert
Assert.NotNull(openApiDoc);
Assert.NotEmpty(openApiDoc.Paths);
Assert.Equal(expectedPathCount, openApiDoc.Paths.Count);
}

[Theory]
[InlineData("Todos.Todo.UpdateTodo", null, 1)]
[InlineData("Todos.Todo.ListTodo", null, 1)]
[InlineData(null, "Todos.Todo", 5)]
public async Task ReturnFilteredOpenApiDocBasedOnOperationIdsAndInputCsdlDocumentAsync(string? operationIds, string? tags, int expectedPathCount)
{
// Arrange
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UtilityFiles", "Todo.xml");
var fileInput = new FileInfo(filePath);
var csdlStream = fileInput.OpenRead();

// Act
var openApiDoc = await OpenApiService.ConvertCsdlToOpenApiAsync(csdlStream);
var predicate = OpenApiFilterService.CreatePredicate(operationIds, tags);
var subsetOpenApiDocument = OpenApiFilterService.CreateFilteredDocument(openApiDoc, predicate);

// Assert
Assert.NotNull(subsetOpenApiDocument);
Assert.NotEmpty(subsetOpenApiDocument.Paths);
Assert.Equal(expectedPathCount, subsetOpenApiDocument.Paths.Count);
}

[Fact]
Expand Down Expand Up @@ -198,23 +161,6 @@ public async Task ShowCommandGeneratesMermaidHtmlFileWithMermaidDiagramAsync()
Assert.True(File.Exists(filePath));
}

[Fact]
public async Task ShowCommandGeneratesMermaidMarkdownFileFromCsdlWithMermaidDiagramAsync()
{
var options = new HidiOptions
{
Csdl = Path.Combine("UtilityFiles", "Todo.xml"),
CsdlFilter = "todos",
Output = new("sample.md")
};

// create a dummy ILogger instance for testing
await OpenApiService.ShowOpenApiDocumentAsync(options, _logger);

var output = await File.ReadAllTextAsync(options.Output.FullName);
Assert.Contains("graph LR", output, StringComparison.Ordinal);
}

[Fact]
public Task ThrowIfOpenApiUrlIsNotProvidedWhenValidatingAsync()
{
Expand Down Expand Up @@ -309,24 +255,6 @@ public async Task TransformCommandConvertsOpenApiWithDefaultOutputNameAsync()
Assert.NotEmpty(output);
}

[Fact]
public async Task TransformCommandConvertsCsdlWithDefaultOutputNameAsync()
{
var options = new HidiOptions
{
Csdl = Path.Combine("UtilityFiles", "Todo.xml"),
CleanOutput = true,
TerseOutput = false,
InlineLocal = false,
InlineExternal = false,
};
// create a dummy ILogger instance for testing
await OpenApiService.TransformOpenApiDocumentAsync(options, _logger);

var output = await File.ReadAllTextAsync("output.yml");
Assert.NotEmpty(output);
}

[Fact]
public async Task TransformCommandConvertsOpenApiWithDefaultOutputNameAndSwitchFormatAsync()
{
Expand Down
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 @@ -64,8 +64,8 @@ public async Task StreamShouldReadWhenInitializedAsync()
var stream = await httpClient.GetStreamAsync("master/examples/v3.0/petstore.yaml");

// Read V3 as YAML
var openApiDocument = new OpenApiStreamReader().Read(stream, out var diagnostic);
Assert.NotNull(openApiDocument);
var result = OpenApiDocument.Load(stream, "yaml");
Assert.NotNull(result.OpenApiDocument);
}
}
}
Loading

0 comments on commit 3c64451

Please sign in to comment.