From fb50d00192896f9ac26e65df1e991854b33aa17c Mon Sep 17 00:00:00 2001
From: Dec Kolakowski <51292634+dpwdec@users.noreply.github.com>
Date: Tue, 9 Jul 2024 14:44:14 +0100
Subject: [PATCH 01/18] =?UTF-8?q?fix:=20correct=20typing=20of=20exclusive?=
=?UTF-8?q?=20maximums=20and=20minimums=20for=20draft7=20jso=E2=80=A6=20(#?=
=?UTF-8?q?188)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../V2/AsyncApiSchemaDeserializer.cs | 10 ++++++++--
src/LEGO.AsyncAPI/Models/AsyncApiSchema.cs | 4 ++--
.../Models/AsyncApiSchema_Should.cs | 10 +++++-----
3 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/src/LEGO.AsyncAPI.Readers/V2/AsyncApiSchemaDeserializer.cs b/src/LEGO.AsyncAPI.Readers/V2/AsyncApiSchemaDeserializer.cs
index b99fdef8..1934cb0d 100644
--- a/src/LEGO.AsyncAPI.Readers/V2/AsyncApiSchemaDeserializer.cs
+++ b/src/LEGO.AsyncAPI.Readers/V2/AsyncApiSchemaDeserializer.cs
@@ -61,7 +61,10 @@ public class JsonSchemaDeserializer
}
},
{
- "exclusiveMaximum", (a, n) => { a.ExclusiveMaximum = bool.Parse(n.GetScalarValue()); }
+ "exclusiveMaximum", (a, n) =>
+ {
+ a.ExclusiveMaximum = double.Parse(n.GetScalarValue(), NumberStyles.Float, n.Context.Settings.CultureInfo);
+ }
},
{
"minimum",
@@ -71,7 +74,10 @@ public class JsonSchemaDeserializer
}
},
{
- "exclusiveMinimum", (a, n) => { a.ExclusiveMinimum = bool.Parse(n.GetScalarValue()); }
+ "exclusiveMinimum", (a, n) =>
+ {
+ a.ExclusiveMinimum = double.Parse(n.GetScalarValue(), NumberStyles.Float, n.Context.Settings.CultureInfo);
+ }
},
{
"maxLength", (a, n) => { a.MaxLength = int.Parse(n.GetScalarValue(), n.Context.Settings.CultureInfo); }
diff --git a/src/LEGO.AsyncAPI/Models/AsyncApiSchema.cs b/src/LEGO.AsyncAPI/Models/AsyncApiSchema.cs
index 3244017b..0931c953 100644
--- a/src/LEGO.AsyncAPI/Models/AsyncApiSchema.cs
+++ b/src/LEGO.AsyncAPI/Models/AsyncApiSchema.cs
@@ -42,7 +42,7 @@ public class AsyncApiSchema : IAsyncApiReferenceable, IAsyncApiExtensible, IAsyn
///
/// follow JSON Schema definition: https://json-schema.org/draft-07/json-schema-release-notes.html.
///
- public bool? ExclusiveMaximum { get; set; }
+ public double? ExclusiveMaximum { get; set; }
///
/// follow JSON Schema definition: https://json-schema.org/draft-07/json-schema-release-notes.html.
@@ -52,7 +52,7 @@ public class AsyncApiSchema : IAsyncApiReferenceable, IAsyncApiExtensible, IAsyn
///
/// follow JSON Schema definition: https://json-schema.org/draft-07/json-schema-release-notes.html.
///
- public bool? ExclusiveMinimum { get; set; }
+ public double? ExclusiveMinimum { get; set; }
///
/// follow JSON Schema definition: https://json-schema.org/draft-07/json-schema-release-notes.html.
diff --git a/test/LEGO.AsyncAPI.Tests/Models/AsyncApiSchema_Should.cs b/test/LEGO.AsyncAPI.Tests/Models/AsyncApiSchema_Should.cs
index 830a44bc..ec7c023f 100644
--- a/test/LEGO.AsyncAPI.Tests/Models/AsyncApiSchema_Should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Models/AsyncApiSchema_Should.cs
@@ -21,7 +21,7 @@ public class AsyncApiSchema_Should : TestBase
Title = "title1",
MultipleOf = 3,
Maximum = 42,
- ExclusiveMinimum = true,
+ ExclusiveMinimum = 42,
Minimum = 10,
Default = new AsyncApiAny(15),
Type = SchemaType.Integer,
@@ -37,7 +37,7 @@ public class AsyncApiSchema_Should : TestBase
Title = "title1",
MultipleOf = 3,
Maximum = double.MaxValue,
- ExclusiveMinimum = true,
+ ExclusiveMinimum = double.MinValue,
Minimum = double.MinValue,
Default = new AsyncApiAny(15),
Type = SchemaType.Integer,
@@ -211,7 +211,7 @@ public class AsyncApiSchema_Should : TestBase
Title = "title1",
MultipleOf = 3,
Maximum = 42,
- ExclusiveMinimum = true,
+ ExclusiveMinimum = 42,
Minimum = 10,
Default = new AsyncApiAny(15),
Type = SchemaType.Integer,
@@ -307,7 +307,7 @@ public void SerializeAsJson_WithAdvancedSchemaNumber_V2Works()
"type": "integer",
"maximum": 42,
"minimum": 10,
- "exclusiveMinimum": true,
+ "exclusiveMinimum": 42,
"multipleOf": 3,
"default": 15,
"nullable": true,
@@ -335,7 +335,7 @@ public void SerializeAsJson_WithAdvancedSchemaBigNumbers_V2Works()
"type": "integer",
"maximum": 1.7976931348623157E+308,
"minimum": -1.7976931348623157E+308,
- "exclusiveMinimum": true,
+ "exclusiveMinimum": -1.7976931348623157E+308,
"multipleOf": 3,
"default": 15,
"nullable": true,
From a554e419149b261ab8b5768743921614131a9270 Mon Sep 17 00:00:00 2001
From: Alex Wichmann
Date: Mon, 29 Jul 2024 11:49:38 +0200
Subject: [PATCH 02/18] refactor: improve bindings TryGetValue (#190)
---
...dings.cs => AsyncApiBindings{TBinding}.cs} | 27 ------
src/LEGO.AsyncAPI/Models/BindingExtensions.cs | 62 +++++++++++++
.../Bindings/BindingExtensions_Should.cs | 89 +++++++++++++++++++
.../WebSockets/WebSocketBindings_Should.cs | 4 +-
4 files changed, 153 insertions(+), 29 deletions(-)
rename src/LEGO.AsyncAPI/Models/{AsyncApiBindings.cs => AsyncApiBindings{TBinding}.cs} (57%)
create mode 100644 src/LEGO.AsyncAPI/Models/BindingExtensions.cs
create mode 100644 test/LEGO.AsyncAPI.Tests/Bindings/BindingExtensions_Should.cs
diff --git a/src/LEGO.AsyncAPI/Models/AsyncApiBindings.cs b/src/LEGO.AsyncAPI/Models/AsyncApiBindings{TBinding}.cs
similarity index 57%
rename from src/LEGO.AsyncAPI/Models/AsyncApiBindings.cs
rename to src/LEGO.AsyncAPI/Models/AsyncApiBindings{TBinding}.cs
index 6aaa389a..f11858aa 100644
--- a/src/LEGO.AsyncAPI/Models/AsyncApiBindings.cs
+++ b/src/LEGO.AsyncAPI/Models/AsyncApiBindings{TBinding}.cs
@@ -7,33 +7,6 @@ namespace LEGO.AsyncAPI.Models
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Writers;
- public static class BindingExtensions
- {
- public static bool TryGetValue(this AsyncApiBindings bindings, out IServerBinding binding)
- where TBinding : IServerBinding
- {
- return bindings.TryGetValue(Activator.CreateInstance().BindingKey, out binding);
- }
-
- public static bool TryGetValue(this AsyncApiBindings bindings, out IChannelBinding binding)
- where TBinding : IChannelBinding
- {
- return bindings.TryGetValue(Activator.CreateInstance().BindingKey, out binding);
- }
-
- public static bool TryGetValue(this AsyncApiBindings bindings, out IOperationBinding binding)
- where TBinding : IOperationBinding
- {
- return bindings.TryGetValue(Activator.CreateInstance().BindingKey, out binding);
- }
-
- public static bool TryGetValue(this AsyncApiBindings bindings, out IMessageBinding binding)
- where TBinding : IMessageBinding
- {
- return bindings.TryGetValue(Activator.CreateInstance().BindingKey, out binding);
- }
- }
-
public class AsyncApiBindings : Dictionary, IAsyncApiReferenceable
where TBinding : IBinding
{
diff --git a/src/LEGO.AsyncAPI/Models/BindingExtensions.cs b/src/LEGO.AsyncAPI/Models/BindingExtensions.cs
new file mode 100644
index 00000000..3bcab20f
--- /dev/null
+++ b/src/LEGO.AsyncAPI/Models/BindingExtensions.cs
@@ -0,0 +1,62 @@
+// Copyright (c) The LEGO Group. All rights reserved.
+
+namespace LEGO.AsyncAPI.Models
+{
+ using System;
+ using LEGO.AsyncAPI.Models.Interfaces;
+
+ public static class BindingExtensions
+ {
+ public static bool TryGetValue(this AsyncApiBindings bindings, out TBinding binding)
+ where TBinding : class, IServerBinding
+ {
+ if (bindings.TryGetValue(Activator.CreateInstance().BindingKey, out var serverBinding))
+ {
+ binding = serverBinding as TBinding;
+ return true;
+ }
+
+ binding = default;
+ return false;
+ }
+
+ public static bool TryGetValue(this AsyncApiBindings bindings, out TBinding binding)
+ where TBinding : class, IChannelBinding
+ {
+ if (bindings.TryGetValue(Activator.CreateInstance().BindingKey, out var channelBinding))
+ {
+ binding = channelBinding as TBinding;
+ return true;
+ }
+
+ binding = default;
+ return false;
+ }
+
+ public static bool TryGetValue(this AsyncApiBindings bindings, out TBinding binding)
+ where TBinding : class, IOperationBinding
+ {
+ if (bindings.TryGetValue(Activator.CreateInstance().BindingKey, out var operationBinding))
+ {
+ binding = operationBinding as TBinding;
+ return true;
+ }
+
+ binding = default;
+ return false;
+ }
+
+ public static bool TryGetValue(this AsyncApiBindings bindings, out TBinding binding)
+ where TBinding : class, IMessageBinding
+ {
+ if (bindings.TryGetValue(Activator.CreateInstance().BindingKey, out var messageBinding))
+ {
+ binding = messageBinding as TBinding;
+ return true;
+ }
+
+ binding = default;
+ return false;
+ }
+ }
+}
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/BindingExtensions_Should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/BindingExtensions_Should.cs
new file mode 100644
index 00000000..3806fc03
--- /dev/null
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/BindingExtensions_Should.cs
@@ -0,0 +1,89 @@
+// Copyright (c) The LEGO Group. All rights reserved.
+
+namespace LEGO.AsyncAPI.Tests.Bindings.WebSockets
+{
+ using System.Linq;
+ using FluentAssertions;
+ using LEGO.AsyncAPI.Bindings.MQTT;
+ using LEGO.AsyncAPI.Bindings.Pulsar;
+ using LEGO.AsyncAPI.Bindings.WebSockets;
+ using LEGO.AsyncAPI.Models;
+ using NUnit.Framework;
+
+ public class BindingExtensions_Should
+ {
+ [Test]
+ public void TryGetValue_WithChannelBinding_ReturnsBinding()
+ {
+ var channel = new AsyncApiChannel();
+ channel.Bindings.Add(new WebSocketsChannelBinding
+ {
+ Method = "POST",
+ Query = new AsyncApiSchema
+ {
+ Description = "this mah query",
+ },
+ Headers = new AsyncApiSchema
+ {
+ Description = "this mah binding",
+ },
+ });
+
+ var result = channel.Bindings.TryGetValue(out var channelBinding);
+ result.Should().BeTrue();
+ channelBinding.Should().NotBeNull();
+ channelBinding.Should().BeEquivalentTo(channel.Bindings.First().Value);
+ }
+
+ [Test]
+ public void TryGetValue_WithServerBinding_ReturnsBinding()
+ {
+ var server = new AsyncApiServer();
+ server.Bindings.Add(new PulsarServerBinding
+ {
+ Tenant = "test tenant",
+ });
+
+ var result = server.Bindings.TryGetValue(out var serverBinding);
+ result.Should().BeTrue();
+ serverBinding.Should().NotBeNull();
+ serverBinding.Should().BeEquivalentTo(server.Bindings.First().Value);
+ }
+
+ [Test]
+ public void TryGetValue_WithOperationBinding_ReturnsBinding()
+ {
+ var operation = new AsyncApiOperation();
+ operation.Bindings.Add(new MQTTOperationBinding
+ {
+ QoS = 23,
+ MessageExpiryInterval = 1,
+ Retain = true,
+ });
+
+ var result = operation.Bindings.TryGetValue(out var operationBinding);
+ result.Should().BeTrue();
+ operationBinding.Should().NotBeNull();
+ operationBinding.Should().BeEquivalentTo(operation.Bindings.First().Value);
+ }
+
+ [Test]
+ public void TryGetValue_WithMessageBinding_ReturnsBinding()
+ {
+ var message = new AsyncApiMessage();
+ message.Bindings.Add(new MQTTMessageBinding
+ {
+ PayloadFormatIndicator = 2,
+ CorrelationData = new AsyncApiSchema
+ {
+ Description = "Test",
+ },
+ });
+
+ var result = message.Bindings.TryGetValue(out var messageBinding);
+ result.Should().BeTrue();
+ messageBinding.Should().NotBeNull();
+ messageBinding.Should().BeEquivalentTo(message.Bindings.First().Value);
+ }
+ }
+}
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/WebSockets/WebSocketBindings_Should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/WebSockets/WebSocketBindings_Should.cs
index b8aef976..c37ada58 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/WebSockets/WebSocketBindings_Should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/WebSockets/WebSocketBindings_Should.cs
@@ -8,8 +8,8 @@ namespace LEGO.AsyncAPI.Tests.Bindings.WebSockets
using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Readers;
using NUnit.Framework;
-
- internal class WebSocketBindings_Should : TestBase
+
+ public class WebSocketBindings_Should : TestBase
{
[Test]
public void WebSocketChannelBinding_WithFilledObject_SerializesAndDeserializes()
From e1830b99d41076b236759354b086d5872d5d70ce Mon Sep 17 00:00:00 2001
From: "lego-10-01-06[bot]"
<119427331+lego-10-01-06[bot]@users.noreply.github.com>
Date: Mon, 29 Jul 2024 09:50:34 +0000
Subject: [PATCH 03/18] chore: update CHANGELOG.md
---
CHANGELOG.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 505c9b09..c2b85fba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+## [5.2.2](https://github.com/LEGO/AsyncAPI.NET/compare/v5.2.1...v5.2.2) (2024-07-29)
+
+
+### Bug Fixes
+
+* correct typing of exclusive maximums and minimums for draft7 jso… ([#188](https://github.com/LEGO/AsyncAPI.NET/issues/188)) ([fb50d00](https://github.com/LEGO/AsyncAPI.NET/commit/fb50d00192896f9ac26e65df1e991854b33aa17c))
+* resolving wrong reference ([#180](https://github.com/LEGO/AsyncAPI.NET/issues/180)) ([47685cd](https://github.com/LEGO/AsyncAPI.NET/commit/47685cd19c7e58391625be043b1e5d82c49eedc8))
+
## [5.2.1](https://github.com/LEGO/AsyncAPI.NET/compare/v5.2.0...v5.2.1) (2024-06-12)
From b8307c57a6f9bc7c546702c24dffdfb1833aa5d3 Mon Sep 17 00:00:00 2001
From: Alex Wichmann
Date: Mon, 29 Jul 2024 13:58:02 +0200
Subject: [PATCH 04/18] fix: add missing walk and visit methods for bindings.
(#191)
---
.../Services/AsyncApiVisitorBase.cs | 32 +++++
src/LEGO.AsyncAPI/Services/AsyncApiWalker.cs | 127 ++++++++++++++++--
src/LEGO.AsyncAPI/Services/CurrentKeys.cs | 8 +-
.../Validation/AsyncApiValidator.cs | 8 ++
4 files changed, 165 insertions(+), 10 deletions(-)
diff --git a/src/LEGO.AsyncAPI/Services/AsyncApiVisitorBase.cs b/src/LEGO.AsyncAPI/Services/AsyncApiVisitorBase.cs
index 8e3dc241..899731d0 100644
--- a/src/LEGO.AsyncAPI/Services/AsyncApiVisitorBase.cs
+++ b/src/LEGO.AsyncAPI/Services/AsyncApiVisitorBase.cs
@@ -246,6 +246,38 @@ public virtual void Visit(IDictionary channels)
{
}
+ public virtual void Visit(AsyncApiBindings bindings)
+ {
+ }
+
+ public virtual void Visit(IServerBinding binding)
+ {
+ }
+
+ public virtual void Visit(AsyncApiBindings bindings)
+ {
+ }
+
+ public virtual void Visit(IChannelBinding binding)
+ {
+ }
+
+ public virtual void Visit(AsyncApiBindings bindings)
+ {
+ }
+
+ public virtual void Visit(IOperationBinding binding)
+ {
+ }
+
+ public virtual void Visit(AsyncApiBindings bindings)
+ {
+ }
+
+ public virtual void Visit(IMessageBinding binding)
+ {
+ }
+
public virtual void Visit(AsyncApiChannel channel)
{
}
diff --git a/src/LEGO.AsyncAPI/Services/AsyncApiWalker.cs b/src/LEGO.AsyncAPI/Services/AsyncApiWalker.cs
index fc5c5186..844ab7e9 100644
--- a/src/LEGO.AsyncAPI/Services/AsyncApiWalker.cs
+++ b/src/LEGO.AsyncAPI/Services/AsyncApiWalker.cs
@@ -74,15 +74,48 @@ internal void Walk(AsyncApiComponents components)
});
this.Walk(AsyncApiConstants.ServerBindings, () =>
- {
- if (components.ServerBindings != null)
- {
- foreach (var item in components.ServerBindings)
- {
- this.Walk(item.Key, () => this.Walk(item.Value, isComponent: true));
- }
- }
- });
+ {
+ if (components.ServerBindings != null)
+ {
+ foreach (var item in components.ServerBindings)
+ {
+ this.Walk(item.Key, () => this.Walk(item.Value, isComponent: true));
+ }
+ }
+ });
+
+ this.Walk(AsyncApiConstants.ChannelBindings, () =>
+ {
+ if (components.ChannelBindings != null)
+ {
+ foreach (var item in components.ChannelBindings)
+ {
+ this.Walk(item.Key, () => this.Walk(item.Value, isComponent: true));
+ }
+ }
+ });
+
+ this.Walk(AsyncApiConstants.OperationBindings, () =>
+ {
+ if (components.OperationBindings != null)
+ {
+ foreach (var item in components.OperationBindings)
+ {
+ this.Walk(item.Key, () => this.Walk(item.Value, isComponent: true));
+ }
+ }
+ });
+
+ this.Walk(AsyncApiConstants.MessageBindings, () =>
+ {
+ if (components.MessageBindings != null)
+ {
+ foreach (var item in components.MessageBindings)
+ {
+ this.Walk(item.Key, () => this.Walk(item.Value, isComponent: true));
+ }
+ }
+ });
this.Walk(AsyncApiConstants.Parameters, () =>
{
@@ -562,6 +595,25 @@ internal void Walk(AsyncApiBindings serverBindings, bool isCompo
}
this.visitor.Visit(serverBindings);
+ if (serverBindings != null)
+ {
+ foreach (var binding in serverBindings)
+ {
+ this.visitor.CurrentKeys.ServerBinding = binding.Key;
+ this.Walk(binding.Key, () => this.Walk(binding.Value));
+ this.visitor.CurrentKeys.ServerBinding = null;
+ }
+ }
+ }
+
+ internal void Walk(IServerBinding binding)
+ {
+ if (binding == null)
+ {
+ return;
+ }
+
+ this.visitor.Visit(binding);
}
internal void Walk(AsyncApiBindings channelBindings, bool isComponent = false)
@@ -572,6 +624,25 @@ internal void Walk(AsyncApiBindings channelBindings, bool isCom
}
this.visitor.Visit(channelBindings);
+ if (channelBindings != null)
+ {
+ foreach (var binding in channelBindings)
+ {
+ this.visitor.CurrentKeys.ChannelBinding = binding.Key;
+ this.Walk(binding.Key, () => this.Walk(binding.Value));
+ this.visitor.CurrentKeys.ChannelBinding = null;
+ }
+ }
+ }
+
+ internal void Walk(IChannelBinding binding)
+ {
+ if (binding == null)
+ {
+ return;
+ }
+
+ this.visitor.Visit(binding);
}
internal void Walk(AsyncApiBindings operationBindings, bool isComponent = false)
@@ -582,6 +653,25 @@ internal void Walk(AsyncApiBindings operationBindings, bool i
}
this.visitor.Visit(operationBindings);
+ if (operationBindings != null)
+ {
+ foreach (var binding in operationBindings)
+ {
+ this.visitor.CurrentKeys.OperationBinding = binding.Key;
+ this.Walk(binding.Key, () => this.Walk(binding.Value));
+ this.visitor.CurrentKeys.OperationBinding = null;
+ }
+ }
+ }
+
+ internal void Walk(IOperationBinding binding)
+ {
+ if (binding == null)
+ {
+ return;
+ }
+
+ this.visitor.Visit(binding);
}
internal void Walk(AsyncApiBindings messageBindings, bool isComponent = false)
@@ -592,6 +682,25 @@ internal void Walk(AsyncApiBindings messageBindings, bool isCom
}
this.visitor.Visit(messageBindings);
+ if (messageBindings != null)
+ {
+ foreach (var binding in messageBindings)
+ {
+ this.visitor.CurrentKeys.MessageBinding = binding.Key;
+ this.Walk(binding.Key, () => this.Walk(binding.Value));
+ this.visitor.CurrentKeys.MessageBinding = null;
+ }
+ }
+ }
+
+ internal void Walk(IMessageBinding binding)
+ {
+ if (binding == null)
+ {
+ return;
+ }
+
+ this.visitor.Visit(binding);
}
internal void Walk(IList examples)
diff --git a/src/LEGO.AsyncAPI/Services/CurrentKeys.cs b/src/LEGO.AsyncAPI/Services/CurrentKeys.cs
index 3544eb21..f610aabb 100644
--- a/src/LEGO.AsyncAPI/Services/CurrentKeys.cs
+++ b/src/LEGO.AsyncAPI/Services/CurrentKeys.cs
@@ -4,7 +4,13 @@ namespace LEGO.AsyncAPI.Services
{
public class CurrentKeys
{
- public string ServerBindings { get; internal set; }
+ public string ServerBinding { get; internal set; }
+
+ public string ChannelBinding { get; internal set; }
+
+ public string OperationBinding { get; internal set; }
+
+ public string MessageBinding { get; internal set; }
public string Channel { get; internal set; }
diff --git a/src/LEGO.AsyncAPI/Validation/AsyncApiValidator.cs b/src/LEGO.AsyncAPI/Validation/AsyncApiValidator.cs
index 4ce96627..3f8bf392 100644
--- a/src/LEGO.AsyncAPI/Validation/AsyncApiValidator.cs
+++ b/src/LEGO.AsyncAPI/Validation/AsyncApiValidator.cs
@@ -136,6 +136,14 @@ public void AddWarning(AsyncApiValidatorWarning warning)
/// The object to be validated.
public override void Visit(AsyncApiServer item) => this.Validate(item);
+ public override void Visit(IServerBinding item) => this.Validate(item);
+
+ public override void Visit(IChannelBinding item) => this.Validate(item);
+
+ public override void Visit(IOperationBinding item) => this.Validate(item);
+
+ public override void Visit(IMessageBinding item) => this.Validate(item);
+
///
/// Execute validation rules against an .
///
From ba16297b2e4ba96b4259a2e85033894360593405 Mon Sep 17 00:00:00 2001
From: "lego-10-01-06[bot]"
<119427331+lego-10-01-06[bot]@users.noreply.github.com>
Date: Mon, 29 Jul 2024 11:59:34 +0000
Subject: [PATCH 05/18] chore: update CHANGELOG.md
---
CHANGELOG.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c2b85fba..e8d4454c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## [5.2.3](https://github.com/LEGO/AsyncAPI.NET/compare/v5.2.2...v5.2.3) (2024-07-29)
+
+
+### Bug Fixes
+
+* add missing walk and visit methods for bindings. ([#191](https://github.com/LEGO/AsyncAPI.NET/issues/191)) ([b8307c5](https://github.com/LEGO/AsyncAPI.NET/commit/b8307c57a6f9bc7c546702c24dffdfb1833aa5d3))
+
## [5.2.2](https://github.com/LEGO/AsyncAPI.NET/compare/v5.2.1...v5.2.2) (2024-07-29)
From 52165f213502d9436e25a4e761804b5796b5de8c Mon Sep 17 00:00:00 2001
From: VisualBean
Date: Mon, 29 Jul 2024 14:54:58 +0200
Subject: [PATCH 06/18] fix: remove persistence nullability
---
.../Pulsar/PulsarChannelBinding.cs | 2 +-
.../Bindings/Pulsar/PulsarBindings_Should.cs | 27 -------------------
2 files changed, 1 insertion(+), 28 deletions(-)
diff --git a/src/LEGO.AsyncAPI.Bindings/Pulsar/PulsarChannelBinding.cs b/src/LEGO.AsyncAPI.Bindings/Pulsar/PulsarChannelBinding.cs
index c673a8e8..88435b74 100644
--- a/src/LEGO.AsyncAPI.Bindings/Pulsar/PulsarChannelBinding.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Pulsar/PulsarChannelBinding.cs
@@ -19,7 +19,7 @@ public class PulsarChannelBinding : ChannelBinding
///
/// persistence of the topic in Pulsar persistent or non-persistent.
///
- public Persistence? Persistence { get; set; }
+ public Persistence Persistence { get; set; }
///
/// Topic compaction threshold given in bytes.
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/Pulsar/PulsarBindings_Should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/Pulsar/PulsarBindings_Should.cs
index e8a80ac1..7e69a0b7 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/Pulsar/PulsarBindings_Should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/Pulsar/PulsarBindings_Should.cs
@@ -88,33 +88,6 @@ public void PulsarChannelBindingNamespaceDefaultToNull()
Assert.AreEqual(null, ((PulsarChannelBinding)binding.Bindings["pulsar"]).Namespace);
}
- [Test]
- public void PulsarChannelBindingPropertiesExceptNamespaceDefaultToNull()
- {
- // Arrange
- var actual =
- """
- bindings:
- pulsar:
- namespace: staging
- """;
-
- // Act
- // Assert
- var settings = new AsyncApiReaderSettings();
- settings.Bindings = BindingsCollection.Pulsar;
- var binding = new AsyncApiStringReader(settings).ReadFragment(actual, AsyncApiVersion.AsyncApi2_0, out _);
- var pulsarBinding = ((PulsarChannelBinding)binding.Bindings["pulsar"]);
-
- Assert.AreEqual("staging", pulsarBinding.Namespace);
- Assert.AreEqual(null, pulsarBinding.Persistence);
- Assert.AreEqual(null, pulsarBinding.Compaction);
- Assert.AreEqual(null, pulsarBinding.GeoReplication);
- Assert.AreEqual(null, pulsarBinding.Retention);
- Assert.AreEqual(null, pulsarBinding.TTL);
- Assert.AreEqual(null, pulsarBinding.Deduplication);
- }
-
[Test]
public void PulsarServerBinding_WithFilledObject_SerializesAndDeserializes()
{
From c90f41ddee9cb3b358469c17abe932caa6cce0db Mon Sep 17 00:00:00 2001
From: "lego-10-01-06[bot]"
<119427331+lego-10-01-06[bot]@users.noreply.github.com>
Date: Mon, 29 Jul 2024 13:02:21 +0000
Subject: [PATCH 07/18] chore: update CHANGELOG.md
---
CHANGELOG.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8d4454c..7dea98ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## [5.2.4](https://github.com/LEGO/AsyncAPI.NET/compare/v5.2.3...v5.2.4) (2024-07-29)
+
+
+### Bug Fixes
+
+* remove persistence nullability ([52165f2](https://github.com/LEGO/AsyncAPI.NET/commit/52165f213502d9436e25a4e761804b5796b5de8c))
+
## [5.2.3](https://github.com/LEGO/AsyncAPI.NET/compare/v5.2.2...v5.2.3) (2024-07-29)
From 129622a33c0428e172bdeebce6819b0802d871f1 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 12 Aug 2024 11:09:32 +0200
Subject: [PATCH 08/18] chore(deps): bump System.Text.Json from 8.0.2 to 8.0.4
in /src/LEGO.AsyncAPI (#189)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex Wichmann
---
src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj b/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj
index 560c0f98..99e69016 100644
--- a/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj
+++ b/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj
@@ -19,7 +19,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
<_Parameter1>$(MSBuildProjectName).Tests
From 9cc759fde50fcc02185ddd9200ce8ab0b3f80584 Mon Sep 17 00:00:00 2001
From: Adam Gloyne <44494964+Gadam8@users.noreply.github.com>
Date: Thu, 15 Aug 2024 16:44:45 +0100
Subject: [PATCH 09/18] feat: extend AWS policy (#187)
---
src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs | 63 ++++++++++++
.../Sns/PrincipalObject.cs | 27 ++++++
.../Sns/PrincipalStar.cs | 24 +++++
.../Sns/SnsChannelBinding.cs | 4 +-
src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs | 26 +++--
src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs | 65 +++++++++++++
.../Sqs/PrincipalObject.cs | 27 ++++++
.../Sqs/PrincipalStar.cs | 24 +++++
.../Sqs/SqsChannelBinding.cs | 4 +-
.../Sqs/SqsOperationBinding.cs | 4 +-
src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs | 25 ++++-
.../StringOrStringList.cs | 4 +-
.../Bindings/Sns/SnsBindings_Should.cs | 57 ++++++++---
.../Bindings/Sqs/SqsBindings_should.cs | 96 ++++++++++++++-----
14 files changed, 395 insertions(+), 55 deletions(-)
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs b/src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs
new file mode 100644
index 00000000..a803f6c2
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/Principal.cs
@@ -0,0 +1,63 @@
+namespace LEGO.AsyncAPI.Bindings.Sns;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using LEGO.AsyncAPI.Models.Interfaces;
+using LEGO.AsyncAPI.Readers.ParseNodes;
+using LEGO.AsyncAPI.Writers;
+
+public abstract class Principal : IAsyncApiElement
+{
+ public abstract void Serialize(IAsyncApiWriter writer);
+
+ public static Principal Parse(ParseNode node)
+ {
+ switch (node)
+ {
+ case ValueNode:
+ var nodeValue = node.GetScalarValue();
+ if (!IsStarString(nodeValue))
+ {
+ throw new ArgumentException($"An error occured while parsing a {nameof(Principal)} node. " +
+ $"Principal value without a property name can only be a string value of '*'.");
+ }
+
+ return new PrincipalStar();
+
+ case MapNode mapNode:
+ {
+ var propertyNode = mapNode.First();
+ if (!IsValidPrincipalProperty(propertyNode.Name))
+ {
+ throw new ArgumentException($"An error occured while parsing a {nameof(Principal)} node. " +
+ $"Node should contain a valid AWS principal property name.");
+ }
+
+ var principalValue = new KeyValuePair(
+ propertyNode.Name,
+ StringOrStringList.Parse(propertyNode.Value));
+
+ return new PrincipalObject(principalValue);
+ }
+
+ default:
+ throw new ArgumentException($"An error occured while parsing a {nameof(Principal)} node. " +
+ $"Node should contain a string value of '*' or a valid AWS principal property.");
+ }
+ }
+
+ private static bool IsStarString(JsonNode value)
+ {
+ var element = JsonDocument.Parse(value.ToJsonString()).RootElement;
+
+ return element.ValueKind == JsonValueKind.String && element.ValueEquals("*");
+ }
+
+ private static bool IsValidPrincipalProperty(string property)
+ {
+ return new[] { "AWS", "Service" }.Contains(property);
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
new file mode 100644
index 00000000..a25c198f
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
@@ -0,0 +1,27 @@
+namespace LEGO.AsyncAPI.Bindings.Sns;
+
+using System;
+using System.Collections.Generic;
+using LEGO.AsyncAPI.Writers;
+
+public class PrincipalObject : Principal
+{
+ private KeyValuePair PrincipalValue;
+
+ public PrincipalObject(KeyValuePair principalValue)
+ {
+ this.PrincipalValue = principalValue;
+ }
+
+ public override void Serialize(IAsyncApiWriter writer)
+ {
+ if (writer is null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+
+ writer.WriteStartObject();
+ writer.WriteRequiredObject(this.PrincipalValue.Key, this.PrincipalValue.Value, (w, t) => t.Value.Write(w));
+ writer.WriteEndObject();
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
new file mode 100644
index 00000000..533e9fb7
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
@@ -0,0 +1,24 @@
+namespace LEGO.AsyncAPI.Bindings.Sns;
+
+using System;
+using LEGO.AsyncAPI.Writers;
+
+public class PrincipalStar : Principal
+{
+ private string PrincipalValue;
+
+ public PrincipalStar()
+ {
+ this.PrincipalValue = "*";
+ }
+
+ public override void Serialize(IAsyncApiWriter writer)
+ {
+ if (writer is null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+
+ writer.WriteValue(this.PrincipalValue);
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs b/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs
index 13676168..4d8668c9 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs
@@ -57,8 +57,10 @@ public class SnsChannelBinding : ChannelBinding
private static FixedFieldMap statementFixedFields = new()
{
{ "effect", (a, n) => { a.Effect = n.GetScalarValue().GetEnumFromDisplayName(); } },
- { "principal", (a, n) => { a.Principal = StringOrStringList.Parse(n); } },
+ { "principal", (a, n) => { a.Principal = Principal.Parse(n); } },
{ "action", (a, n) => { a.Action = StringOrStringList.Parse(n); } },
+ { "resource", (a, n) => { a.Resource = StringOrStringList.Parse(n); } },
+ { "condition", (a, n) => { a.Condition = n.CreateAny(); } },
};
///
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs b/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
index 7f3771f0..170fe371 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
@@ -1,28 +1,40 @@
// Copyright (c) The LEGO Group. All rights reserved.
-
namespace LEGO.AsyncAPI.Bindings.Sns
{
using System;
using System.Collections.Generic;
using LEGO.AsyncAPI.Attributes;
+ using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Writers;
public class Statement : IAsyncApiExtensible
{
+ ///
+ /// Indicates whether the policy allows or denies access.
+ ///
public Effect Effect { get; set; }
///
- /// The AWS account or resource ARN that this statement applies to.
+ /// The AWS account(s) or resource ARN(s) that this statement applies to.
///
- // public StringOrStringList Principal { get; set; }
- public StringOrStringList Principal { get; set; }
+ public Principal Principal { get; set; }
///
- /// The SNS permission being allowed or denied e.g. sns:Publish
+ /// The SNS permission being allowed or denied e.g. sns:Publish.
///
public StringOrStringList Action { get; set; }
+ ///
+ /// The resource(s) that this policy applies to.
+ ///
+ public StringOrStringList? Resource { get; set; }
+
+ ///
+ /// Specific circumstances under which the policy grants permission.
+ ///
+ public AsyncApiAny? Condition { get; set; }
+
public IDictionary Extensions { get; set; } = new Dictionary();
public void Serialize(IAsyncApiWriter writer)
@@ -34,8 +46,10 @@ public void Serialize(IAsyncApiWriter writer)
writer.WriteStartObject();
writer.WriteRequiredProperty("effect", this.Effect.GetDisplayName());
- writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Value.Write(w));
+ writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Serialize(w));
writer.WriteRequiredObject("action", this.Action, (w, t) => t.Value.Write(w));
+ writer.WriteOptionalObject("resource", this.Resource, (w, t) => t?.Value.Write(w));
+ writer.WriteOptionalObject("condition", this.Condition, (w, t) => t?.Write(w));
writer.WriteExtensions(this.Extensions);
writer.WriteEndObject();
}
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs
new file mode 100644
index 00000000..2821f952
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/Principal.cs
@@ -0,0 +1,65 @@
+// Copyright (c) The LEGO Group. All rights reserved.
+
+namespace LEGO.AsyncAPI.Bindings.Sqs;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using LEGO.AsyncAPI.Models.Interfaces;
+using LEGO.AsyncAPI.Readers.ParseNodes;
+using LEGO.AsyncAPI.Writers;
+
+public abstract class Principal : IAsyncApiElement
+{
+ public abstract void Serialize(IAsyncApiWriter writer);
+
+ public static Principal Parse(ParseNode node)
+ {
+ switch (node)
+ {
+ case ValueNode:
+ var nodeValue = node.GetScalarValue();
+ if (!IsStarString(nodeValue))
+ {
+ throw new ArgumentException($"An error occured while parsing a {nameof(Principal)} node. " +
+ $"Principal value without a property name can only be a string value of '*'.");
+ }
+
+ return new PrincipalStar();
+
+ case MapNode mapNode:
+ {
+ var propertyNode = mapNode.First();
+ if (!IsValidPrincipalProperty(propertyNode.Name))
+ {
+ throw new ArgumentException($"An error occured while parsing a {nameof(Principal)} node. " +
+ $"Node should contain a valid AWS principal property name.");
+ }
+
+ var principalValue = new KeyValuePair(
+ propertyNode.Name,
+ StringOrStringList.Parse(propertyNode.Value));
+
+ return new PrincipalObject(principalValue);
+ }
+
+ default:
+ throw new ArgumentException($"An error occured while parsing a {nameof(Principal)} node. " +
+ $"Node should contain a string value of '*' or a valid AWS principal property.");
+ }
+ }
+
+ private static bool IsStarString(JsonNode value)
+ {
+ var element = JsonDocument.Parse(value.ToJsonString()).RootElement;
+
+ return element.ValueKind == JsonValueKind.String && element.ValueEquals("*");
+ }
+
+ private static bool IsValidPrincipalProperty(string property)
+ {
+ return new[] { "AWS", "Service" }.Contains(property);
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
new file mode 100644
index 00000000..2652060d
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
@@ -0,0 +1,27 @@
+namespace LEGO.AsyncAPI.Bindings.Sqs;
+
+using System;
+using System.Collections.Generic;
+using LEGO.AsyncAPI.Writers;
+
+public class PrincipalObject : Principal
+{
+ private KeyValuePair PrincipalValue;
+
+ public PrincipalObject(KeyValuePair principalValue)
+ {
+ this.PrincipalValue = principalValue;
+ }
+
+ public override void Serialize(IAsyncApiWriter writer)
+ {
+ if (writer is null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+
+ writer.WriteStartObject();
+ writer.WriteRequiredObject(this.PrincipalValue.Key, this.PrincipalValue.Value, (w, t) => t.Value.Write(w));
+ writer.WriteEndObject();
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
new file mode 100644
index 00000000..9e54bc5a
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
@@ -0,0 +1,24 @@
+namespace LEGO.AsyncAPI.Bindings.Sqs;
+
+using System;
+using LEGO.AsyncAPI.Writers;
+
+public class PrincipalStar : Principal
+{
+ private string PrincipalValue;
+
+ public PrincipalStar()
+ {
+ this.PrincipalValue = "*";
+ }
+
+ public override void Serialize(IAsyncApiWriter writer)
+ {
+ if (writer is null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+
+ writer.WriteValue(this.PrincipalValue);
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs
index 6f98da99..f0b24be7 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs
@@ -64,8 +64,10 @@ public class SqsChannelBinding : ChannelBinding
private static FixedFieldMap statementFixedFields = new()
{
{ "effect", (a, n) => { a.Effect = n.GetScalarValue().GetEnumFromDisplayName(); } },
- { "principal", (a, n) => { a.Principal = StringOrStringList.Parse(n); } },
+ { "principal", (a, n) => { a.Principal = Principal.Parse(n); } },
{ "action", (a, n) => { a.Action = StringOrStringList.Parse(n); } },
+ { "resource", (a, n) => { a.Resource = StringOrStringList.Parse(n); } },
+ { "condition", (a, n) => { a.Condition = n.CreateAny(); } },
};
public override void SerializeProperties(IAsyncApiWriter writer)
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs
index d8eb43dd..ed278013 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs
@@ -56,8 +56,10 @@ public class SqsOperationBinding : OperationBinding
private static FixedFieldMap statementFixedFields = new()
{
{ "effect", (a, n) => { a.Effect = n.GetScalarValue().GetEnumFromDisplayName(); } },
- { "principal", (a, n) => { a.Principal = StringOrStringList.Parse(n); } },
+ { "principal", (a, n) => { a.Principal = Principal.Parse(n); } },
{ "action", (a, n) => { a.Action = StringOrStringList.Parse(n); } },
+ { "resource", (a, n) => { a.Resource = StringOrStringList.Parse(n); } },
+ { "condition", (a, n) => { a.Condition = n.CreateAny(); } },
};
public override void SerializeProperties(IAsyncApiWriter writer)
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
index 9518d2d4..4abc05a6 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
@@ -5,24 +5,37 @@ namespace LEGO.AsyncAPI.Bindings.Sqs
using System;
using System.Collections.Generic;
using LEGO.AsyncAPI.Attributes;
+ using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Writers;
public class Statement : IAsyncApiExtensible
{
+ ///
+ /// Indicates whether the policy allows or denies access.
+ ///
public Effect Effect { get; set; }
///
- /// The AWS account or resource ARN that this statement applies to.
+ /// The AWS account(s) or resource ARN(s) that this statement applies to.
///
- // public StringOrStringList Principal { get; set; }
- public StringOrStringList Principal { get; set; }
+ public Principal Principal { get; set; }
///
- /// The SNS permission being allowed or denied e.g. sns:Publish
+ /// The SNS permission being allowed or denied e.g. sns:Publish.
///
public StringOrStringList Action { get; set; }
+ ///
+ /// The resource(s) that this policy applies to.
+ ///
+ public StringOrStringList? Resource { get; set; }
+
+ ///
+ /// Specific circumstances under which the policy grants permission.
+ ///
+ public AsyncApiAny? Condition { get; set; }
+
public IDictionary Extensions { get; set; } = new Dictionary();
public void Serialize(IAsyncApiWriter writer)
@@ -34,8 +47,10 @@ public void Serialize(IAsyncApiWriter writer)
writer.WriteStartObject();
writer.WriteRequiredProperty("effect", this.Effect.GetDisplayName());
- writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Value.Write(w));
+ writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Serialize(w));
writer.WriteRequiredObject("action", this.Action, (w, t) => t.Value.Write(w));
+ writer.WriteOptionalObject("resource", this.Resource, (w, t) => t?.Value.Write(w));
+ writer.WriteOptionalObject("condition", this.Condition, (w, t) => t?.Write(w));
writer.WriteExtensions(this.Extensions);
writer.WriteEndObject();
}
diff --git a/src/LEGO.AsyncAPI.Bindings/StringOrStringList.cs b/src/LEGO.AsyncAPI.Bindings/StringOrStringList.cs
index 6be69094..b9946f08 100644
--- a/src/LEGO.AsyncAPI.Bindings/StringOrStringList.cs
+++ b/src/LEGO.AsyncAPI.Bindings/StringOrStringList.cs
@@ -30,10 +30,10 @@ public static StringOrStringList Parse(ParseNode node)
{
case ValueNode:
return new StringOrStringList(new AsyncApiAny(node.GetScalarValue()));
- case ListNode:
+ case ListNode listNode:
{
var jsonArray = new JsonArray();
- foreach (var item in node as ListNode)
+ foreach (var item in listNode)
{
jsonArray.Add(item.GetScalarValue());
}
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
index 6d4f5779..fbb3622e 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
@@ -31,15 +31,24 @@ public void SnsChannelBinding_WithFilledObject_SerializesAndDeserializes()
policy:
statements:
- effect: Deny
- principal: arn:aws:iam::123456789012:user/alex.wichmann
+ principal: '*'
action:
- sns:Publish
- sns:Delete
+ condition:
+ StringEquals:
+ aws:username:
+ - johndoe
+ - mrsmith
- effect: Allow
principal:
- - arn:aws:iam::123456789012:user/alex.wichmann
- - arn:aws:iam::123456789012:user/dec.kolakowski
+ AWS:
+ - arn:aws:iam::123456789012:user/alex.wichmann
+ - arn:aws:iam::123456789012:user/dec.kolakowski
action: sns:Create
+ condition:
+ NumericLessThanEquals:
+ aws:MultiFactorAuthAge: '3600'
x-statementExtension:
statementXPropertyName: statementXPropertyValue
x-policyExtension:
@@ -77,22 +86,38 @@ public void SnsChannelBinding_WithFilledObject_SerializesAndDeserializes()
new Statement()
{
Effect = Effect.Deny,
- Principal = new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")),
+ Principal = new PrincipalStar(),
Action = new StringOrStringList(new AsyncApiAny(new List()
{
"sns:Publish",
"sns:Delete",
})),
+ Condition = new AsyncApiAny(new Dictionary()
+ {
+ {
+ "StringEquals", new Dictionary>()
+ {
+ { "aws:username", new List() { "johndoe", "mrsmith" } },
+ }
+ },
+ }),
},
new Statement()
{
Effect = Effect.Allow,
- Principal = new StringOrStringList(new AsyncApiAny(new List()
- {
- "arn:aws:iam::123456789012:user/alex.wichmann",
- "arn:aws:iam::123456789012:user/dec.kolakowski",
- })),
+ Principal = new PrincipalObject(new KeyValuePair(
+ "AWS", new StringOrStringList(new AsyncApiAny(new List
+ { "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
Action = new StringOrStringList(new AsyncApiAny("sns:Create")),
+ Condition = new AsyncApiAny(new Dictionary()
+ {
+ {
+ "NumericLessThanEquals", new Dictionary()
+ {
+ { "aws:MultiFactorAuthAge", "3600" },
+ }
+ },
+ }),
Extensions = new Dictionary()
{
{
@@ -137,8 +162,11 @@ public void SnsChannelBinding_WithFilledObject_SerializesAndDeserializes()
var actual = channel.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
// Assert
- var settings = new AsyncApiReaderSettings();
- settings.Bindings = BindingsCollection.Sns;
+ var settings = new AsyncApiReaderSettings
+ {
+ Bindings = BindingsCollection.Sns,
+ };
+
var binding = new AsyncApiStringReader(settings).ReadFragment(actual, AsyncApiVersion.AsyncApi2_0, out _);
// Assert
@@ -381,8 +409,11 @@ public void SnsOperationBinding_WithFilledObject_SerializesAndDeserializes()
var actual = operation.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
// Assert
- var settings = new AsyncApiReaderSettings();
- settings.Bindings = BindingsCollection.Sns;
+ var settings = new AsyncApiReaderSettings
+ {
+ Bindings = BindingsCollection.Sns,
+ };
+
var binding = new AsyncApiStringReader(settings).ReadFragment(actual, AsyncApiVersion.AsyncApi2_0, out _);
var binding2 = new AsyncApiStringReader(settings).ReadFragment(expected, AsyncApiVersion.AsyncApi2_0, out _);
binding2.Bindings.First().Value.Extensions.TryGetValue("x-bindingExtension", out IAsyncApiExtension any);
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
index c031621c..3a0337a3 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
@@ -3,6 +3,7 @@
namespace LEGO.AsyncAPI.Tests.Bindings.Sqs
{
using System.Collections.Generic;
+ using System.Linq;
using FluentAssertions;
using LEGO.AsyncAPI.Bindings;
using LEGO.AsyncAPI.Bindings.Sqs;
@@ -42,17 +43,27 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
policy:
statements:
- effect: deny
- principal: arn:aws:iam::123456789012:user/alex.wichmann
+ principal:
+ AWS: arn:aws:iam::123456789012:user/alex.wichmann
action:
- sqs:SendMessage
- sqs:ReceiveMessage
+ condition:
+ StringEquals:
+ aws:username:
+ - johndoe
+ - mrsmith
x-statementExtension:
statementXPropertyName: statementXPropertyValue
- effect: allow
principal:
- - arn:aws:iam::123456789012:user/alex.wichmann
- - arn:aws:iam::123456789012:user/dec.kolakowski
+ AWS:
+ - arn:aws:iam::123456789012:user/alex.wichmann
+ - arn:aws:iam::123456789012:user/dec.kolakowski
action: sqs:CreateQueue
+ condition:
+ NumericLessThanEquals:
+ aws:MultiFactorAuthAge: '3600'
x-policyExtension:
policyXPropertyName: policyXPropertyValue
tags:
@@ -69,7 +80,8 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
policy:
statements:
- effect: allow
- principal: arn:aws:iam::123456789012:user/alex.wichmann
+ principal:
+ Service: s3.amazonaws.com
action:
- sqs:*
x-internalObject:
@@ -124,12 +136,22 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
new Statement()
{
Effect = Effect.Deny,
- Principal = new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")),
+ Principal = new PrincipalObject(new KeyValuePair(
+ "AWS", new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")))),
Action = new StringOrStringList(new AsyncApiAny(new List
{
"sqs:SendMessage",
"sqs:ReceiveMessage",
})),
+ Condition = new AsyncApiAny(new Dictionary()
+ {
+ {
+ "StringEquals", new Dictionary>()
+ {
+ { "aws:username", new List() { "johndoe", "mrsmith" } },
+ }
+ },
+ }),
Extensions = new Dictionary()
{
{
@@ -144,12 +166,19 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
new Statement()
{
Effect = Effect.Allow,
- Principal = new StringOrStringList(new AsyncApiAny(new List
- {
- "arn:aws:iam::123456789012:user/alex.wichmann",
- "arn:aws:iam::123456789012:user/dec.kolakowski",
- })),
+ Principal = new PrincipalObject(new KeyValuePair(
+ "AWS", new StringOrStringList(new AsyncApiAny(new List
+ { "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
Action = new StringOrStringList(new AsyncApiAny("sqs:CreateQueue")),
+ Condition = new AsyncApiAny(new Dictionary()
+ {
+ {
+ "NumericLessThanEquals", new Dictionary()
+ {
+ { "aws:MultiFactorAuthAge", "3600" },
+ }
+ },
+ }),
},
},
Extensions = new Dictionary()
@@ -194,7 +223,8 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
new Statement()
{
Effect = Effect.Allow,
- Principal = new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")),
+ Principal = new PrincipalObject(new KeyValuePair(
+ "Service", new StringOrStringList(new AsyncApiAny("s3.amazonaws.com")))),
Action = new StringOrStringList(new AsyncApiAny(new List
{
"sqs:*",
@@ -218,8 +248,10 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
var actual = channel.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
// Assert
- var settings = new AsyncApiReaderSettings();
- settings.Bindings = BindingsCollection.Sqs;
+ var settings = new AsyncApiReaderSettings
+ {
+ Bindings = BindingsCollection.Sqs,
+ };
var binding =
new AsyncApiStringReader(settings).ReadFragment(actual, AsyncApiVersion.AsyncApi2_0, out _);
@@ -227,6 +259,9 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
actual.Should()
.BePlatformAgnosticEquivalentTo(expected);
binding.Should().BeEquivalentTo(channel);
+
+ var expectedSqsBinding = (SqsChannelBinding)channel.Bindings.Values.First();
+ expectedSqsBinding.Should().BeEquivalentTo((SqsChannelBinding)binding.Bindings.Values.First(), options => options.IgnoringCyclicReferences());
}
[Test]
@@ -254,7 +289,8 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
policy:
statements:
- effect: deny
- principal: arn:aws:iam::123456789012:user/alex.wichmann
+ principal:
+ AWS: arn:aws:iam::123456789012:user/alex.wichmann
action:
- sqs:SendMessage
- sqs:ReceiveMessage
@@ -262,8 +298,9 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
statementXPropertyName: statementXPropertyValue
- effect: allow
principal:
- - arn:aws:iam::123456789012:user/alex.wichmann
- - arn:aws:iam::123456789012:user/dec.kolakowski
+ AWS:
+ - arn:aws:iam::123456789012:user/alex.wichmann
+ - arn:aws:iam::123456789012:user/dec.kolakowski
action: sqs:CreateQueue
x-policyExtension:
policyXPropertyName: policyXPropertyValue
@@ -280,7 +317,8 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
policy:
statements:
- effect: allow
- principal: arn:aws:iam::123456789012:user/alex.wichmann
+ principal:
+ AWS: arn:aws:iam::123456789012:user/alex.wichmann
action:
- sqs:*
x-queueExtension:
@@ -339,7 +377,8 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
new Statement()
{
Effect = Effect.Deny,
- Principal = new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")),
+ Principal = new PrincipalObject(new KeyValuePair(
+ "AWS", new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")))),
Action = new StringOrStringList(new AsyncApiAny(new List()
{
"sqs:SendMessage",
@@ -359,11 +398,9 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
new Statement()
{
Effect = Effect.Allow,
- Principal = new StringOrStringList(new AsyncApiAny(new List
- {
- "arn:aws:iam::123456789012:user/alex.wichmann",
- "arn:aws:iam::123456789012:user/dec.kolakowski",
- })),
+ Principal = new PrincipalObject(new KeyValuePair(
+ "AWS", new StringOrStringList(new AsyncApiAny(new List
+ { "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
Action = new StringOrStringList(new AsyncApiAny("sqs:CreateQueue")),
},
},
@@ -409,7 +446,8 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
new Statement()
{
Effect = Effect.Allow,
- Principal = new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")),
+ Principal = new PrincipalObject(new KeyValuePair(
+ "AWS", new StringOrStringList(new AsyncApiAny("arn:aws:iam::123456789012:user/alex.wichmann")))),
Action = new StringOrStringList(new AsyncApiAny(new List
{
"sqs:*",
@@ -444,14 +482,20 @@ public void SqsOperationBinding_WithFilledObject_SerializesAndDeserializes()
var actual = operation.SerializeAsYaml(AsyncApiVersion.AsyncApi2_0);
// Assert
- var settings = new AsyncApiReaderSettings();
- settings.Bindings = BindingsCollection.Sqs;
+ var settings = new AsyncApiReaderSettings
+ {
+ Bindings = BindingsCollection.Sqs,
+ };
+
var binding = new AsyncApiStringReader(settings).ReadFragment(actual, AsyncApiVersion.AsyncApi2_0, out _);
// Assert
actual.Should()
.BePlatformAgnosticEquivalentTo(expected);
binding.Should().BeEquivalentTo(operation);
+
+ var expectedSqsBinding = (SqsOperationBinding)operation.Bindings.Values.First();
+ expectedSqsBinding.Should().BeEquivalentTo((SqsOperationBinding)binding.Bindings.Values.First(), options => options.IgnoringCyclicReferences());
}
}
}
\ No newline at end of file
From 38390d87aefbf1707ec17514e721a034bff2f561 Mon Sep 17 00:00:00 2001
From: Alex Wichmann
Date: Fri, 16 Aug 2024 13:14:18 +0200
Subject: [PATCH 10/18] Add beta link to bindings.
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 593dbd88..ce65fd33 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Install the NuGet packages:
### AsyncAPI.Bindings
[](https://www.nuget.org/packages/AsyncAPI.NET.Bindings/)
-
+[](https://www.nuget.org/packages/AsyncAPI.NET.Bindings/)
## Example Usage
Main classes to know:
From 57c0c3365f4d215860d8b599fd9d18e6e5185d54 Mon Sep 17 00:00:00 2001
From: Adam Gloyne <44494964+Gadam8@users.noreply.github.com>
Date: Tue, 20 Aug 2024 13:01:50 +0100
Subject: [PATCH 11/18] chore: make principal values public (#192)
Co-authored-by: adam.gloyne
---
src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs | 8 ++++----
src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs | 6 +++---
src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs | 8 ++++----
src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs | 6 +++---
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
index a25c198f..209be8bf 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalObject.cs
@@ -6,11 +6,11 @@ namespace LEGO.AsyncAPI.Bindings.Sns;
public class PrincipalObject : Principal
{
- private KeyValuePair PrincipalValue;
+ public KeyValuePair Value { get; private set; }
- public PrincipalObject(KeyValuePair principalValue)
+ public PrincipalObject(KeyValuePair value)
{
- this.PrincipalValue = principalValue;
+ this.Value = value;
}
public override void Serialize(IAsyncApiWriter writer)
@@ -21,7 +21,7 @@ public override void Serialize(IAsyncApiWriter writer)
}
writer.WriteStartObject();
- writer.WriteRequiredObject(this.PrincipalValue.Key, this.PrincipalValue.Value, (w, t) => t.Value.Write(w));
+ writer.WriteRequiredObject(this.Value.Key, this.Value.Value, (w, t) => t.Value.Write(w));
writer.WriteEndObject();
}
}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
index 533e9fb7..c885d252 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/PrincipalStar.cs
@@ -5,11 +5,11 @@ namespace LEGO.AsyncAPI.Bindings.Sns;
public class PrincipalStar : Principal
{
- private string PrincipalValue;
+ public string Value { get; private set; }
public PrincipalStar()
{
- this.PrincipalValue = "*";
+ this.Value = "*";
}
public override void Serialize(IAsyncApiWriter writer)
@@ -19,6 +19,6 @@ public override void Serialize(IAsyncApiWriter writer)
throw new ArgumentNullException(nameof(writer));
}
- writer.WriteValue(this.PrincipalValue);
+ writer.WriteValue(this.Value);
}
}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
index 2652060d..61e6e546 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalObject.cs
@@ -6,11 +6,11 @@ namespace LEGO.AsyncAPI.Bindings.Sqs;
public class PrincipalObject : Principal
{
- private KeyValuePair PrincipalValue;
+ public KeyValuePair Value { get; private set; }
- public PrincipalObject(KeyValuePair principalValue)
+ public PrincipalObject(KeyValuePair value)
{
- this.PrincipalValue = principalValue;
+ this.Value = value;
}
public override void Serialize(IAsyncApiWriter writer)
@@ -21,7 +21,7 @@ public override void Serialize(IAsyncApiWriter writer)
}
writer.WriteStartObject();
- writer.WriteRequiredObject(this.PrincipalValue.Key, this.PrincipalValue.Value, (w, t) => t.Value.Write(w));
+ writer.WriteRequiredObject(this.Value.Key, this.Value.Value, (w, t) => t.Value.Write(w));
writer.WriteEndObject();
}
}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
index 9e54bc5a..1705b966 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/PrincipalStar.cs
@@ -5,11 +5,11 @@ namespace LEGO.AsyncAPI.Bindings.Sqs;
public class PrincipalStar : Principal
{
- private string PrincipalValue;
+ public string Value { get; private set; }
public PrincipalStar()
{
- this.PrincipalValue = "*";
+ this.Value = "*";
}
public override void Serialize(IAsyncApiWriter writer)
@@ -19,6 +19,6 @@ public override void Serialize(IAsyncApiWriter writer)
throw new ArgumentNullException(nameof(writer));
}
- writer.WriteValue(this.PrincipalValue);
+ writer.WriteValue(this.Value);
}
}
\ No newline at end of file
From 030d603673bbde25a3e6cdd99c63f45159f4e9fd Mon Sep 17 00:00:00 2001
From: Adam Gloyne <44494964+Gadam8@users.noreply.github.com>
Date: Wed, 4 Sep 2024 17:36:37 +0100
Subject: [PATCH 12/18] chore: make aws condition value explicit (#193)
Co-authored-by: adam.gloyne
---
src/LEGO.AsyncAPI.Bindings/Sns/Condition.cs | 67 +++++++++++++++++++
.../Sns/SnsChannelBinding.cs | 2 +-
src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs | 4 +-
src/LEGO.AsyncAPI.Bindings/Sqs/Condition.cs | 67 +++++++++++++++++++
.../Sqs/SqsChannelBinding.cs | 2 +-
.../Sqs/SqsOperationBinding.cs | 2 +-
src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs | 4 +-
.../Bindings/Sns/SnsBindings_Should.cs | 16 +++--
.../Bindings/Sqs/SqsBindings_should.cs | 16 +++--
9 files changed, 161 insertions(+), 19 deletions(-)
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sns/Condition.cs
create mode 100644 src/LEGO.AsyncAPI.Bindings/Sqs/Condition.cs
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/Condition.cs b/src/LEGO.AsyncAPI.Bindings/Sns/Condition.cs
new file mode 100644
index 00000000..38b21da9
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/Condition.cs
@@ -0,0 +1,67 @@
+// Copyright (c) The LEGO Group. All rights reserved.
+
+namespace LEGO.AsyncAPI.Bindings.Sns;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using LEGO.AsyncAPI.Models.Interfaces;
+using LEGO.AsyncAPI.Readers.ParseNodes;
+using LEGO.AsyncAPI.Writers;
+
+public class Condition : IAsyncApiElement
+{
+ public Dictionary> Value { get; private set; }
+
+ public Condition(Dictionary> value)
+ {
+ this.Value = value;
+ }
+
+ public void Serialize(IAsyncApiWriter writer)
+ {
+ if (writer is null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+
+ writer.WriteStartObject();
+ foreach (var conditionValue in this.Value)
+ {
+ writer.WriteRequiredMap(conditionValue.Key, conditionValue.Value, (w, t) => t.Value.Write(w));
+ }
+
+ writer.WriteEndObject();
+ }
+
+ public static Condition Parse(ParseNode node)
+ {
+ switch (node)
+ {
+ case MapNode mapNode:
+ {
+ var conditionValues = new Dictionary>();
+ foreach (var conditionNode in mapNode)
+ {
+ switch (conditionNode.Value)
+ {
+ case MapNode conditionValueNode:
+ conditionValues.Add(conditionNode.Name, new Dictionary(conditionValueNode.Select(x =>
+ new KeyValuePair(x.Name, StringOrStringList.Parse(x.Value)))
+ .ToDictionary(x => x.Key, x => x.Value)));
+ break;
+ default:
+ throw new ArgumentException($"An error occured while parsing a {nameof(Condition)} node. " +
+ $"AWS condition values should be one or more key value pairs.");
+ }
+ }
+
+ return new Condition(conditionValues);
+ }
+
+ default:
+ throw new ArgumentException($"An error occured while parsing a {nameof(Condition)} node. " +
+ $"Node should contain a collection of condition types.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs b/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs
index 4d8668c9..4394cdd1 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/SnsChannelBinding.cs
@@ -60,7 +60,7 @@ public class SnsChannelBinding : ChannelBinding
{ "principal", (a, n) => { a.Principal = Principal.Parse(n); } },
{ "action", (a, n) => { a.Action = StringOrStringList.Parse(n); } },
{ "resource", (a, n) => { a.Resource = StringOrStringList.Parse(n); } },
- { "condition", (a, n) => { a.Condition = n.CreateAny(); } },
+ { "condition", (a, n) => { a.Condition = Condition.Parse(n); } },
};
///
diff --git a/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs b/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
index 170fe371..da93cfbf 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sns/Statement.cs
@@ -33,7 +33,7 @@ public class Statement : IAsyncApiExtensible
///
/// Specific circumstances under which the policy grants permission.
///
- public AsyncApiAny? Condition { get; set; }
+ public Condition Condition { get; set; }
public IDictionary Extensions { get; set; } = new Dictionary();
@@ -49,7 +49,7 @@ public void Serialize(IAsyncApiWriter writer)
writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Serialize(w));
writer.WriteRequiredObject("action", this.Action, (w, t) => t.Value.Write(w));
writer.WriteOptionalObject("resource", this.Resource, (w, t) => t?.Value.Write(w));
- writer.WriteOptionalObject("condition", this.Condition, (w, t) => t?.Write(w));
+ writer.WriteOptionalObject("condition", this.Condition, (w, t) => t.Serialize(w));
writer.WriteExtensions(this.Extensions);
writer.WriteEndObject();
}
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/Condition.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/Condition.cs
new file mode 100644
index 00000000..93bdf733
--- /dev/null
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/Condition.cs
@@ -0,0 +1,67 @@
+// Copyright (c) The LEGO Group. All rights reserved.
+
+namespace LEGO.AsyncAPI.Bindings.Sqs;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using LEGO.AsyncAPI.Models.Interfaces;
+using LEGO.AsyncAPI.Readers.ParseNodes;
+using LEGO.AsyncAPI.Writers;
+
+public class Condition : IAsyncApiElement
+{
+ public Dictionary> Value { get; private set; }
+
+ public Condition(Dictionary> value)
+ {
+ this.Value = value;
+ }
+
+ public void Serialize(IAsyncApiWriter writer)
+ {
+ if (writer is null)
+ {
+ throw new ArgumentNullException(nameof(writer));
+ }
+
+ writer.WriteStartObject();
+ foreach (var conditionValue in this.Value)
+ {
+ writer.WriteRequiredMap(conditionValue.Key, conditionValue.Value, (w, t) => t.Value.Write(w));
+ }
+
+ writer.WriteEndObject();
+ }
+
+ public static Condition Parse(ParseNode node)
+ {
+ switch (node)
+ {
+ case MapNode mapNode:
+ {
+ var conditionValues = new Dictionary>();
+ foreach (var conditionNode in mapNode)
+ {
+ switch (conditionNode.Value)
+ {
+ case MapNode conditionValueNode:
+ conditionValues.Add(conditionNode.Name, new Dictionary(conditionValueNode.Select(x =>
+ new KeyValuePair(x.Name, StringOrStringList.Parse(x.Value)))
+ .ToDictionary(x => x.Key, x => x.Value)));
+ break;
+ default:
+ throw new ArgumentException($"An error occured while parsing a {nameof(Condition)} node. " +
+ $"AWS condition values should be one or more key value pairs.");
+ }
+ }
+
+ return new Condition(conditionValues);
+ }
+
+ default:
+ throw new ArgumentException($"An error occured while parsing a {nameof(Condition)} node. " +
+ $"Node should contain a collection of AWS condition types.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs
index f0b24be7..bd806071 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsChannelBinding.cs
@@ -67,7 +67,7 @@ public class SqsChannelBinding : ChannelBinding
{ "principal", (a, n) => { a.Principal = Principal.Parse(n); } },
{ "action", (a, n) => { a.Action = StringOrStringList.Parse(n); } },
{ "resource", (a, n) => { a.Resource = StringOrStringList.Parse(n); } },
- { "condition", (a, n) => { a.Condition = n.CreateAny(); } },
+ { "condition", (a, n) => { a.Condition = Condition.Parse(n); } },
};
public override void SerializeProperties(IAsyncApiWriter writer)
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs
index ed278013..0beb89b8 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/SqsOperationBinding.cs
@@ -59,7 +59,7 @@ public class SqsOperationBinding : OperationBinding
{ "principal", (a, n) => { a.Principal = Principal.Parse(n); } },
{ "action", (a, n) => { a.Action = StringOrStringList.Parse(n); } },
{ "resource", (a, n) => { a.Resource = StringOrStringList.Parse(n); } },
- { "condition", (a, n) => { a.Condition = n.CreateAny(); } },
+ { "condition", (a, n) => { a.Condition = Condition.Parse(n); } },
};
public override void SerializeProperties(IAsyncApiWriter writer)
diff --git a/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs b/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
index 4abc05a6..4a9c5303 100644
--- a/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
+++ b/src/LEGO.AsyncAPI.Bindings/Sqs/Statement.cs
@@ -34,7 +34,7 @@ public class Statement : IAsyncApiExtensible
///
/// Specific circumstances under which the policy grants permission.
///
- public AsyncApiAny? Condition { get; set; }
+ public Condition Condition { get; set; }
public IDictionary Extensions { get; set; } = new Dictionary();
@@ -50,7 +50,7 @@ public void Serialize(IAsyncApiWriter writer)
writer.WriteRequiredObject("principal", this.Principal, (w, t) => t.Serialize(w));
writer.WriteRequiredObject("action", this.Action, (w, t) => t.Value.Write(w));
writer.WriteOptionalObject("resource", this.Resource, (w, t) => t?.Value.Write(w));
- writer.WriteOptionalObject("condition", this.Condition, (w, t) => t?.Write(w));
+ writer.WriteOptionalObject("condition", this.Condition, (w, t) => t.Serialize(w));
writer.WriteExtensions(this.Extensions);
writer.WriteEndObject();
}
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
index fbb3622e..daed9e88 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/Sns/SnsBindings_Should.cs
@@ -92,12 +92,14 @@ public void SnsChannelBinding_WithFilledObject_SerializesAndDeserializes()
"sns:Publish",
"sns:Delete",
})),
- Condition = new AsyncApiAny(new Dictionary()
+ Condition = new Condition(new Dictionary>
{
{
- "StringEquals", new Dictionary>()
+ "StringEquals", new Dictionary
{
- { "aws:username", new List() { "johndoe", "mrsmith" } },
+ {
+ "aws:username", new StringOrStringList(new AsyncApiAny(new List() { "johndoe", "mrsmith" }))
+ },
}
},
}),
@@ -109,12 +111,14 @@ public void SnsChannelBinding_WithFilledObject_SerializesAndDeserializes()
"AWS", new StringOrStringList(new AsyncApiAny(new List
{ "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
Action = new StringOrStringList(new AsyncApiAny("sns:Create")),
- Condition = new AsyncApiAny(new Dictionary()
+ Condition = new Condition(new Dictionary>
{
{
- "NumericLessThanEquals", new Dictionary()
+ "NumericLessThanEquals", new Dictionary
{
- { "aws:MultiFactorAuthAge", "3600" },
+ {
+ "aws:MultiFactorAuthAge", new StringOrStringList(new AsyncApiAny("3600"))
+ },
}
},
}),
diff --git a/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs b/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
index 3a0337a3..c3f7ff9d 100644
--- a/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
+++ b/test/LEGO.AsyncAPI.Tests/Bindings/Sqs/SqsBindings_should.cs
@@ -143,12 +143,14 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
"sqs:SendMessage",
"sqs:ReceiveMessage",
})),
- Condition = new AsyncApiAny(new Dictionary()
+ Condition = new Condition(new Dictionary>
{
{
- "StringEquals", new Dictionary>()
+ "StringEquals", new Dictionary
{
- { "aws:username", new List() { "johndoe", "mrsmith" } },
+ {
+ "aws:username", new StringOrStringList(new AsyncApiAny(new List { "johndoe", "mrsmith" }))
+ },
}
},
}),
@@ -170,12 +172,14 @@ public void SqsChannelBinding_WithFilledObject_SerializesAndDeserializes()
"AWS", new StringOrStringList(new AsyncApiAny(new List
{ "arn:aws:iam::123456789012:user/alex.wichmann", "arn:aws:iam::123456789012:user/dec.kolakowski" })))),
Action = new StringOrStringList(new AsyncApiAny("sqs:CreateQueue")),
- Condition = new AsyncApiAny(new Dictionary()
+ Condition = new Condition(new Dictionary>
{
{
- "NumericLessThanEquals", new Dictionary()
+ "NumericLessThanEquals", new Dictionary
{
- { "aws:MultiFactorAuthAge", "3600" },
+ {
+ "aws:MultiFactorAuthAge", new StringOrStringList(new AsyncApiAny("3600"))
+ },
}
},
}),
From 68657dd2d035a1fd5468844c37c3ee85f019cfe6 Mon Sep 17 00:00:00 2001
From: Alex Wichmann
Date: Wed, 8 Jan 2025 10:05:05 +0100
Subject: [PATCH 13/18] Update and rename release-internal.yml to
release-beta.yml
---
.github/workflows/{release-internal.yml => release-beta.yml} | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
rename .github/workflows/{release-internal.yml => release-beta.yml} (97%)
diff --git a/.github/workflows/release-internal.yml b/.github/workflows/release-beta.yml
similarity index 97%
rename from .github/workflows/release-internal.yml
rename to .github/workflows/release-beta.yml
index 1231b9e6..9cbebb05 100644
--- a/.github/workflows/release-internal.yml
+++ b/.github/workflows/release-beta.yml
@@ -1,7 +1,9 @@
name: Publish beta NuGet package
on:
workflow_dispatch:
-
+ push:
+ branches:
+ - vnext
jobs:
check:
runs-on: ubuntu-latest
From 57c40958d8d57e7055d13282243dc2c04434011d Mon Sep 17 00:00:00 2001
From: VisualBean
Date: Fri, 24 Jan 2025 12:47:38 +0100
Subject: [PATCH 14/18] chore: add Ulrik as codeowner chore: add Ulrik as
codeowner
---
CODEOWNERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CODEOWNERS b/CODEOWNERS
index f1759cb1..2e87be63 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1 +1 @@
-* @VisualBean
+* @VisualBean @UlrikSandberg
From e6b9bf4b8f6631fa8862848cc9288dd93c8035e1 Mon Sep 17 00:00:00 2001
From: UlrikSandberg
Date: Thu, 20 Feb 2025 10:19:02 +0100
Subject: [PATCH 15/18] fix: dont return early for required map (#206)
---
.../Writers/AsyncApiWriterExtensions.cs | 5 +--
.../AsyncApiDocumentV2Tests.cs | 31 +++++++++++++++++++
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/src/LEGO.AsyncAPI/Writers/AsyncApiWriterExtensions.cs b/src/LEGO.AsyncAPI/Writers/AsyncApiWriterExtensions.cs
index 67c4737a..25777d51 100644
--- a/src/LEGO.AsyncAPI/Writers/AsyncApiWriterExtensions.cs
+++ b/src/LEGO.AsyncAPI/Writers/AsyncApiWriterExtensions.cs
@@ -285,10 +285,7 @@ public static void WriteRequiredMap(
Action action)
where T : IAsyncApiElement
{
- if (elements != null && elements.Any())
- {
- writer.WriteMapInternal(name, elements, action);
- }
+ writer.WriteMapInternal(name, elements, action);
}
///
diff --git a/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs b/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs
index 63e818b4..6e1a9c70 100644
--- a/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs
+++ b/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs
@@ -1325,5 +1325,36 @@ public void Serializev2_WithBindings_Serializes()
Assert.AreEqual("this mah binding", httpBinding.Headers.Description);
}
+
+
+
+ [Test]
+ public void SerializeV2_EmptyChannelObject_DeserializeAndSerializePreserveChannelObject()
+ {
+ // Arrange
+ var spec = """
+ asyncapi: 2.6.0
+ info:
+ title: Spec with missing channel info
+ description: test description
+ servers:
+ production:
+ url: example.com
+ protocol: pulsar+ssl
+ description: test description
+ channels: { }
+ """;
+
+ var settings = new AsyncApiReaderSettings();
+ var reader = new AsyncApiStringReader(settings);
+
+ // Act
+ var deserialized = reader.Read(spec, out var diagnostic);
+ var actual = deserialized.Serialize(AsyncApiVersion.AsyncApi2_0, AsyncApiFormat.Yaml);
+
+ // Assert
+ actual.Should()
+ .BePlatformAgnosticEquivalentTo(spec);
+ }
}
}
\ No newline at end of file
From 24cf1a976986d095a20d0094130184dcdd542be8 Mon Sep 17 00:00:00 2001
From: DominikKaloc
Date: Mon, 8 Sep 2025 09:41:41 +0200
Subject: [PATCH 16/18] fix: empty channels should be allowed (#208)
---
src/LEGO.AsyncAPI/Models/AsyncApiDocument.cs | 4 ++--
.../Validation/Rules/AsyncApiDocumentRules.cs | 2 +-
test/LEGO.AsyncAPI.Tests/AsyncApiDocumentBuilder.cs | 7 ++++++-
test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs | 8 ++++++++
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/src/LEGO.AsyncAPI/Models/AsyncApiDocument.cs b/src/LEGO.AsyncAPI/Models/AsyncApiDocument.cs
index 5be55202..b6488883 100644
--- a/src/LEGO.AsyncAPI/Models/AsyncApiDocument.cs
+++ b/src/LEGO.AsyncAPI/Models/AsyncApiDocument.cs
@@ -6,8 +6,8 @@ namespace LEGO.AsyncAPI.Models
using System.Collections.Generic;
using LEGO.AsyncAPI.Exceptions;
using LEGO.AsyncAPI.Models.Interfaces;
- using LEGO.AsyncAPI.Writers;
using LEGO.AsyncAPI.Services;
+ using LEGO.AsyncAPI.Writers;
///
/// This is the root document object for the API specification. It combines resource listing and API declaration together into one document.
@@ -46,7 +46,7 @@ public class AsyncApiDocument : IAsyncApiExtensible, IAsyncApiSerializable
///
/// REQUIRED. The available channels and messages for the API.
///
- public IDictionary Channels { get; set; } = new Dictionary();
+ public IDictionary Channels { get; set; }
///
/// an element to hold various schemas for the specification.
diff --git a/src/LEGO.AsyncAPI/Validation/Rules/AsyncApiDocumentRules.cs b/src/LEGO.AsyncAPI/Validation/Rules/AsyncApiDocumentRules.cs
index 27076369..264c1611 100644
--- a/src/LEGO.AsyncAPI/Validation/Rules/AsyncApiDocumentRules.cs
+++ b/src/LEGO.AsyncAPI/Validation/Rules/AsyncApiDocumentRules.cs
@@ -30,7 +30,7 @@ public static class AsyncApiDocumentRules
context.Exit();
context.Enter("channels");
- if (document.Channels == null || !document.Channels.Keys.Any())
+ if (document.Channels == null)
{
context.CreateError(
nameof(DocumentRequiredFields),
diff --git a/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentBuilder.cs b/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentBuilder.cs
index 3f2ee429..886fb7bf 100644
--- a/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentBuilder.cs
+++ b/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentBuilder.cs
@@ -2,9 +2,10 @@
namespace LEGO.AsyncAPI.Tests
{
+ using System;
+ using System.Collections.Generic;
using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Models.Interfaces;
- using System;
internal class AsyncApiDocumentBuilder
{
@@ -42,6 +43,10 @@ public AsyncApiDocumentBuilder WithDefaultContentType(string contentType = "appl
public AsyncApiDocumentBuilder WithChannel(string key, AsyncApiChannel channel)
{
+ if (this.document.Channels == null)
+ {
+ this.document.Channels = new Dictionary();
+ }
this.document.Channels.Add(key, channel);
return this;
}
diff --git a/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs b/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs
index 6e1a9c70..13ae85e5 100644
--- a/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs
+++ b/test/LEGO.AsyncAPI.Tests/AsyncApiDocumentV2Tests.cs
@@ -1202,6 +1202,10 @@ public void Serialize_WithBindingReferences_SerializesDeserializes()
},
},
};
+ if (doc.Channels == null)
+ {
+ doc.Channels = new Dictionary();
+ }
doc.Channels.Add(
"testChannel",
new AsyncApiChannel
@@ -1260,6 +1264,10 @@ public void Serializev2_WithBindings_Serializes()
Protocol = "pulsar+ssl",
Url = "example.com",
});
+ if (doc.Channels == null)
+ {
+ doc.Channels = new Dictionary();
+ }
doc.Channels.Add(
"testChannel",
new AsyncApiChannel
From 47fee3ffbc9017abdf8304aa78f5cb452027f280 Mon Sep 17 00:00:00 2001
From: DominikKaloc
Date: Thu, 25 Sep 2025 13:22:55 +0200
Subject: [PATCH 17/18] chore: manual release - custom version (#210)
---
.github/workflows/release-manual.yml | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 .github/workflows/release-manual.yml
diff --git a/.github/workflows/release-manual.yml b/.github/workflows/release-manual.yml
new file mode 100644
index 00000000..0eeca64b
--- /dev/null
+++ b/.github/workflows/release-manual.yml
@@ -0,0 +1,28 @@
+name: Publish custom NuGet package version
+on:
+ workflow_dispatch:
+ inputs:
+ package_version:
+ description: 'NuGet package version (e.g. 6.0.0-beta.1041)'
+ required: true
+
+jobs:
+ pre-release:
+ runs-on: ubuntu-latest
+ name: Publish NuGet packages
+ environment: AsyncAPI
+ strategy:
+ matrix:
+ package-name: [ "LEGO.AsyncAPI", "LEGO.AsyncAPI.Readers", "LEGO.AsyncAPI.Bindings" ]
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v1
+
+ - name: Setup .NET Core @ Latest
+ uses: actions/setup-dotnet@v1
+
+ - name: Build ${{ matrix.package-name }} project and pack NuGet package
+ run: dotnet pack src/${{ matrix.package-name }}/${{ matrix.package-name }}.csproj -c Release -o out-${{ matrix.package-name }} -p:PackageVersion=${{ github.event.inputs.package_version }}
+
+ - name: Push generated package to NuGet
+ run: dotnet nuget push out-${{ matrix.package-name }}/*.nupkg -s https://api.nuget.org/v3/index.json --skip-duplicate -n --api-key ${{secrets.NUGET}}
From f5becdf3d24a5138dcc54bfbe6a961b806f22c0f Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 17 Jul 2026 13:11:46 +0200
Subject: [PATCH 18/18] fix: bump System.Text.Json from 8.0.4 to 8.0.5 (#200)
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj b/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj
index 99e69016..a321a003 100644
--- a/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj
+++ b/src/LEGO.AsyncAPI/LEGO.AsyncAPI.csproj
@@ -19,7 +19,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
<_Parameter1>$(MSBuildProjectName).Tests