Skip to content

Commit ab906e3

Browse files
committed
Add support to enable direct loading of model objects
1 parent 5b17f37 commit ab906e3

32 files changed

+2210
-75
lines changed

src/Microsoft.OpenApi.Readers/OpenApiStreamReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public async Task<ReadResult> ReadAsync(Stream input, CancellationToken cancella
8585
/// <param name="version">Version of the OpenAPI specification that the fragment conforms to.</param>
8686
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
8787
/// <returns>Instance of newly created OpenApiDocument</returns>
88-
public T ReadFragment<T>(Stream input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic) where T : IOpenApiReferenceable
88+
public T ReadFragment<T>(Stream input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic) where T : IOpenApiElement
8989
{
9090
using var reader = new StreamReader(input);
9191
return new OpenApiTextReaderReader(_settings).ReadFragment<T>(reader, version, out diagnostic);

src/Microsoft.OpenApi.Readers/OpenApiYamlReader.cs

Lines changed: 97 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.IO;
66
using System.Net.Http;
77
using System.Security;
8+
using System.Text.Json.Nodes;
89
using System.Threading;
910
using System.Threading.Tasks;
1011
using Microsoft.OpenApi.Interfaces;
@@ -29,13 +30,32 @@ public OpenApiDocument Parse(string input, out OpenApiDiagnostic diagnostic, Ope
2930

3031
/// <inheritdoc/>
3132
public OpenApiDocument Read(string url, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null)
33+
{
34+
var stream = GetStream(url);
35+
return Read(stream, out diagnostic, settings);
36+
}
37+
38+
/// <inheritdoc/>
39+
public OpenApiDocument Read(Stream stream, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null)
40+
{
41+
return new OpenApiStreamReader(settings).Read(stream, out diagnostic);
42+
}
43+
44+
/// <inheritdoc/>
45+
public OpenApiDocument Read(TextReader input, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null)
46+
{
47+
return new OpenApiTextReaderReader(settings).Read(input, out diagnostic);
48+
}
49+
50+
/// <inheritdoc/>
51+
public async Task<ReadResult> ReadAsync(string url, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default)
3252
{
3353
Stream stream;
3454
if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
3555
{
3656
try
3757
{
38-
stream = _httpClient.GetStreamAsync(new Uri(url)).GetAwaiter().GetResult();
58+
stream = await _httpClient.GetStreamAsync(new Uri(url));
3959
}
4060
catch (HttpRequestException ex)
4161
{
@@ -63,30 +83,96 @@ SecurityException or
6383
}
6484
}
6585

66-
return Read(stream, out diagnostic, settings);
86+
return await ReadAsync(stream, settings, cancellationToken);
6787
}
6888

69-
/// <inheritdoc/>
70-
public OpenApiDocument Read(Stream stream, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null)
89+
/// <inheritdoc/>
90+
public async Task<ReadResult> ReadAsync(Stream stream, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default)
7191
{
72-
return new OpenApiStreamReader(settings).Read(stream, out diagnostic);
92+
return await new OpenApiStreamReader(settings).ReadAsync(stream, cancellationToken);
7393
}
7494

7595
/// <inheritdoc/>
76-
public OpenApiDocument Read(TextReader input, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null)
96+
public async Task<ReadResult> ReadAsync(TextReader input,
97+
OpenApiReaderSettings settings = null,
98+
CancellationToken cancellationToken = default)
7799
{
78-
return new OpenApiTextReaderReader(settings).Read(input, out diagnostic);
100+
return await new OpenApiTextReaderReader(settings).ReadAsync(input, cancellationToken);
101+
}
102+
103+
104+
/// <summary>
105+
/// Takes in an input URL and parses it into an Open API document
106+
/// </summary>
107+
/// <param name="url">The path to the Open API file</param>
108+
/// <param name="version">The OpenAPI specification version.</param>
109+
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing.</param>
110+
/// <param name="settings">The Reader settings to be used during parsing.</param>
111+
/// <returns></returns>
112+
/// <exception cref="ArgumentException"></exception>
113+
public T Read<T>(string url,
114+
OpenApiSpecVersion version,
115+
out OpenApiDiagnostic diagnostic,
116+
OpenApiReaderSettings settings = null) where T : IOpenApiElement
117+
{
118+
settings ??= new OpenApiReaderSettings();
119+
var stream = GetStream(url);
120+
return Read<T>(stream, version, out diagnostic, settings);
79121
}
80122

81123
/// <inheritdoc/>
82-
public async Task<ReadResult> ReadAsync(string url, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default)
124+
public T Read<T>(Stream input,
125+
OpenApiSpecVersion version,
126+
out OpenApiDiagnostic diagnostic,
127+
OpenApiReaderSettings settings = null) where T : IOpenApiElement
128+
{
129+
return new OpenApiStreamReader(settings).ReadFragment<T>(input, version, out diagnostic);
130+
}
131+
132+
/// <inheritdoc/>
133+
public T Read<T>(TextReader input,
134+
OpenApiSpecVersion version,
135+
out OpenApiDiagnostic diagnostic,
136+
OpenApiReaderSettings settings = null) where T : IOpenApiElement
137+
{
138+
return new OpenApiTextReaderReader(settings).ReadFragment<T>(input, version, out diagnostic);
139+
}
140+
141+
/// <inheritdoc/>
142+
public T Read<T>(JsonNode input,
143+
OpenApiSpecVersion version,
144+
out OpenApiDiagnostic diagnostic,
145+
OpenApiReaderSettings settings = null) where T : IOpenApiElement
146+
{
147+
return new OpenApiYamlDocumentReader(settings).ReadFragment<T>(input, version, out diagnostic);
148+
}
149+
150+
/// <summary>
151+
/// Parses an input string into an Open API document.
152+
/// </summary>
153+
/// <param name="input"></param>
154+
/// <param name="version"></param>
155+
/// <param name="diagnostic"></param>
156+
/// <param name="settings"></param>
157+
/// <returns></returns>
158+
public T Parse<T>(string input,
159+
OpenApiSpecVersion version,
160+
out OpenApiDiagnostic diagnostic,
161+
OpenApiReaderSettings settings = null) where T : IOpenApiElement
162+
{
163+
settings ??= new OpenApiReaderSettings();
164+
using var reader = new StringReader(input);
165+
return Read<T>(reader, version, out diagnostic, settings);
166+
}
167+
168+
private Stream GetStream(string url)
83169
{
84170
Stream stream;
85171
if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase) || url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
86172
{
87173
try
88174
{
89-
stream = await _httpClient.GetStreamAsync(new Uri(url));
175+
stream = _httpClient.GetStreamAsync(new Uri(url)).GetAwaiter().GetResult();
90176
}
91177
catch (HttpRequestException ex)
92178
{
@@ -114,21 +200,7 @@ SecurityException or
114200
}
115201
}
116202

117-
return await ReadAsync(stream, settings, cancellationToken);
118-
}
119-
120-
/// <inheritdoc/>
121-
public async Task<ReadResult> ReadAsync(Stream stream, OpenApiReaderSettings settings = null, CancellationToken cancellationToken = default)
122-
{
123-
return await new OpenApiStreamReader(settings).ReadAsync(stream, cancellationToken);
124-
}
125-
126-
/// <inheritdoc/>
127-
public async Task<ReadResult> ReadAsync(TextReader input,
128-
OpenApiReaderSettings settings = null,
129-
CancellationToken cancellationToken = default)
130-
{
131-
return await new OpenApiTextReaderReader(settings).ReadAsync(input, cancellationToken);
132-
}
203+
return stream;
204+
}
133205
}
134206
}

src/Microsoft.OpenApi/Interfaces/IOpenApiReader.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
using System.IO;
5+
using System.Text.Json.Nodes;
56
using System.Threading;
67
using System.Threading.Tasks;
78
using Microsoft.OpenApi.Models;
@@ -76,5 +77,46 @@ public interface IOpenApiReader
7677
/// <param name="settings"> The OpenApi reader settings.</param>
7778
/// <returns></returns>
7879
OpenApiDocument Parse(string input, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null);
80+
81+
/// <summary>
82+
/// Reads the input string and parses it into an Open API document.
83+
/// </summary>
84+
/// <typeparam name="T"></typeparam>
85+
/// <param name="input"></param>
86+
/// <param name="version"></param>
87+
/// <param name="diagnostic"></param>
88+
/// <param name="settings"></param>
89+
/// <returns></returns>
90+
T Parse<T>(string input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement;
91+
92+
/// <summary>
93+
/// Reads the stream input and parses the fragment of an OpenAPI description into an Open API Element.
94+
/// </summary>
95+
/// <param name="input">Stream containing OpenAPI description to parse.</param>
96+
/// <param name="version">Version of the OpenAPI specification that the fragment conforms to.</param>
97+
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
98+
/// <param name="settings">The OpenApiReader settings.</param>
99+
/// <returns>Instance of newly created OpenApiDocument</returns>
100+
T Read<T>(Stream input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement;
101+
102+
/// <summary>
103+
/// Reads the TextReader input and parses the fragment of an OpenAPI description into an Open API Element.
104+
/// </summary>
105+
/// <param name="input">TextReader containing OpenAPI description to parse.</param>
106+
/// <param name="version">Version of the OpenAPI specification that the fragment conforms to.</param>
107+
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
108+
/// <param name="settings">The OpenApiReader settings.</param>
109+
/// <returns>Instance of newly created OpenApiDocument</returns>
110+
T Read<T>(TextReader input, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement;
111+
112+
/// <summary>
113+
/// Reads the stream input and parses the fragment of an OpenAPI description into an Open API Element.
114+
/// </summary>
115+
/// <param name="url">Url pointing to the document.</param>
116+
/// <param name="version">Version of the OpenAPI specification that the fragment conforms to.</param>
117+
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
118+
/// <param name="settings">The OpenApiReader settings.</param>
119+
/// <returns>Instance of newly created OpenApiDocument</returns>
120+
T Read<T>(string url, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null) where T : IOpenApiElement;
79121
}
80122
}

src/Microsoft.OpenApi/Models/OpenApiCallback.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.IO;
67
using Microsoft.OpenApi.Expressions;
78
using Microsoft.OpenApi.Interfaces;
9+
using Microsoft.OpenApi.Reader;
810
using Microsoft.OpenApi.Writers;
911

1012
namespace Microsoft.OpenApi.Models
@@ -187,5 +189,73 @@ public void SerializeAsV2WithoutReference(IOpenApiWriter writer)
187189
{
188190
// Callback object does not exist in V2.
189191
}
192+
193+
/// <summary>
194+
/// Parses a local file path or Url into an Open API document.
195+
/// </summary>
196+
/// <param name="url"> The path to the OpenAPI file.</param>
197+
/// <param name="version">The OpenAPI specification version.</param>
198+
/// <param name="diagnostic"></param>
199+
/// <param name="settings"></param>
200+
/// <returns></returns>
201+
public static OpenApiCallback Load(string url, OpenApiSpecVersion version, out OpenApiDiagnostic diagnostic, OpenApiReaderSettings settings = null)
202+
{
203+
return OpenApiModelFactory.Load<OpenApiCallback>(url, version, out diagnostic, settings);
204+
}
205+
206+
/// <summary>
207+
/// Reads the stream input and parses it into an Open API document.
208+
/// </summary>
209+
/// <param name="stream">Stream containing OpenAPI description to parse.</param>
210+
/// <param name="format">The OpenAPI format to use during parsing.</param>
211+
/// <param name="version"></param>
212+
/// <param name="diagnostic"></param>
213+
/// <param name="settings"></param>
214+
/// <returns></returns>
215+
public static OpenApiCallback Load(Stream stream,
216+
string format,
217+
OpenApiSpecVersion version,
218+
out OpenApiDiagnostic diagnostic,
219+
OpenApiReaderSettings settings = null)
220+
{
221+
return OpenApiModelFactory.Load<OpenApiCallback>(stream, version, out diagnostic, format, settings);
222+
}
223+
224+
/// <summary>
225+
/// Reads the text reader content and parses it into an Open API document.
226+
/// </summary>
227+
/// <param name="input">TextReader containing OpenAPI description to parse.</param>
228+
/// <param name="format"> The OpenAPI format to use during parsing.</param>
229+
/// <param name="version"></param>
230+
/// <param name="diagnostic"></param>
231+
/// <param name="settings"></param>
232+
/// <returns></returns>
233+
public static OpenApiCallback Load(TextReader input,
234+
string format,
235+
OpenApiSpecVersion version,
236+
out OpenApiDiagnostic diagnostic,
237+
OpenApiReaderSettings settings = null)
238+
{
239+
return OpenApiModelFactory.Load<OpenApiCallback>(input, version, out diagnostic, format, settings);
240+
}
241+
242+
243+
/// <summary>
244+
/// Parses a string into a <see cref="OpenApiDocument"/> object.
245+
/// </summary>
246+
/// <param name="input"> The string input.</param>
247+
/// <param name="version"></param>
248+
/// <param name="diagnostic"></param>
249+
/// <param name="format"></param>
250+
/// <param name="settings"></param>
251+
/// <returns></returns>
252+
public static OpenApiCallback Parse(string input,
253+
OpenApiSpecVersion version,
254+
out OpenApiDiagnostic diagnostic,
255+
string format = null,
256+
OpenApiReaderSettings settings = null)
257+
{
258+
return OpenApiModelFactory.Parse<OpenApiCallback>(input, version, out diagnostic, format, settings);
259+
}
190260
}
191261
}

0 commit comments

Comments
 (0)