Skip to content

Commit c54b76b

Browse files
committed
fix reference id to be whole fragments
also fixed up external references and streams
1 parent b8b0b8d commit c54b76b

28 files changed

+337
-665
lines changed

src/LEGO.AsyncAPI.Readers/AsyncApiJsonDocumentReader.cs

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace LEGO.AsyncAPI.Readers
1010
using System.Text.Json.Nodes;
1111
using System.Threading;
1212
using System.Threading.Tasks;
13+
using Json.More;
1314
using Json.Pointer;
1415
using LEGO.AsyncAPI.Exceptions;
1516
using LEGO.AsyncAPI.Extensions;
@@ -20,6 +21,7 @@ namespace LEGO.AsyncAPI.Readers
2021
using LEGO.AsyncAPI.Readers.Services;
2122
using LEGO.AsyncAPI.Services;
2223
using LEGO.AsyncAPI.Validations;
24+
using YamlDotNet.RepresentationModel;
2325

2426
/// <summary>
2527
/// Service class for converting contents of TextReader into AsyncApiDocument instances.
@@ -211,7 +213,7 @@ private void ResolveInternalReferences(AsyncApiDiagnostic diagnostic, AsyncApiDo
211213

212214
private void ResolveExternalReferences(AsyncApiDiagnostic diagnostic, IAsyncApiSerializable serializable, AsyncApiDocument hostDocument)
213215
{
214-
var loader = this.settings.ExternalReferenceLoader ??= new DefaultStreamLoader();
216+
var loader = this.settings.ExternalReferenceLoader ??= new DefaultStreamLoader(this.settings);
215217
var collector = new AsyncApiRemoteReferenceCollector(hostDocument);
216218
var walker = new AsyncApiWalker(collector);
217219
walker.Walk(serializable);
@@ -232,10 +234,11 @@ private void ResolveExternalReferences(AsyncApiDiagnostic diagnostic, IAsyncApiS
232234
}
233235
else
234236
{
235-
stream = loader.Load(new Uri(reference.Reference.Reference, UriKind.RelativeOrAbsolute));
237+
stream = loader.Load(new Uri(reference.Reference.ExternalResource, UriKind.RelativeOrAbsolute));
238+
this.context.Workspace.RegisterComponent(reference.Reference.ExternalResource, stream);
236239
}
237240

238-
var component = this.ResolveStream(stream, reference, diagnostic);
241+
var component = this.ResolveArtifactReferences(stream, reference, diagnostic);
239242
if (component == null)
240243
{
241244
diagnostic.Errors.Add(new AsyncApiError(string.Empty, $"Unable to deserialize reference '{reference.Reference.Reference}'"));
@@ -252,12 +255,34 @@ private void ResolveExternalReferences(AsyncApiDiagnostic diagnostic, IAsyncApiS
252255
}
253256
}
254257

255-
private IAsyncApiSerializable ResolveStream(Stream input, IAsyncApiReferenceable reference, AsyncApiDiagnostic diagnostic)
258+
private JsonNode ReadToJson(Stream stream)
256259
{
257-
var json = JsonNode.Parse(input);
260+
if (stream != null)
261+
{
262+
var reader = new StreamReader(stream);
263+
var yamlStream = new YamlStream();
264+
yamlStream.Load(reader);
265+
return yamlStream.Documents.First().ToJsonNode(this.settings.CultureInfo);
266+
}
267+
268+
return default;
269+
}
270+
271+
private IAsyncApiSerializable ResolveArtifactReferences(Stream stream, IAsyncApiReferenceable reference, AsyncApiDiagnostic diagnostic)
272+
{
273+
JsonNode json = null;
274+
try
275+
{
276+
json = this.ReadToJson(stream);
277+
}
278+
catch
279+
{
280+
diagnostic.Errors.Add(new AsyncApiError(string.Empty, $"Unable to deserialize reference: '{reference.Reference.Reference}'"));
281+
}
282+
258283
if (reference.Reference.IsFragment)
259284
{
260-
var pointer = JsonPointer.Parse(reference.Reference.Id);
285+
var pointer = JsonPointer.Parse(reference.Reference.FragmentId);
261286
if (pointer.TryEvaluate(json, out var pointerResult))
262287
{
263288
json = pointerResult;
@@ -269,53 +294,55 @@ private IAsyncApiSerializable ResolveStream(Stream input, IAsyncApiReferenceable
269294
}
270295
}
271296

297+
AsyncApiDiagnostic fragmentDiagnostic = new AsyncApiDiagnostic();
272298
IAsyncApiSerializable result = null;
273299
switch (reference.Reference.Type)
274300
{
275301
case ReferenceType.Schema:
276-
result = this.ReadFragment<AsyncApiJsonSchema>(json, AsyncApiVersion.AsyncApi2_0, out var streamDiagnostics);
302+
result = this.ReadFragment<AsyncApiJsonSchema>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
277303
break;
278304
case ReferenceType.Server:
279-
result = this.ReadFragment<AsyncApiServer>(json, AsyncApiVersion.AsyncApi2_0, out var _);
305+
result = this.ReadFragment<AsyncApiServer>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
280306
break;
281307
case ReferenceType.Channel:
282-
result = this.ReadFragment<AsyncApiChannel>(json, AsyncApiVersion.AsyncApi2_0, out var _);
308+
result = this.ReadFragment<AsyncApiChannel>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
283309
break;
284310
case ReferenceType.Message:
285-
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out var _);
311+
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
286312
break;
287313
case ReferenceType.SecurityScheme:
288-
result = this.ReadFragment<AsyncApiSecurityScheme>(json, AsyncApiVersion.AsyncApi2_0, out var _);
314+
result = this.ReadFragment<AsyncApiSecurityScheme>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
289315
break;
290316
case ReferenceType.Parameter:
291-
result = this.ReadFragment<AsyncApiParameter>(json, AsyncApiVersion.AsyncApi2_0, out var _);
317+
result = this.ReadFragment<AsyncApiParameter>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
292318
break;
293319
case ReferenceType.CorrelationId:
294-
result = this.ReadFragment<AsyncApiCorrelationId>(json, AsyncApiVersion.AsyncApi2_0, out var _);
320+
result = this.ReadFragment<AsyncApiCorrelationId>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
295321
break;
296322
case ReferenceType.OperationTrait:
297-
result = this.ReadFragment<AsyncApiOperationTrait>(json, AsyncApiVersion.AsyncApi2_0, out var _);
323+
result = this.ReadFragment<AsyncApiOperationTrait>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
298324
break;
299325
case ReferenceType.MessageTrait:
300-
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out var _);
326+
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
301327
break;
302328
case ReferenceType.ServerBindings:
303-
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out var _);
329+
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
304330
break;
305331
case ReferenceType.ChannelBindings:
306-
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out var _);
332+
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
307333
break;
308334
case ReferenceType.OperationBindings:
309-
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out var _);
335+
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
310336
break;
311337
case ReferenceType.MessageBindings:
312-
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out var _);
338+
result = this.ReadFragment<AsyncApiMessage>(json, AsyncApiVersion.AsyncApi2_0, out fragmentDiagnostic);
313339
break;
314340
default:
315341
diagnostic.Errors.Add(new AsyncApiError(reference.Reference.Reference, "Could not resolve reference."));
316342
break;
317343
}
318344

345+
diagnostic.Append(fragmentDiagnostic);
319346
return result;
320347
}
321348
}

src/LEGO.AsyncAPI.Readers/AsyncApiReferenceHostDocumentResolver.cs

Lines changed: 0 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,10 @@
22

33
namespace LEGO.AsyncAPI.Readers
44
{
5-
using System;
65
using System.Collections.Generic;
7-
using System.Linq;
8-
using System.Text.Json.Nodes;
9-
using System.Threading;
10-
using System.Threading.Tasks;
11-
using LEGO.AsyncAPI.Exceptions;
12-
using LEGO.AsyncAPI.Extensions;
136
using LEGO.AsyncAPI.Models;
147
using LEGO.AsyncAPI.Models.Interfaces;
15-
using LEGO.AsyncAPI.Readers.Interface;
16-
using LEGO.AsyncAPI.Readers.Services;
178
using LEGO.AsyncAPI.Services;
18-
using LEGO.AsyncAPI.Validations;
19-
209

2110
internal class AsyncApiReferenceHostDocumentResolver : AsyncApiVisitorBase
2211
{
@@ -42,216 +31,7 @@ public override void Visit(IAsyncApiReferenceable referenceable)
4231
if (referenceable.Reference != null)
4332
{
4433
referenceable.Reference.HostDocument = this.currentDocument;
45-
this.currentDocument.Workspace.RegisterReference(referenceable);
4634
}
47-
4835
}
4936
}
50-
//public override void Visit(AsyncApiComponents components)
51-
//{
52-
// this.ResolveMap(components.Parameters);
53-
// this.ResolveMap(components.Channels);
54-
// this.ResolveMap(components.Schemas);
55-
// this.ResolveMap(components.Servers);
56-
// this.ResolveMap(components.CorrelationIds);
57-
// this.ResolveMap(components.MessageTraits);
58-
// this.ResolveMap(components.OperationTraits);
59-
// this.ResolveMap(components.SecuritySchemes);
60-
// this.ResolveMap(components.ChannelBindings);
61-
// this.ResolveMap(components.MessageBindings);
62-
// this.ResolveMap(components.OperationBindings);
63-
// this.ResolveMap(components.ServerBindings);
64-
// this.ResolveMap(components.Messages);
65-
//}
66-
67-
//public override void Visit(AsyncApiDocument doc)
68-
//{
69-
// this.ResolveMap(doc.Servers);
70-
// this.ResolveMap(doc.Channels);
71-
//}
72-
73-
//public override void Visit(AsyncApiChannel channel)
74-
//{
75-
// this.ResolveMap(channel.Parameters);
76-
// this.ResolveObject(channel.Bindings, r => channel.Bindings = r);
77-
//}
78-
79-
//public override void Visit(AsyncApiMessageTrait trait)
80-
//{
81-
// this.ResolveObject(trait.CorrelationId, r => trait.CorrelationId = r);
82-
// this.ResolveObject(trait.Headers, r => trait.Headers = r);
83-
//}
84-
85-
///// <summary>
86-
///// Resolve all references used in an operation.
87-
///// </summary>
88-
//public override void Visit(AsyncApiOperation operation)
89-
//{
90-
// this.ResolveList(operation.Message);
91-
// this.ResolveList(operation.Traits);
92-
// this.ResolveObject(operation.Bindings, r => operation.Bindings = r);
93-
//}
94-
95-
//public override void Visit(AsyncApiMessage message)
96-
//{
97-
// this.ResolveObject(message.Headers, r => message.Headers = r);
98-
99-
// // #ToFix Resolve references correctly
100-
// if (message.Payload is AsyncApiJsonSchemaPayload)
101-
// {
102-
// this.ResolveObject(message.Payload as AsyncApiJsonSchemaPayload, r => message.Payload = r);
103-
// }
104-
105-
// this.ResolveList(message.Traits);
106-
// this.ResolveObject(message.CorrelationId, r => message.CorrelationId = r);
107-
// this.ResolveObject(message.Bindings, r => message.Bindings = r);
108-
//}
109-
110-
//public override void Visit(AsyncApiServer server)
111-
//{
112-
// this.ResolveObject(server.Bindings, r => server.Bindings = r);
113-
//}
114-
115-
///// <summary>
116-
///// Resolve all references to SecuritySchemes.
117-
///// </summary>
118-
//public override void Visit(AsyncApiSecurityRequirement securityRequirement)
119-
//{
120-
// foreach (var scheme in securityRequirement.Keys.ToList())
121-
// {
122-
// this.ResolveObject(scheme, (resolvedScheme) =>
123-
// {
124-
// if (resolvedScheme != null)
125-
// {
126-
// // If scheme was unresolved
127-
// // copy Scopes and remove old unresolved scheme
128-
// var scopes = securityRequirement[scheme];
129-
// securityRequirement.Remove(scheme);
130-
// securityRequirement.Add(resolvedScheme, scopes);
131-
// }
132-
// });
133-
// }
134-
//}
135-
136-
///// <summary>
137-
///// Resolve all references to parameters.
138-
///// </summary>
139-
//public override void Visit(IList<AsyncApiParameter> parameters)
140-
//{
141-
// this.ResolveList(parameters);
142-
//}
143-
144-
///// <summary>
145-
///// Resolve all references used in a parameter.
146-
///// </summary>
147-
//public override void Visit(AsyncApiParameter parameter)
148-
//{
149-
// this.ResolveObject(parameter.Schema, r => parameter.Schema = r);
150-
//}
151-
152-
///// <summary>
153-
///// Resolve all references used in a schema.
154-
///// </summary>
155-
//public override void Visit(AsyncApiJsonSchema schema)
156-
//{
157-
// this.ResolveObject(schema.Items, r => schema.Items = r);
158-
// this.ResolveList(schema.OneOf);
159-
// this.ResolveList(schema.AllOf);
160-
// this.ResolveList(schema.AnyOf);
161-
// this.ResolveObject(schema.Contains, r => schema.Contains = r);
162-
// this.ResolveObject(schema.Else, r => schema.Else = r);
163-
// this.ResolveObject(schema.If, r => schema.If = r);
164-
// this.ResolveObject(schema.Items, r => schema.Items = r);
165-
// this.ResolveObject(schema.Not, r => schema.Not = r);
166-
// this.ResolveObject(schema.Then, r => schema.Then = r);
167-
// this.ResolveObject(schema.PropertyNames, r => schema.PropertyNames = r);
168-
// this.ResolveObject(schema.AdditionalProperties, r => schema.AdditionalProperties = r);
169-
// this.ResolveMap(schema.Properties);
170-
//}
171-
172-
//private void ResolveObject<T>(T entity, Action<T> assign)
173-
// where T : class, IAsyncApiReferenceable, new()
174-
//{
175-
// if (entity == null)
176-
// {
177-
// return;
178-
// }
179-
180-
// if (this.IsUnresolvedReference(entity))
181-
// {
182-
// assign(this.ResolveReference<T>(entity.Reference));
183-
// }
184-
//}
185-
186-
//private void ResolveList<T>(IList<T> list)
187-
// where T : class, IAsyncApiReferenceable, new()
188-
//{
189-
// if (list == null)
190-
// {
191-
// return;
192-
// }
193-
194-
// for (int i = 0; i < list.Count; i++)
195-
// {
196-
// var entity = list[i];
197-
// if (this.IsUnresolvedReference(entity))
198-
// {
199-
// list[i] = this.ResolveReference<T>(entity.Reference);
200-
// }
201-
// }
202-
//}
203-
204-
//private void ResolveMap<T>(IDictionary<string, T> map)
205-
// where T : class, IAsyncApiReferenceable, new()
206-
//{
207-
// if (map == null)
208-
// {
209-
// return;
210-
// }
211-
212-
// foreach (var key in map.Keys.ToList())
213-
// {
214-
// var entity = map[key];
215-
// if (this.IsUnresolvedReference(entity))
216-
// {
217-
// map[key] = this.ResolveReference<T>(entity.Reference);
218-
// }
219-
// }
220-
//}
221-
222-
//private T ResolveReference<T>(AsyncApiReference reference)
223-
// where T : class, IAsyncApiReferenceable, new()
224-
//{
225-
// // external references are resolved by the AsyncApiExternalReferenceResolver
226-
// if (reference.IsExternal)
227-
// {
228-
// return new()
229-
// {
230-
// UnresolvedReference = true,
231-
// Reference = reference,
232-
// };
233-
// }
234-
235-
// try
236-
// {
237-
// var resolvedReference = this.currentDocument.ResolveReference<T>(reference);
238-
// if (resolvedReference == null)
239-
// {
240-
// throw new AsyncApiException($"Cannot resolve reference '{reference.Reference}' to '{typeof(T).Name}'.");
241-
// }
242-
243-
// return resolvedReference;
244-
// }
245-
// catch (AsyncApiException ex)
246-
// {
247-
// this.errors.Add(new AsyncApiReferenceError(ex));
248-
// return null;
249-
// }
250-
//}
251-
252-
//private bool IsUnresolvedReference(IAsyncApiReferenceable possibleReference)
253-
//{
254-
// return (possibleReference != null && possibleReference.UnresolvedReference);
255-
//}
256-
//}
25737
}

src/LEGO.AsyncAPI.Readers/AsyncApiTextReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static JsonNode LoadYamlDocument(TextReader input, AsyncApiReaderSettings settin
122122
{
123123
var yamlStream = new YamlStream();
124124
yamlStream.Load(input);
125-
return yamlStream.Documents.First().ToJsonNode(settings);
125+
return yamlStream.Documents.First().ToJsonNode(settings.CultureInfo);
126126
}
127127
}
128128
}

0 commit comments

Comments
 (0)