Skip to content

Commit 3031023

Browse files
authored
fix: add type to references, always. (LEGO#139)
1 parent e1f8c87 commit 3031023

File tree

10 files changed

+98
-81
lines changed

10 files changed

+98
-81
lines changed

src/LEGO.AsyncAPI.Readers/AsyncApiJsonDocumentReader.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) The LEGO Group. All rights reserved.
1+
// Copyright (c) The LEGO Group. All rights reserved.
22

33
namespace LEGO.AsyncAPI.Readers
44
{
@@ -63,12 +63,12 @@ public AsyncApiDocument Read(JsonNode input, out AsyncApiDiagnostic diagnostic)
6363
if (this.settings.RuleSet != null && this.settings.RuleSet.Rules.Count > 0)
6464
{
6565
var asyncApiErrors = document.Validate(this.settings.RuleSet);
66-
foreach (var item in asyncApiErrors.Where(e => e is AsyncApiValidatorError))
66+
foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorError>())
6767
{
6868
diagnostic.Errors.Add(item);
6969
}
7070

71-
foreach (var item in asyncApiErrors.Where(e => e is AsyncApiValidatorWarning))
71+
foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorWarning>())
7272
{
7373
diagnostic.Warnings.Add(item);
7474
}
@@ -100,11 +100,16 @@ public async Task<ReadResult> ReadAsync(JsonNode input, CancellationToken cancel
100100
// Validate the document
101101
if (this.settings.RuleSet != null && this.settings.RuleSet.Rules.Count > 0)
102102
{
103-
var errors = document.Validate(this.settings.RuleSet);
104-
foreach (var item in errors)
103+
var asyncApiErrors = document.Validate(this.settings.RuleSet);
104+
foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorError>())
105105
{
106106
diagnostic.Errors.Add(item);
107107
}
108+
109+
foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorWarning>())
110+
{
111+
diagnostic.Warnings.Add(item);
112+
}
108113
}
109114

110115
return new ReadResult

src/LEGO.AsyncAPI.Readers/AsyncApiStreamReader.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace LEGO.AsyncAPI.Readers
44
{
55
using System.IO;
6+
using System.Threading;
67
using System.Threading.Tasks;
78
using LEGO.AsyncAPI.Models;
89
using LEGO.AsyncAPI.Models.Interfaces;
@@ -46,8 +47,11 @@ public AsyncApiDocument Read(Stream input, out AsyncApiDiagnostic diagnostic)
4647
/// Reads the stream input and parses it into an AsyncApi document.
4748
/// </summary>
4849
/// <param name="input">Stream containing AsyncApi description to parse.</param>
49-
/// <returns>Instance result containing newly created AsyncApiDocument and diagnostics object from the process.</returns>
50-
public async Task<ReadResult> ReadAsync(Stream input)
50+
/// <param name="cancellationToken">The cancellation token.</param>
51+
/// <returns>
52+
/// Instance result containing newly created AsyncApiDocument and diagnostics object from the process.
53+
/// </returns>
54+
public async Task<ReadResult> ReadAsync(Stream input, CancellationToken cancellationToken)
5155
{
5256
MemoryStream bufferedStream;
5357
if (input is MemoryStream)
@@ -65,7 +69,7 @@ public async Task<ReadResult> ReadAsync(Stream input)
6569

6670
var reader = new StreamReader(bufferedStream);
6771

68-
return await new AsyncApiTextReader(this.settings).ReadAsync(reader);
72+
return await new AsyncApiTextReader(this.settings).ReadAsync(reader, cancellationToken);
6973
}
7074

7175
/// <summary>

src/LEGO.AsyncAPI.Readers/AsyncApiTextReader.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace LEGO.AsyncAPI.Readers
66
using System.Linq;
77
using System.Text.Json;
88
using System.Text.Json.Nodes;
9+
using System.Threading;
910
using System.Threading.Tasks;
1011
using LEGO.AsyncAPI.Models;
1112
using LEGO.AsyncAPI.Models.Interfaces;
@@ -57,8 +58,11 @@ public AsyncApiDocument Read(TextReader input, out AsyncApiDiagnostic diagnostic
5758
/// Reads the content of the TextReader.
5859
/// </summary>
5960
/// <param name="input">TextReader containing AsyncApi description to parse.</param>
60-
/// <returns>A ReadResult instance that contains the resulting AsyncApiDocument and a diagnostics instance.</returns>
61-
public async Task<ReadResult> ReadAsync(TextReader input)
61+
/// <param name="cancellationToken">The cancellation token.</param>
62+
/// <returns>
63+
/// A ReadResult instance that contains the resulting AsyncApiDocument and a diagnostics instance.
64+
/// </returns>
65+
public async Task<ReadResult> ReadAsync(TextReader input, CancellationToken cancellationToken)
6266
{
6367
JsonNode jsonNode;
6468

@@ -78,7 +82,7 @@ public async Task<ReadResult> ReadAsync(TextReader input)
7882
};
7983
}
8084

81-
return await new AsyncApiJsonDocumentReader(this.settings).ReadAsync(jsonNode);
85+
return await new AsyncApiJsonDocumentReader(this.settings).ReadAsync(jsonNode, cancellationToken);
8286
}
8387

8488
/// <summary>

src/LEGO.AsyncAPI.Readers/V2/AsyncApiV2VersionService.cs

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -54,78 +54,81 @@ public AsyncApiReference ConvertToAsyncApiReference(
5454
string reference,
5555
ReferenceType? type)
5656
{
57-
if (!string.IsNullOrWhiteSpace(reference))
57+
if (string.IsNullOrWhiteSpace(reference))
5858
{
59-
var segments = reference.Split('#');
60-
if (segments.Length == 1)
59+
throw new AsyncApiException($"The reference string '{reference}' has invalid format.");
60+
}
61+
62+
var segments = reference.Split('#');
63+
if (segments.Length == 1)
64+
{
65+
if (type == ReferenceType.SecurityScheme)
6166
{
62-
if (type == ReferenceType.SecurityScheme)
67+
return new AsyncApiReference
6368
{
64-
return new AsyncApiReference
65-
{
66-
Type = type,
67-
Id = reference,
68-
};
69-
}
69+
Type = type,
70+
Id = reference,
71+
};
72+
}
7073

71-
var asyncApiReference = new AsyncApiReference();
72-
if (reference.StartsWith("/"))
73-
{
74-
asyncApiReference.IsFragment = true;
75-
}
74+
var asyncApiReference = new AsyncApiReference();
75+
asyncApiReference.Type = type;
76+
if (reference.StartsWith("/"))
77+
{
78+
asyncApiReference.IsFragment = true;
79+
}
7680

77-
asyncApiReference.ExternalResource = segments[0];
81+
asyncApiReference.ExternalResource = segments[0];
7882

79-
return asyncApiReference;
83+
return asyncApiReference;
8084

81-
}
82-
else if (segments.Length == 2)
85+
}
86+
else if (segments.Length == 2)
87+
{
88+
// Local reference
89+
if (reference.StartsWith("#"))
8390
{
84-
// Local reference
85-
if (reference.StartsWith("#"))
91+
try
8692
{
87-
try
88-
{
89-
return this.ParseReference(segments[1]);
90-
}
91-
catch (AsyncApiException ex)
92-
{
93-
this.Diagnostic.Errors.Add(new AsyncApiError(ex));
94-
return null;
95-
}
93+
return this.ParseReference(segments[1]);
9694
}
97-
98-
var id = segments[1];
99-
var asyncApiReference = new AsyncApiReference();
100-
if (id.StartsWith("/components/"))
95+
catch (AsyncApiException ex)
10196
{
102-
var localSegments = segments[1].Split('/');
103-
var referencedType = localSegments[2].GetEnumFromDisplayName<ReferenceType>();
104-
if (type == null)
105-
{
106-
type = referencedType;
107-
}
108-
else
109-
{
110-
if (type != referencedType)
111-
{
112-
throw new AsyncApiException("Referenced type mismatch");
113-
}
114-
}
97+
this.Diagnostic.Errors.Add(new AsyncApiError(ex));
98+
return null;
99+
}
100+
}
115101

116-
id = localSegments[3];
102+
var id = segments[1];
103+
var asyncApiReference = new AsyncApiReference();
104+
if (id.StartsWith("/components/"))
105+
{
106+
var localSegments = segments[1].Split('/');
107+
var referencedType = localSegments[2].GetEnumFromDisplayName<ReferenceType>();
108+
if (type == null)
109+
{
110+
type = referencedType;
117111
}
118112
else
119113
{
120-
asyncApiReference.IsFragment = true;
114+
if (type != referencedType)
115+
{
116+
throw new AsyncApiException("Referenced type mismatch");
117+
}
121118
}
122119

123-
asyncApiReference.ExternalResource = segments[0];
124-
asyncApiReference.Type = type;
125-
asyncApiReference.Id = id;
126-
127-
return asyncApiReference;
120+
id = localSegments[3];
128121
}
122+
else
123+
{
124+
asyncApiReference.IsFragment = true;
125+
}
126+
127+
asyncApiReference.ExternalResource = segments[0];
128+
asyncApiReference.Type = type;
129+
asyncApiReference.Id = id;
130+
131+
return asyncApiReference;
129132
}
130133

131134
throw new AsyncApiException($"The reference string '{reference}' has invalid format.");

test/LEGO.AsyncAPI.Tests/Bindings/Http/HttpBindings_Should.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void HttpMessageBinding_FilledObject_SerializesAndDeserializes()
3636
actual = actual.MakeLineBreaksEnvironmentNeutral();
3737
expected = expected.MakeLineBreaksEnvironmentNeutral();
3838
var settings = new AsyncApiReaderSettings();
39-
settings.Bindings.Add(BindingsCollection.Http);
39+
settings.Bindings = BindingsCollection.Http;
4040
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiMessage>(actual, AsyncApiVersion.AsyncApi2_0, out _);
4141

4242
// Assert
@@ -73,7 +73,7 @@ public void HttpOperationBinding_FilledObject_SerializesAndDeserializes()
7373
actual = actual.MakeLineBreaksEnvironmentNeutral();
7474
expected = expected.MakeLineBreaksEnvironmentNeutral();
7575
var settings = new AsyncApiReaderSettings();
76-
settings.Bindings.Add(BindingsCollection.Http);
76+
settings.Bindings = BindingsCollection.Http;
7777
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiOperation>(actual, AsyncApiVersion.AsyncApi2_0, out _);
7878

7979
// Assert

test/LEGO.AsyncAPI.Tests/Bindings/Kafka/KafkaBindings_Should.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void KafkaChannelBinding_WithFilledObject_SerializesAndDeserializes()
5555
actual = actual.MakeLineBreaksEnvironmentNeutral();
5656
expected = expected.MakeLineBreaksEnvironmentNeutral();
5757
var settings = new AsyncApiReaderSettings();
58-
settings.Bindings.Add(BindingsCollection.Kafka);
58+
settings.Bindings = BindingsCollection.Kafka;
5959
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>(actual, AsyncApiVersion.AsyncApi2_0, out _);
6060

6161
// Assert
@@ -92,7 +92,7 @@ public void KafkaServerBinding_WithFilledObject_SerializesAndDeserializes()
9292
actual = actual.MakeLineBreaksEnvironmentNeutral();
9393
expected = expected.MakeLineBreaksEnvironmentNeutral();
9494
var settings = new AsyncApiReaderSettings();
95-
settings.Bindings.Add(BindingsCollection.Kafka);
95+
settings.Bindings = BindingsCollection.Kafka;
9696
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);
9797

9898
// Assert
@@ -131,7 +131,7 @@ public void KafkaMessageBinding_WithFilledObject_SerializesAndDeserializes()
131131
actual = actual.MakeLineBreaksEnvironmentNeutral();
132132
expected = expected.MakeLineBreaksEnvironmentNeutral();
133133
var settings = new AsyncApiReaderSettings();
134-
settings.Bindings.Add(BindingsCollection.Kafka);
134+
settings.Bindings = BindingsCollection.Kafka;
135135
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiMessage>(actual, AsyncApiVersion.AsyncApi2_0, out _);
136136

137137
// Assert
@@ -171,7 +171,7 @@ public void KafkaOperationBinding_WithFilledObject_SerializesAndDeserializes()
171171
expected = expected.MakeLineBreaksEnvironmentNeutral();
172172

173173
var settings = new AsyncApiReaderSettings();
174-
settings.Bindings.Add(BindingsCollection.Kafka);
174+
settings.Bindings = BindingsCollection.Kafka;
175175
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiOperation>(actual, AsyncApiVersion.AsyncApi2_0, out _);
176176

177177
// Assert

test/LEGO.AsyncAPI.Tests/Bindings/Pulsar/PulsarBindings_Should.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void PulsarChannelBinding_WithFilledObject_SerializesAndDeserializes()
6161
expected = expected.MakeLineBreaksEnvironmentNeutral();
6262

6363
var settings = new AsyncApiReaderSettings();
64-
settings.Bindings.Add(BindingsCollection.Pulsar);
64+
settings.Bindings = BindingsCollection.Pulsar;
6565
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>(actual, AsyncApiVersion.AsyncApi2_0, out _);
6666

6767
// Assert
@@ -80,7 +80,7 @@ public void PulsarChannelBindingNamespaceDefaultToNull()
8080

8181
// Act
8282
var settings = new AsyncApiReaderSettings();
83-
settings.Bindings.Add(BindingsCollection.Pulsar);
83+
settings.Bindings = BindingsCollection.Pulsar;
8484
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>(actual, AsyncApiVersion.AsyncApi2_0, out _);
8585

8686
// Assert
@@ -99,7 +99,7 @@ public void PulsarChannelBindingPropertiesExceptNamespaceDefaultToNull()
9999
// Act
100100
// Assert
101101
var settings = new AsyncApiReaderSettings();
102-
settings.Bindings.Add(BindingsCollection.Pulsar);
102+
settings.Bindings = BindingsCollection.Pulsar;
103103
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>(actual, AsyncApiVersion.AsyncApi2_0, out _);
104104
var pulsarBinding = ((PulsarChannelBinding)binding.Bindings["pulsar"]);
105105

@@ -139,7 +139,7 @@ public void PulsarServerBinding_WithFilledObject_SerializesAndDeserializes()
139139
actual = actual.MakeLineBreaksEnvironmentNeutral();
140140
expected = expected.MakeLineBreaksEnvironmentNeutral();
141141
var settings = new AsyncApiReaderSettings();
142-
settings.Bindings.Add(BindingsCollection.Pulsar);
142+
settings.Bindings = BindingsCollection.Pulsar;
143143
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);
144144

145145
// Assert
@@ -175,7 +175,7 @@ public void ServerBindingVersionDefaultsToNull()
175175
actual = actual.MakeLineBreaksEnvironmentNeutral();
176176
expected = expected.MakeLineBreaksEnvironmentNeutral();
177177
var settings = new AsyncApiReaderSettings();
178-
settings.Bindings.Add(BindingsCollection.Pulsar);
178+
settings.Bindings = BindingsCollection.Pulsar;
179179
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);
180180

181181
// Assert
@@ -212,7 +212,7 @@ public void ServerTenantDefaultsToNull()
212212
actual = actual.MakeLineBreaksEnvironmentNeutral();
213213
expected = expected.MakeLineBreaksEnvironmentNeutral();
214214
var settings = new AsyncApiReaderSettings();
215-
settings.Bindings.Add(BindingsCollection.Pulsar);
215+
settings.Bindings = BindingsCollection.Pulsar;
216216
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);
217217

218218
// Assert

test/LEGO.AsyncAPI.Tests/Bindings/WebSockets/WebSocketBindings_Should.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public void WebSocketChannelBinding_WithFilledObject_SerializesAndDeserializes()
4444
expected = expected.MakeLineBreaksEnvironmentNeutral();
4545

4646
var settings = new AsyncApiReaderSettings();
47-
settings.Bindings.Add(BindingsCollection.Websockets);
47+
settings.Bindings = BindingsCollection.Websockets;
4848
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>(actual, AsyncApiVersion.AsyncApi2_0, out _);
4949

5050
// Assert

test/LEGO.AsyncAPI.Tests/Models/AsyncApiMessage_Should.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ public void AsyncApiMessage_WithFilledObject_Serializes()
393393
expected = expected.MakeLineBreaksEnvironmentNeutral();
394394

395395
var settings = new AsyncApiReaderSettings();
396-
settings.Bindings.Add(BindingsCollection.All);
396+
settings.Bindings = BindingsCollection.All;
397397
var deserializedMessage = new AsyncApiStringReader(settings).ReadFragment<AsyncApiMessage>(expected, AsyncApiVersion.AsyncApi2_0, out _);
398398

399399
// Assert

test/LEGO.AsyncAPI.Tests/Models/AsyncApiReference_Should.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void AsyncApiReference_WithExternalFragmentUriReference_AllowReference()
3131
reference.Id.Should().Be("/path/to/external/fragment");
3232
reference.IsFragment.Should().BeTrue();
3333
reference.IsExternal.Should().BeTrue();
34-
34+
reference.Type.Should().Be(ReferenceType.Schema);
3535
var serialized = deserialized.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
3636
actual = actual.MakeLineBreaksEnvironmentNeutral();
3737
var expected = serialized.MakeLineBreaksEnvironmentNeutral();
@@ -54,6 +54,7 @@ public void AsyncApiReference_WithFragmentReference_AllowReference()
5454
deserialized.Payload.UnresolvedReference.Should().BeTrue();
5555

5656
var reference = deserialized.Payload.Reference;
57+
reference.Type.Should().Be(ReferenceType.Schema);
5758
reference.ExternalResource.Should().Be("/fragments/myFragment");
5859
reference.Id.Should().BeNull();
5960
reference.IsFragment.Should().BeTrue();
@@ -206,10 +207,10 @@ public void AsyncApiDocument_WithExternalReference_DoesNotResolve()
206207
channel.UnresolvedReference.Should().BeTrue();
207208
channel.Description.Should().BeNull();
208209
channel.Reference.ExternalResource.Should().Be("http://example.com/channel.json");
210+
channel.Reference.Type.Should().Be(ReferenceType.Channel);
209211
channel.Reference.Id.Should().BeNull();
210212
channel.Reference.IsExternal.Should().BeTrue();
211213
channel.Reference.IsFragment.Should().BeFalse();
212-
channel.Reference.Type.Should().BeNull();
213214
}
214215

215216
[Test]

0 commit comments

Comments
 (0)