diff --git a/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs b/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs
index cff6dd1da..1a85e6a27 100644
--- a/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs
+++ b/src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs
@@ -19,17 +19,34 @@ namespace Microsoft.OpenApi.Readers
///
public class OpenApiYamlReader : IOpenApiReader
{
+ private const int copyBufferSize = 4096;
+
///
- public async Task ReadAsync(TextReader input,
+ public async Task ReadAsync(Stream input,
OpenApiReaderSettings settings = null,
CancellationToken cancellationToken = default)
+ {
+ if (input is MemoryStream memoryStream)
+ {
+ return Read(memoryStream, settings);
+ } else {
+ using var preparedStream = new MemoryStream();
+ await input.CopyToAsync(preparedStream, copyBufferSize, cancellationToken);
+ preparedStream.Position = 0;
+ return Read(preparedStream, settings);
+ }
+ }
+
+ ///
+ public ReadResult Read(MemoryStream input,
+ OpenApiReaderSettings settings = null)
{
JsonNode jsonNode;
// Parse the YAML text in the TextReader into a sequence of JsonNodes
try
{
- jsonNode = LoadJsonNodesFromYamlDocument(input);
+ jsonNode = LoadJsonNodesFromYamlDocument(new StreamReader(input)); // Should we leave the stream open?
}
catch (JsonException ex)
{
@@ -42,11 +59,11 @@ public async Task ReadAsync(TextReader input,
};
}
- return await ReadAsync(jsonNode, settings, cancellationToken: cancellationToken);
+ return Read(jsonNode, settings);
}
///
- public T ReadFragment(TextReader input,
+ public T ReadFragment(MemoryStream input,
OpenApiSpecVersion version,
out OpenApiDiagnostic diagnostic,
OpenApiReaderSettings settings = null) where T : IOpenApiElement
@@ -56,7 +73,7 @@ public T ReadFragment(TextReader input,
// Parse the YAML
try
{
- jsonNode = LoadJsonNodesFromYamlDocument(input);
+ jsonNode = LoadJsonNodesFromYamlDocument(new StreamReader(input));
}
catch (JsonException ex)
{
@@ -81,10 +98,10 @@ static JsonNode LoadJsonNodesFromYamlDocument(TextReader input)
return yamlDocument.ToJsonNode();
}
- ///
- public async Task ReadAsync(JsonNode jsonNode, OpenApiReaderSettings settings, string format = null, CancellationToken cancellationToken = default)
+ ///
+ public ReadResult Read(JsonNode jsonNode, OpenApiReaderSettings settings, string format = null)
{
- return await OpenApiReaderRegistry.DefaultReader.ReadAsync(jsonNode, settings, OpenApiConstants.Yaml, cancellationToken);
+ return OpenApiReaderRegistry.DefaultReader.Read(jsonNode, settings, OpenApiConstants.Yaml);
}
///
diff --git a/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs b/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs
index 5f8b1cb22..b746b857b 100644
--- a/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs
+++ b/src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs
@@ -15,33 +15,40 @@ namespace Microsoft.OpenApi.Interfaces
public interface IOpenApiReader
{
///
- /// Reads the TextReader input and parses it into an Open API document.
+ /// Async method to reads the stream and parse it into an Open API document.
///
/// The TextReader input.
/// The OpenApi reader settings.
/// Propagates notification that an operation should be cancelled.
///
- Task ReadAsync(TextReader input, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default);
+ Task ReadAsync(Stream input, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default);
+
+ ///
+ /// Provides a synchronous method to read the input memory stream and parse it into an Open API document.
+ ///
+ ///
+ ///
+ ///
+ ReadResult Read(MemoryStream input, OpenApiReaderSettings settings = null);
///
/// Parses the JsonNode input into an Open API document.
///
/// The JsonNode input.
/// The Reader settings to be used during parsing.
- /// Propagates notifications that operations should be cancelled.
/// The OpenAPI format.
///
- Task ReadAsync(JsonNode jsonNode, OpenApiReaderSettings settings, string format = null, CancellationToken cancellationToken = default);
+ ReadResult Read(JsonNode jsonNode, OpenApiReaderSettings settings, string format = null);
///
- /// Reads the TextReader input and parses the fragment of an OpenAPI description into an Open API Element.
+ /// Reads the MemoryStream and parses the fragment of an OpenAPI description into an Open API Element.
///
/// TextReader containing OpenAPI description to parse.
/// Version of the OpenAPI specification that the fragment conforms to.
/// Returns diagnostic object containing errors detected during parsing.
/// The OpenApiReader settings.
/// Instance of newly created IOpenApiElement.
- T ReadFragment(TextReader input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement;
+ T ReadFragment(MemoryStream input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement;
///
/// Reads the JsonNode input and parses the fragment of an OpenAPI description into an Open API Element.
diff --git a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
index bf8458f2c..a41e7ca6b 100644
--- a/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
+++ b/src/Microsoft.OpenApi/Models/OpenApiDocument.cs
@@ -553,27 +553,13 @@ public static ReadResult Load(string url, OpenApiReaderSettings? settings = null
/// The OpenAPI format to use during parsing.
/// The OpenApi reader settings.
///
- public static ReadResult Load(Stream stream,
+ public static ReadResult Load(MemoryStream stream,
string format,
OpenApiReaderSettings? settings = null)
{
return OpenApiModelFactory.Load(stream, format, settings);
}
- ///
- /// Reads the text reader content and parses it into an Open API document.
- ///
- /// TextReader containing OpenAPI description to parse.
- /// The OpenAPI format to use during parsing.
- /// The OpenApi reader settings.
- ///
- public static ReadResult Load(TextReader input,
- string format,
- OpenApiReaderSettings? settings = null)
- {
- return OpenApiModelFactory.Load(input, format, settings);
- }
-
///
/// Parses a local file path or Url into an Open API document.
///
@@ -598,17 +584,6 @@ public static async Task LoadAsync(Stream stream, string format, Ope
return await OpenApiModelFactory.LoadAsync(stream, format, settings, cancellationToken);
}
- ///
- /// Reads the text reader content and parses it into an Open API document.
- ///
- /// TextReader containing OpenAPI description to parse.
- /// The OpenAPI format to use during parsing.
- /// The OpenApi reader settings.
- ///
- public static async Task LoadAsync(TextReader input, string format, OpenApiReaderSettings? settings = null)
- {
- return await OpenApiModelFactory.LoadAsync(input, format, settings);
- }
///
/// Parses a string into a object.
diff --git a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs
index 27aad722e..d24d31b9d 100644
--- a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs
+++ b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs
@@ -24,14 +24,47 @@ namespace Microsoft.OpenApi.Reader
///
public class OpenApiJsonReader : IOpenApiReader
{
+
+ ///
+ /// Reads the memory stream input and parses it into an Open API document.
+ ///
+ /// TextReader containing OpenAPI description to parse.
+ /// The Reader settings to be used during parsing.
+ ///
+ public ReadResult Read(MemoryStream input,
+ OpenApiReaderSettings settings = null)
+ {
+ JsonNode jsonNode;
+ var diagnostic = new OpenApiDiagnostic();
+ settings ??= new OpenApiReaderSettings();
+
+ // Parse the JSON text in the TextReader into JsonNodes
+ try
+ {
+ jsonNode = JsonNode.Parse(input);
+ }
+ catch (JsonException ex)
+ {
+ diagnostic.Errors.Add(new OpenApiError($"#line={ex.LineNumber}", $"Please provide the correct format, {ex.Message}"));
+ return new ReadResult
+ {
+ OpenApiDocument = null,
+ OpenApiDiagnostic = diagnostic
+ };
+ }
+
+ return Read(jsonNode, settings);
+ }
+
+
///
- /// Reads the stream input and parses it into an Open API document.
+ /// Reads the stream input asynchronously and parses it into an Open API document.
///
/// TextReader containing OpenAPI description to parse.
/// The Reader settings to be used during parsing.
/// Propagates notifications that operations should be cancelled.
///
- public async Task ReadAsync(TextReader input,
+ public async Task ReadAsync(Stream input,
OpenApiReaderSettings settings = null,
CancellationToken cancellationToken = default)
{
@@ -42,7 +75,7 @@ public async Task ReadAsync(TextReader input,
// Parse the JSON text in the TextReader into JsonNodes
try
{
- jsonNode = LoadJsonNodes(input);
+ jsonNode = await JsonNode.ParseAsync(input);;
}
catch (JsonException ex)
{
@@ -54,7 +87,7 @@ public async Task ReadAsync(TextReader input,
};
}
- return await ReadAsync(jsonNode, settings, cancellationToken: cancellationToken);
+ return Read(jsonNode, settings);
}
///
@@ -63,12 +96,10 @@ public async Task ReadAsync(TextReader input,
/// The JsonNode input.
/// The Reader settings to be used during parsing.
/// The OpenAPI format.
- /// Propagates notifications that operations should be cancelled.
///
- public async Task ReadAsync(JsonNode jsonNode,
+ public ReadResult Read(JsonNode jsonNode,
OpenApiReaderSettings settings,
- string format = null,
- CancellationToken cancellationToken = default)
+ string format = null)
{
var diagnostic = new OpenApiDiagnostic();
var context = new ParsingContext(diagnostic)
@@ -84,16 +115,16 @@ public async Task ReadAsync(JsonNode jsonNode,
// Parse the OpenAPI Document
document = context.Parse(jsonNode);
- if (settings.LoadExternalRefs)
- {
- var diagnosticExternalRefs = await LoadExternalRefsAsync(document, cancellationToken, settings, format);
- // Merge diagnostics of external reference
- if (diagnosticExternalRefs != null)
- {
- diagnostic.Errors.AddRange(diagnosticExternalRefs.Errors);
- diagnostic.Warnings.AddRange(diagnosticExternalRefs.Warnings);
- }
- }
+ // if (settings.LoadExternalRefs)
+ // {
+ // var diagnosticExternalRefs = await LoadExternalRefsAsync(document, cancellationToken, settings, format);
+ // // Merge diagnostics of external reference
+ // if (diagnosticExternalRefs != null)
+ // {
+ // diagnostic.Errors.AddRange(diagnosticExternalRefs.Errors);
+ // diagnostic.Warnings.AddRange(diagnosticExternalRefs.Warnings);
+ // }
+ // }
document.SetReferenceHostDocument();
}
@@ -124,7 +155,7 @@ public async Task ReadAsync(JsonNode jsonNode,
}
///
- public T ReadFragment(TextReader input,
+ public T ReadFragment(MemoryStream input,
OpenApiSpecVersion version,
out OpenApiDiagnostic diagnostic,
OpenApiReaderSettings settings = null) where T : IOpenApiElement
@@ -134,7 +165,7 @@ public T ReadFragment(TextReader input,
// Parse the JSON
try
{
- jsonNode = LoadJsonNodes(input);
+ jsonNode = JsonNode.Parse(input);
}
catch (JsonException ex)
{
@@ -183,22 +214,6 @@ public T ReadFragment(JsonNode input,
return (T)element;
}
- private JsonNode LoadJsonNodes(TextReader input)
- {
- var nodes = JsonNode.Parse(input.ReadToEnd());
- return nodes;
- }
- private async Task 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);
- var openApiWorkSpace = new OpenApiWorkspace(baseUrl);
-
- // Load this root document into the workspace
- var streamLoader = new DefaultStreamLoader(settings.BaseUrl);
- var workspaceLoader = new OpenApiWorkspaceLoader(openApiWorkSpace, settings.CustomExternalLoader ?? streamLoader, settings);
- return await workspaceLoader.LoadAsync(new OpenApiReference() { ExternalResource = "/" }, document, format ?? OpenApiConstants.Json, null, cancellationToken);
- }
}
}
diff --git a/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs b/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs
index ddabdc6be..2554c48a5 100644
--- a/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs
+++ b/src/Microsoft.OpenApi/Reader/OpenApiModelFactory.cs
@@ -2,14 +2,18 @@
// Licensed under the MIT license.
using System;
+using System.Buffers.Text;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Reader.Services;
+using Microsoft.OpenApi.Services;
namespace Microsoft.OpenApi.Reader
{
@@ -45,15 +49,13 @@ public static ReadResult Load(string url, OpenApiReaderSettings settings = null)
/// The OpenApi reader settings.
/// The OpenAPI format.
/// An OpenAPI document instance.
- public static ReadResult Load(Stream stream,
+ public static ReadResult Load(MemoryStream stream,
string format,
OpenApiReaderSettings settings = null)
{
settings ??= new OpenApiReaderSettings();
-#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
- var result = LoadAsync(stream, format, settings).GetAwaiter().GetResult();
-#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
+ var result = InternalLoad(stream, format, settings);
if (!settings.LeaveStreamOpen)
{
@@ -63,22 +65,6 @@ public static ReadResult Load(Stream stream,
return result;
}
- ///
- /// Loads the TextReader input and parses it into an Open API document.
- ///
- /// The TextReader input.
- /// The OpenApi reader settings.
- /// The Open API format
- /// An OpenAPI document instance.
- public static ReadResult Load(TextReader input,
- string format,
- OpenApiReaderSettings settings = null)
- {
-#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
- var result = LoadAsync(input, format, settings).GetAwaiter().GetResult();
-#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
- return result;
- }
///
/// Loads the input URL and parses it into an Open API document.
@@ -87,14 +73,23 @@ public static ReadResult Load(TextReader input,
/// The OpenApi reader settings.
///
public static async Task LoadAsync(string url, OpenApiReaderSettings settings = null)
- {
+ {
+ // If url is HTTP
+ // Get the response object.
+ // Select format based on MediaType
+ // Get the stream from the response object.
+ // Load the stream.
+ // Else
+ // Determine the format from the file extension.
+ // Load the file from the local file system.
+
var format = GetFormat(url);
- var stream = await GetStreamAsync(url);
+ var stream = await GetStreamAsync(url); // Get response back and then get Content
return await LoadAsync(stream, format, settings);
}
///
- /// Loads the input stream and parses it into an Open API document.
+ /// Loads the input stream and parses it into an Open API document. If the stream is not buffered and it contains yaml, it will be buffered before parsing.
///
/// The input stream.
/// The OpenApi reader settings.
@@ -122,24 +117,7 @@ public static async Task LoadAsync(Stream input, string format, Open
}
// Use StreamReader to process the prepared stream (buffered for YAML, direct for JSON)
- using var reader = new StreamReader(preparedStream, default, true, -1, settings.LeaveStreamOpen);
- return await LoadAsync(reader, format, settings, cancellationToken);
- }
-
-
- ///
- /// Loads the TextReader input and parses it into an Open API document.
- ///
- /// The TextReader input.
- /// The Open API format
- /// The OpenApi reader settings.
- /// Propagates notification that operations should be cancelled.
- ///
- public static async Task LoadAsync(TextReader input, string format, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default)
- {
- Utils.CheckArgumentNull(format, nameof(format));
- var reader = OpenApiReaderRegistry.GetReader(format);
- return await reader.ReadAsync(input, settings, cancellationToken);
+ return await InternalLoadAsync(preparedStream, format, settings, cancellationToken);
}
///
@@ -155,29 +133,61 @@ public static ReadResult Parse(string input,
{
format ??= OpenApiConstants.Json;
settings ??= new OpenApiReaderSettings();
- using var reader = new StringReader(input);
-#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
- return ParseAsync(input, reader, format, settings).GetAwaiter().GetResult();
-#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
+ // Copy string into MemoryStream
+ var stream = new MemoryStream(Encoding.UTF8.GetBytes(input));
+
+ return InternalLoad(stream, format, settings);
}
- ///
- /// An Async method to prevent synchornously blocking the calling thread.
- ///
- ///
- ///
- ///
- ///
- ///
- public static async Task ParseAsync(string input,
- StringReader reader,
- string format = null,
- OpenApiReaderSettings settings = null)
+ private static async Task InternalLoadAsync(Stream input, string format, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default)
{
- return await LoadAsync(reader, format, settings);
+ Utils.CheckArgumentNull(format, nameof(format));
+ var reader = OpenApiReaderRegistry.GetReader(format);
+ var readResult = await reader.ReadAsync(input, settings, cancellationToken);
+
+ if (settings.LoadExternalRefs)
+ {
+ var diagnosticExternalRefs = await LoadExternalRefsAsync(readResult.OpenApiDocument, cancellationToken, settings, format);
+ // Merge diagnostics of external reference
+ if (diagnosticExternalRefs != null)
+ {
+ readResult.OpenApiDiagnostic.Errors.AddRange(diagnosticExternalRefs.Errors);
+ readResult.OpenApiDiagnostic.Warnings.AddRange(diagnosticExternalRefs.Warnings);
+ }
+ }
+
+
+ return readResult;
}
+ private static async Task 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);
+ var openApiWorkSpace = new OpenApiWorkspace(baseUrl);
+
+ // Load this root document into the workspace
+ var streamLoader = new DefaultStreamLoader(settings.BaseUrl);
+ var workspaceLoader = new OpenApiWorkspaceLoader(openApiWorkSpace, settings.CustomExternalLoader ?? streamLoader, settings);
+ return await workspaceLoader.LoadAsync(new OpenApiReference() { ExternalResource = "/" }, document, format ?? OpenApiConstants.Json, null, cancellationToken);
+ }
+
+ private static ReadResult InternalLoad(MemoryStream input, string format, OpenApiReaderSettings settings = null)
+ {
+ Utils.CheckArgumentNull(format, nameof(format));
+ if (settings.LoadExternalRefs)
+ {
+ throw new InvalidOperationException("Loading external references are not supported when using synchronous methods.");
+ }
+
+ var reader = OpenApiReaderRegistry.GetReader(format);
+ var readResult = reader.Read(input, settings);
+
+ return readResult;
+ }
+
+
///
/// Reads the input string and parses it into an Open API document.
///
@@ -195,8 +205,8 @@ public static T Parse(string input,
{
format ??= OpenApiConstants.Json;
settings ??= new OpenApiReaderSettings();
- using var reader = new StringReader(input);
- return Load(reader, version, out diagnostic, format, settings);
+ var stream = new MemoryStream(Encoding.UTF8.GetBytes(input));
+ return Load(stream, version, format, out diagnostic, settings);
}
///
@@ -218,45 +228,51 @@ public static T Load(string url, OpenApiSpecVersion version, out OpenApiDiagn
var stream = GetStreamAsync(url).GetAwaiter().GetResult();
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
- return Load(stream, version, format, out diagnostic, settings);
+ return Load(stream as MemoryStream, version, format, out diagnostic, settings);
}
+
///
- /// Reads the stream input and parses the fragment of an OpenAPI description into an Open API Element.
+ /// Reads the stream input and ensures it is buffered before passing it to the Load method.
///
///
- /// Stream containing OpenAPI description to parse.
- /// Version of the OpenAPI specification that the fragment conforms to.
+ ///
+ ///
///
- /// Returns diagnostic object containing errors detected during parsing.
- /// The OpenApiReader settings.
- /// Instance of newly created IOpenApiElement.
- /// The OpenAPI element.
+ ///
+ ///
+ ///
public static T Load(Stream input, OpenApiSpecVersion version, string format, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement
{
- format ??= OpenApiConstants.Json;
- using var reader = new StreamReader(input);
- return Load(reader, version, out diagnostic, format, settings);
+ if (input is MemoryStream memoryStream)
+ {
+ return Load(memoryStream, version, format, out diagnostic, settings);
+ } else {
+ memoryStream = new MemoryStream();
+ input.CopyTo(memoryStream);
+ memoryStream.Position = 0;
+ return Load(memoryStream, version, format, out diagnostic, settings);
+ }
}
+
///
- /// Reads the TextReader input and parses the fragment of an OpenAPI description into an Open API Element.
+ /// Reads the stream input and parses the fragment of an OpenAPI description into an Open API Element.
///
///
- /// TextReader containing OpenAPI description to parse.
+ /// Stream containing OpenAPI description to parse.
/// Version of the OpenAPI specification that the fragment conforms to.
- /// The OpenAPI format.
+ ///
/// Returns diagnostic object containing errors detected during parsing.
/// The OpenApiReader settings.
/// Instance of newly created IOpenApiElement.
/// The OpenAPI element.
- public static T Load(TextReader input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, string format, OpenApiReaderSettings settings = null) where T : IOpenApiElement
+ public static T Load(MemoryStream input, OpenApiSpecVersion version, string format, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement
{
format ??= OpenApiConstants.Json;
return OpenApiReaderRegistry.GetReader(format).ReadFragment(input, version, out diagnostic, settings);
}
-
private static string GetContentType(string url)
{
if (!string.IsNullOrEmpty(url))
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs
index 967bb0f3e..e591ad6e4 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
+using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json.Nodes;
@@ -18,6 +19,14 @@ public class OpenApiSchemaTests
{
private const string SampleFolderPath = "V31Tests/Samples/OpenApiSchema/";
+
+ public MemoryStream GetMemoryStream(string fileName)
+ {
+ var filePath = Path.Combine(SampleFolderPath, fileName);
+ var fileBytes = File.ReadAllBytes(filePath);
+ return new MemoryStream(fileBytes);
+ }
+
public OpenApiSchemaTests()
{
OpenApiReaderRegistry.RegisterReader("yaml", new OpenApiYamlReader());
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs
index 6556ade48..bcbc6a02a 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDiscriminatorTests.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using System.IO;
+using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Reader;
@@ -20,13 +21,16 @@ public OpenApiDiscriminatorTests()
}
[Fact]
- public void ParseBasicDiscriminatorShouldSucceed()
+ public async Task ParseBasicDiscriminatorShouldSucceed()
{
// Arrange
using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "basicDiscriminator.yaml"));
+ // Copy stream to MemoryStream
+ using var memoryStream = new MemoryStream();
+ await stream.CopyToAsync(memoryStream);
// Act
- var discriminator = OpenApiModelFactory.Load(stream, OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Yaml, out var diagnostic);
+ var discriminator = OpenApiModelFactory.Load(memoryStream, OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Yaml, out var diagnostic);
// Assert
discriminator.Should().BeEquivalentTo(