Skip to content

Commit 827f824

Browse files
authored
feat(bindings): add websockets binding (#69)
1 parent b4002e4 commit 827f824

File tree

6 files changed

+168
-7
lines changed

6 files changed

+168
-7
lines changed

src/LEGO.AsyncAPI.Readers/AsyncApiBindingDeserializer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ internal static partial class AsyncApiDeserializer
1414
private static Type operationBindingType = typeof(IOperationBinding);
1515
private static Type channelBindingType = typeof(IChannelBinding);
1616
private static Type serverBindingType = typeof(IServerBinding);
17+
1718
private static PatternFieldMap<T> BindingPatternExtensionFields<T>()
1819
where T : IBinding, new()
1920
{

src/LEGO.AsyncAPI.Readers/AsyncApiChannelBindingDeserializer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ internal static IChannelBinding LoadChannelBinding(ParseNode node)
4444
return LoadBinding("ChannelBinding", property.Value, kafkaChannelBindingFixedFields);
4545
case BindingType.Pulsar:
4646
return LoadBinding("ChannelBinding", property.Value, pulsarChannelBindingFixedFields);
47+
case BindingType.Websockets:
48+
return LoadBinding("ChannelBinding", property.Value, webSocketsChannelBindingFixedFields);
4749
default:
4850
throw new System.Exception("ChannelBinding not found");
4951
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) The LEGO Group. All rights reserved.
2+
3+
namespace LEGO.AsyncAPI.Readers
4+
{
5+
using LEGO.AsyncAPI.Models.Bindings.Http;
6+
using LEGO.AsyncAPI.Readers.ParseNodes;
7+
using Models.Bindings.WebSockets;
8+
9+
internal static partial class AsyncApiDeserializer
10+
{
11+
private static FixedFieldMap<WebSocketsChannelBinding> webSocketsChannelBindingFixedFields = new()
12+
{
13+
{ "bindingVersion", (a, n) => { a.BindingVersion = n.GetScalarValue(); } },
14+
{ "method", (a, n) => { a.Method = n.GetScalarValue(); } },
15+
{ "query", (a, n) => { a.Query = LoadSchema(n); } },
16+
{ "headers", (a, n) => { a.Headers = LoadSchema(n); } },
17+
};
18+
}
19+
}

src/LEGO.AsyncAPI/Models/Bindings/BindingType.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ public enum BindingType
1212
[Display("http")]
1313
Http,
1414

15+
[Display("websockets")]
16+
Websockets,
17+
1518
[Display("pulsar")]
1619
Pulsar,
1720
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright (c) The LEGO Group. All rights reserved.
2+
3+
namespace LEGO.AsyncAPI.Models.Bindings.WebSockets
4+
{
5+
using System;
6+
using System.Collections.Generic;
7+
using LEGO.AsyncAPI.Models.Interfaces;
8+
using LEGO.AsyncAPI.Writers;
9+
10+
public class WebSocketsChannelBinding : IChannelBinding
11+
{
12+
/// <summary>
13+
/// The HTTP method t use when establishing the connection. Its value MUST be either 'GET' or 'POST'.
14+
/// </summary>
15+
public string Method { get; set; }
16+
17+
/// <summary>
18+
/// A Schema object containing the definitions for each query parameter. This schema MUST be of type 'object' and have a 'properties' key.
19+
/// </summary>
20+
public AsyncApiSchema Query { get; set; }
21+
22+
/// <summary>
23+
/// A Schema object containing the definitions of the HTTP headers to use when establishing the connection. This schma MUST be of type 'object' and have a 'properties' key.
24+
/// </summary>
25+
public AsyncApiSchema Headers { get; set; }
26+
27+
public string BindingVersion { get; set; }
28+
29+
public bool UnresolvedReference { get; set; }
30+
31+
public AsyncApiReference Reference { get; set; }
32+
33+
public IDictionary<string, IAsyncApiExtension> Extensions { get; set; } =
34+
new Dictionary<string, IAsyncApiExtension>();
35+
36+
public BindingType Type => BindingType.Websockets;
37+
38+
public void SerializeV2WithoutReference(IAsyncApiWriter writer)
39+
{
40+
if (writer is null)
41+
{
42+
throw new ArgumentNullException(nameof(writer));
43+
}
44+
45+
writer.WriteStartObject();
46+
47+
writer.WriteOptionalProperty(AsyncApiConstants.Method, this.Method);
48+
writer.WriteOptionalObject(AsyncApiConstants.Query, this.Query, (w, h) => h.SerializeV2(w));
49+
writer.WriteOptionalObject(AsyncApiConstants.Headers, this.Headers, (w, h) => h.SerializeV2(w));
50+
writer.WriteOptionalProperty(AsyncApiConstants.BindingVersion, this.BindingVersion);
51+
52+
writer.WriteEndObject();
53+
}
54+
55+
public void SerializeV2(IAsyncApiWriter writer)
56+
{
57+
if (writer is null)
58+
{
59+
throw new ArgumentNullException(nameof(writer));
60+
}
61+
62+
if (this.Reference != null && writer.GetSettings().ReferenceInline != ReferenceInlineSetting.InlineReferences)
63+
{
64+
this.Reference.SerializeV2(writer);
65+
return;
66+
}
67+
68+
this.SerializeV2WithoutReference(writer);
69+
}
70+
}
71+
}

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

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,79 @@
1-
using LEGO.AsyncAPI.Models;
2-
using LEGO.AsyncAPI.Models.Bindings.Kafka;
3-
using LEGO.AsyncAPI.Models.Interfaces;
4-
using NUnit.Framework;
5-
6-
namespace LEGO.AsyncAPI.Tests.Models
1+
namespace LEGO.AsyncAPI.Tests.Models
72
{
3+
using System.Collections.Generic;
4+
using LEGO.AsyncAPI.Models;
5+
using LEGO.AsyncAPI.Models.Bindings.Kafka;
6+
using LEGO.AsyncAPI.Models.Bindings.WebSockets;
7+
using LEGO.AsyncAPI.Models.Interfaces;
8+
using NUnit.Framework;
9+
810
internal class AsyncApiChannel_Should
911
{
1012
[Test]
11-
public void AsyncApiChannel_WithBindings_Serializes()
13+
public void AsyncApiChannel_WithWebSocketsBinding_Serializes()
14+
{
15+
var expected = @"bindings:
16+
websockets:
17+
method: POST
18+
query:
19+
properties:
20+
index:
21+
description: the index
22+
headers:
23+
properties:
24+
x-correlation-id:
25+
description: the correlationid
26+
bindingVersion: 0.1.0";
27+
28+
var channel = new AsyncApiChannel
29+
{
30+
Bindings = new AsyncApiBindings<IChannelBinding>
31+
{
32+
{
33+
new WebSocketsChannelBinding()
34+
{
35+
Method = "POST",
36+
Query = new AsyncApiSchema()
37+
{
38+
Properties = new Dictionary<string, AsyncApiSchema>()
39+
{
40+
{
41+
"index", new AsyncApiSchema()
42+
{
43+
Description = "the index",
44+
}
45+
},
46+
},
47+
},
48+
Headers = new AsyncApiSchema()
49+
{
50+
Properties = new Dictionary<string, AsyncApiSchema>()
51+
{
52+
{
53+
"x-correlation-id", new AsyncApiSchema()
54+
{
55+
Description = "the correlationid",
56+
}
57+
},
58+
},
59+
},
60+
BindingVersion = "0.1.0",
61+
}
62+
},
63+
},
64+
};
65+
66+
var actual = channel.SerializeAsYaml();
67+
68+
actual = actual.MakeLineBreaksEnvironmentNeutral();
69+
expected = expected.MakeLineBreaksEnvironmentNeutral();
70+
71+
// Assert
72+
Assert.AreEqual(actual, expected);
73+
}
74+
75+
[Test]
76+
public void AsyncApiChannel_WithKafkaBinding_Serializes()
1277
{
1378
var expected =
1479
@"bindings:

0 commit comments

Comments
 (0)