Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add type to references, always. #139

Merged
merged 3 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/LEGO.AsyncAPI.Readers/AsyncApiJsonDocumentReader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) The LEGO Group. All rights reserved.
// Copyright (c) The LEGO Group. All rights reserved.

namespace LEGO.AsyncAPI.Readers
{
Expand Down Expand Up @@ -63,12 +63,12 @@ public AsyncApiDocument Read(JsonNode input, out AsyncApiDiagnostic diagnostic)
if (this.settings.RuleSet != null && this.settings.RuleSet.Rules.Count > 0)
{
var asyncApiErrors = document.Validate(this.settings.RuleSet);
foreach (var item in asyncApiErrors.Where(e => e is AsyncApiValidatorError))
foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorError>())
{
diagnostic.Errors.Add(item);
}

foreach (var item in asyncApiErrors.Where(e => e is AsyncApiValidatorWarning))
foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorWarning>())
{
diagnostic.Warnings.Add(item);
}
Expand Down Expand Up @@ -100,11 +100,16 @@ public async Task<ReadResult> ReadAsync(JsonNode input, CancellationToken cancel
// Validate the document
if (this.settings.RuleSet != null && this.settings.RuleSet.Rules.Count > 0)
{
var errors = document.Validate(this.settings.RuleSet);
foreach (var item in errors)
var asyncApiErrors = document.Validate(this.settings.RuleSet);
foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorError>())
{
diagnostic.Errors.Add(item);
}

foreach (var item in asyncApiErrors.OfType<AsyncApiValidatorWarning>())
{
diagnostic.Warnings.Add(item);
}
}

return new ReadResult
Expand Down
10 changes: 7 additions & 3 deletions src/LEGO.AsyncAPI.Readers/AsyncApiStreamReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace LEGO.AsyncAPI.Readers
{
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Models.Interfaces;
Expand Down Expand Up @@ -46,8 +47,11 @@ public AsyncApiDocument Read(Stream input, out AsyncApiDiagnostic diagnostic)
/// Reads the stream input and parses it into an AsyncApi document.
/// </summary>
/// <param name="input">Stream containing AsyncApi description to parse.</param>
/// <returns>Instance result containing newly created AsyncApiDocument and diagnostics object from the process.</returns>
public async Task<ReadResult> ReadAsync(Stream input)
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// Instance result containing newly created AsyncApiDocument and diagnostics object from the process.
/// </returns>
public async Task<ReadResult> ReadAsync(Stream input, CancellationToken cancellationToken)
{
MemoryStream bufferedStream;
if (input is MemoryStream)
Expand All @@ -65,7 +69,7 @@ public async Task<ReadResult> ReadAsync(Stream input)

var reader = new StreamReader(bufferedStream);

return await new AsyncApiTextReader(this.settings).ReadAsync(reader);
return await new AsyncApiTextReader(this.settings).ReadAsync(reader, cancellationToken);
}

/// <summary>
Expand Down
10 changes: 7 additions & 3 deletions src/LEGO.AsyncAPI.Readers/AsyncApiTextReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace LEGO.AsyncAPI.Readers
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Models.Interfaces;
Expand Down Expand Up @@ -57,8 +58,11 @@ public AsyncApiDocument Read(TextReader input, out AsyncApiDiagnostic diagnostic
/// Reads the content of the TextReader.
/// </summary>
/// <param name="input">TextReader containing AsyncApi description to parse.</param>
/// <returns>A ReadResult instance that contains the resulting AsyncApiDocument and a diagnostics instance.</returns>
public async Task<ReadResult> ReadAsync(TextReader input)
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A ReadResult instance that contains the resulting AsyncApiDocument and a diagnostics instance.
/// </returns>
public async Task<ReadResult> ReadAsync(TextReader input, CancellationToken cancellationToken)
{
JsonNode jsonNode;

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

return await new AsyncApiJsonDocumentReader(this.settings).ReadAsync(jsonNode);
return await new AsyncApiJsonDocumentReader(this.settings).ReadAsync(jsonNode, cancellationToken);
}

/// <summary>
Expand Down
111 changes: 57 additions & 54 deletions src/LEGO.AsyncAPI.Readers/V2/AsyncApiV2VersionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,78 +54,81 @@ public AsyncApiReference ConvertToAsyncApiReference(
string reference,
ReferenceType? type)
{
if (!string.IsNullOrWhiteSpace(reference))
if (string.IsNullOrWhiteSpace(reference))
{
var segments = reference.Split('#');
if (segments.Length == 1)
throw new AsyncApiException($"The reference string '{reference}' has invalid format.");
}

var segments = reference.Split('#');
if (segments.Length == 1)
{
if (type == ReferenceType.SecurityScheme)
{
if (type == ReferenceType.SecurityScheme)
return new AsyncApiReference
{
return new AsyncApiReference
{
Type = type,
Id = reference,
};
}
Type = type,
Id = reference,
};
}

var asyncApiReference = new AsyncApiReference();
if (reference.StartsWith("/"))
{
asyncApiReference.IsFragment = true;
}
var asyncApiReference = new AsyncApiReference();
asyncApiReference.Type = type;
if (reference.StartsWith("/"))
{
asyncApiReference.IsFragment = true;
}

asyncApiReference.ExternalResource = segments[0];
asyncApiReference.ExternalResource = segments[0];

return asyncApiReference;
return asyncApiReference;

}
else if (segments.Length == 2)
}
else if (segments.Length == 2)
{
// Local reference
if (reference.StartsWith("#"))
{
// Local reference
if (reference.StartsWith("#"))
try
{
try
{
return this.ParseReference(segments[1]);
}
catch (AsyncApiException ex)
{
this.Diagnostic.Errors.Add(new AsyncApiError(ex));
return null;
}
return this.ParseReference(segments[1]);
}

var id = segments[1];
var asyncApiReference = new AsyncApiReference();
if (id.StartsWith("/components/"))
catch (AsyncApiException ex)
{
var localSegments = segments[1].Split('/');
var referencedType = localSegments[2].GetEnumFromDisplayName<ReferenceType>();
if (type == null)
{
type = referencedType;
}
else
{
if (type != referencedType)
{
throw new AsyncApiException("Referenced type mismatch");
}
}
this.Diagnostic.Errors.Add(new AsyncApiError(ex));
return null;
}
}

id = localSegments[3];
var id = segments[1];
var asyncApiReference = new AsyncApiReference();
if (id.StartsWith("/components/"))
{
var localSegments = segments[1].Split('/');
var referencedType = localSegments[2].GetEnumFromDisplayName<ReferenceType>();
if (type == null)
{
type = referencedType;
}
else
{
asyncApiReference.IsFragment = true;
if (type != referencedType)
{
throw new AsyncApiException("Referenced type mismatch");
}
}

asyncApiReference.ExternalResource = segments[0];
asyncApiReference.Type = type;
asyncApiReference.Id = id;

return asyncApiReference;
id = localSegments[3];
}
else
{
asyncApiReference.IsFragment = true;
}

asyncApiReference.ExternalResource = segments[0];
asyncApiReference.Type = type;
asyncApiReference.Id = id;

return asyncApiReference;
}

throw new AsyncApiException($"The reference string '{reference}' has invalid format.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void HttpMessageBinding_FilledObject_SerializesAndDeserializes()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Http);
settings.Bindings = BindingsCollection.Http;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiMessage>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down Expand Up @@ -73,7 +73,7 @@ public void HttpOperationBinding_FilledObject_SerializesAndDeserializes()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Http);
settings.Bindings = BindingsCollection.Http;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiOperation>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void KafkaChannelBinding_WithFilledObject_SerializesAndDeserializes()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Kafka);
settings.Bindings = BindingsCollection.Kafka;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down Expand Up @@ -92,7 +92,7 @@ public void KafkaServerBinding_WithFilledObject_SerializesAndDeserializes()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Kafka);
settings.Bindings = BindingsCollection.Kafka;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down Expand Up @@ -131,7 +131,7 @@ public void KafkaMessageBinding_WithFilledObject_SerializesAndDeserializes()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Kafka);
settings.Bindings = BindingsCollection.Kafka;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiMessage>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down Expand Up @@ -171,7 +171,7 @@ public void KafkaOperationBinding_WithFilledObject_SerializesAndDeserializes()
expected = expected.MakeLineBreaksEnvironmentNeutral();

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

// Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void PulsarChannelBinding_WithFilledObject_SerializesAndDeserializes()
expected = expected.MakeLineBreaksEnvironmentNeutral();

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

// Assert
Expand All @@ -80,7 +80,7 @@ public void PulsarChannelBindingNamespaceDefaultToNull()

// Act
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Pulsar);
settings.Bindings = BindingsCollection.Pulsar;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>(actual, AsyncApiVersion.AsyncApi2_0, out _);

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

Expand Down Expand Up @@ -139,7 +139,7 @@ public void PulsarServerBinding_WithFilledObject_SerializesAndDeserializes()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Pulsar);
settings.Bindings = BindingsCollection.Pulsar;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down Expand Up @@ -175,7 +175,7 @@ public void ServerBindingVersionDefaultsToNull()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Pulsar);
settings.Bindings = BindingsCollection.Pulsar;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down Expand Up @@ -212,7 +212,7 @@ public void ServerTenantDefaultsToNull()
actual = actual.MakeLineBreaksEnvironmentNeutral();
expected = expected.MakeLineBreaksEnvironmentNeutral();
var settings = new AsyncApiReaderSettings();
settings.Bindings.Add(BindingsCollection.Pulsar);
settings.Bindings = BindingsCollection.Pulsar;
var binding = new AsyncApiStringReader(settings).ReadFragment<AsyncApiServer>(actual, AsyncApiVersion.AsyncApi2_0, out _);

// Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void WebSocketChannelBinding_WithFilledObject_SerializesAndDeserializes()
expected = expected.MakeLineBreaksEnvironmentNeutral();

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

// Assert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ public void AsyncApiMessage_WithFilledObject_Serializes()
expected = expected.MakeLineBreaksEnvironmentNeutral();

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

// Assert
Expand Down
5 changes: 3 additions & 2 deletions test/LEGO.AsyncAPI.Tests/Models/AsyncApiReference_Should.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void AsyncApiReference_WithExternalFragmentUriReference_AllowReference()
reference.Id.Should().Be("/path/to/external/fragment");
reference.IsFragment.Should().BeTrue();
reference.IsExternal.Should().BeTrue();

reference.Type.Should().Be(ReferenceType.Schema);
var serialized = deserialized.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
actual = actual.MakeLineBreaksEnvironmentNeutral();
var expected = serialized.MakeLineBreaksEnvironmentNeutral();
Expand All @@ -54,6 +54,7 @@ public void AsyncApiReference_WithFragmentReference_AllowReference()
deserialized.Payload.UnresolvedReference.Should().BeTrue();

var reference = deserialized.Payload.Reference;
reference.Type.Should().Be(ReferenceType.Schema);
reference.ExternalResource.Should().Be("/fragments/myFragment");
reference.Id.Should().BeNull();
reference.IsFragment.Should().BeTrue();
Expand Down Expand Up @@ -206,10 +207,10 @@ public void AsyncApiDocument_WithExternalReference_DoesNotResolve()
channel.UnresolvedReference.Should().BeTrue();
channel.Description.Should().BeNull();
channel.Reference.ExternalResource.Should().Be("http://example.com/channel.json");
channel.Reference.Type.Should().Be(ReferenceType.Channel);
channel.Reference.Id.Should().BeNull();
channel.Reference.IsExternal.Should().BeTrue();
channel.Reference.IsFragment.Should().BeFalse();
channel.Reference.Type.Should().BeNull();
}

[Test]
Expand Down
Loading