Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
6 changes: 6 additions & 0 deletions AsyncAPI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LEGO.AsyncAPI.Bindings", "src\LEGO.AsyncAPI.Bindings\LEGO.AsyncAPI.Bindings.csproj", "{33CA31F4-ECFE-4227-BFE9-F49783DD29A0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -32,6 +34,10 @@ Global
{7D9C6FBA-4B6F-48A0-B3F5-E7357021F8F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D9C6FBA-4B6F-48A0-B3F5-E7357021F8F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D9C6FBA-4B6F-48A0-B3F5-E7357021F8F9}.Release|Any CPU.Build.0 = Release|Any CPU
{33CA31F4-ECFE-4227-BFE9-F49783DD29A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33CA31F4-ECFE-4227-BFE9-F49783DD29A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33CA31F4-ECFE-4227-BFE9-F49783DD29A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33CA31F4-ECFE-4227-BFE9-F49783DD29A0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
28 changes: 28 additions & 0 deletions src/LEGO.AsyncAPI.Bindings/Binding.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace LEGO.AsyncAPI.Bindings
{
using Models.Interfaces;
using Readers.Interface;
using Readers.ParseNodes;

public abstract class Binding<T> : AsyncApiBinding, IBindingParser<T>
where T : IBinding, new()
{
protected void ParseMap<T>(
MapNode mapNode,
T domainObject,
FixedFieldMap<T> fixedFieldMap)
{
if (mapNode == null)
{
return;
}

foreach (var propertyNode in mapNode)
{
propertyNode.ParseField(domainObject, fixedFieldMap, null);
}
}

public abstract T LoadBinding(PropertyNode node);
}
}
68 changes: 68 additions & 0 deletions src/LEGO.AsyncAPI.Bindings/BindingsCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using LEGO.AsyncAPI.Bindings.Http;
using LEGO.AsyncAPI.Bindings.Kafka;
using LEGO.AsyncAPI.Bindings.Pulsar;
using LEGO.AsyncAPI.Bindings.WebSockets;
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Readers.Interface;

namespace LEGO.AsyncAPI.Bindings
{

public static class BindingsCollection
{
public static TCollection Add<TCollection, TItem>(
this TCollection destination,
IEnumerable<TItem> source)
where TCollection : ICollection<TItem>
{
ArgumentNullException.ThrowIfNull(destination);
ArgumentNullException.ThrowIfNull(source);

if (destination is List<TItem> list)
{
list.AddRange(source);
return destination;
}

foreach (var item in source)
{
destination.Add(item);
}

return destination;
}

public static IEnumerable<IBindingParser<IBinding>> All => new List<IBindingParser<IBinding>>
{
Pulsar,
Kafka,
Http,
};

public static IEnumerable<IBindingParser<IBinding>> Http => new List<IBindingParser<IBinding>>
{
new HttpOperationBinding(),
new HttpMessageBinding()
};

public static IEnumerable<IBindingParser<IBinding>> Websockets => new List<IBindingParser<IBinding>>
{
new WebSocketsChannelBinding(),
};

public static IEnumerable<IBindingParser<IBinding>> Kafka => new List<IBindingParser<IBinding>>
{
new KafkaServerBinding(),
new KafkaChannelBinding(),
new KafkaOperationBinding(),
new KafkaMessageBinding(),
};

public static IEnumerable<IBindingParser<IBinding>> Pulsar => new List<IBindingParser<IBinding>>
{
// Pulsar
new PulsarServerBinding(),
new PulsarChannelBinding(),
};
}
}
14 changes: 14 additions & 0 deletions src/LEGO.AsyncAPI.Bindings/ChannelBinding{T}.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace LEGO.AsyncAPI.Bindings
{
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Readers;
using LEGO.AsyncAPI.Readers.ParseNodes;

public abstract class ChannelBinding<T> : Binding<T>, IChannelBinding
where T : IChannelBinding, new()
{
protected abstract FixedFieldMap<T> FixedFieldMap { get; }

public override T LoadBinding(PropertyNode node) => BindingDeserializer.LoadBinding("ChannelBinding", node.Value, this.FixedFieldMap);
}
}
Comment thread
UlrikSandberg marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
// Copyright (c) The LEGO Group. All rights reserved.

namespace LEGO.AsyncAPI.Models.Bindings.Http
using LEGO.AsyncAPI.Models;

namespace LEGO.AsyncAPI.Bindings.Http
{
using System;
using System.Collections.Generic;
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Readers;
using LEGO.AsyncAPI.Readers.ParseNodes;
using LEGO.AsyncAPI.Writers;

/// <summary>
/// Binding class for http messaging channels.
/// </summary>
public class HttpMessageBinding : IMessageBinding
public class HttpMessageBinding : MessageBinding<HttpMessageBinding>
{

/// <summary>
Expand All @@ -36,7 +38,7 @@ public class HttpMessageBinding : IMessageBinding
/// <summary>
/// Serialize to AsyncAPI V2 document without using reference.
/// </summary>
public void SerializeV2WithoutReference(IAsyncApiWriter writer)
public override void SerializeProperties(IAsyncApiWriter writer)
{
if (writer is null)
{
Expand All @@ -45,31 +47,20 @@ public void SerializeV2WithoutReference(IAsyncApiWriter writer)

writer.WriteStartObject();

writer.WriteOptionalObject(AsyncApiConstants.Headers, this.Headers, (w, h) => h.SerializeV2(w));
writer.WriteOptionalProperty(AsyncApiConstants.BindingVersion, this.BindingVersion);
writer.WriteOptionalObject(AsyncApiConstants.Headers, Headers, (w, h) => h.SerializeV2(w));
writer.WriteOptionalProperty(AsyncApiConstants.BindingVersion, BindingVersion);
writer.WriteExtensions(Extensions);

writer.WriteEndObject();
}

public void SerializeV2(IAsyncApiWriter writer)
{
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}

if (this.Reference != null && !writer.GetSettings().ShouldInlineReference(this.Reference))
{
this.Reference.SerializeV2(writer);
return;
}

this.SerializeV2WithoutReference(writer);
}
public override string BindingKey => "http";

/// <inheritdoc/>
public IDictionary<string, IAsyncApiExtension> Extensions { get; set; } = new Dictionary<string, IAsyncApiExtension>();
protected override FixedFieldMap<HttpMessageBinding> FixedFieldMap => new()
{
{ "bindingVersion", (a, n) => { a.BindingVersion = n.GetScalarValue(); } },
{ "headers", (a, n) => { a.Headers = JsonSchemaDeserializer.LoadSchema(n); } },
};

public BindingType Type => BindingType.Http;
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
// Copyright (c) The LEGO Group. All rights reserved.

namespace LEGO.AsyncAPI.Models.Bindings.Http
using LEGO.AsyncAPI.Models;

namespace LEGO.AsyncAPI.Bindings.Http
{
using System;
using System.Collections.Generic;
using LEGO.AsyncAPI.Attributes;
using LEGO.AsyncAPI.Models.Interfaces;
using LEGO.AsyncAPI.Readers;
using LEGO.AsyncAPI.Readers.ParseNodes;
using LEGO.AsyncAPI.Writers;

/// <summary>
/// Binding class for http operations.
/// </summary>
public class HttpOperationBinding : IOperationBinding
public class HttpOperationBinding : OperationBinding<HttpOperationBinding>
{
public enum HttpOperationType
{
[Display("request")]
Request,

[Display("response")]
Response,
}
/// <summary>
/// REQUIRED. Type of operation. Its value MUST be either request or response.
/// </summary>
public string Type { get; set; }
public HttpOperationType? Type { get; set; }

/// <summary>
/// When type is request, this is the HTTP method, otherwise it MUST be ignored. Its value MUST be one of GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, CONNECT, and TRACE.
Expand All @@ -27,15 +39,10 @@ public class HttpOperationBinding : IOperationBinding
/// </summary>
public AsyncApiSchema Query { get; set; }

/// <summary>
/// The version of this binding. If omitted, "latest" MUST be assumed.
/// </summary>
public string BindingVersion { get; set; }

/// <summary>
/// Serialize to AsyncAPI V2 document without using reference.
/// </summary>
public void SerializeV2WithoutReference(IAsyncApiWriter writer)
public override void SerializeProperties(IAsyncApiWriter writer)
{
if (writer is null)
{
Expand All @@ -44,37 +51,29 @@ public void SerializeV2WithoutReference(IAsyncApiWriter writer)

writer.WriteStartObject();

writer.WriteRequiredProperty(AsyncApiConstants.Type, this.Type);
writer.WriteOptionalProperty(AsyncApiConstants.Method, this.Method);
writer.WriteOptionalObject(AsyncApiConstants.Query, this.Query, (w, h) => h.SerializeV2(w));
writer.WriteOptionalProperty(AsyncApiConstants.BindingVersion, this.BindingVersion);

writer.WriteRequiredProperty(AsyncApiConstants.Type, this.Type.GetDisplayName());
writer.WriteOptionalProperty(AsyncApiConstants.Method, Method);
writer.WriteOptionalObject(AsyncApiConstants.Query, Query, (w, h) => h.SerializeV2(w));
writer.WriteOptionalProperty(AsyncApiConstants.BindingVersion, BindingVersion);
writer.WriteExtensions(this.Extensions);
writer.WriteEndObject();
}

public void SerializeV2(IAsyncApiWriter writer)
{
if (writer is null)
{
throw new ArgumentNullException(nameof(writer));
}

if (this.Reference != null && !writer.GetSettings().ShouldInlineReference(this.Reference))
{
this.Reference.SerializeV2(writer);
return;
}

this.SerializeV2WithoutReference(writer);
}

/// <inheritdoc/>
public IDictionary<string, IAsyncApiExtension> Extensions { get; set; } = new Dictionary<string, IAsyncApiExtension>();


public bool UnresolvedReference { get; set; }

public AsyncApiReference Reference { get; set; }

BindingType IBinding.Type => BindingType.Http;
protected override FixedFieldMap<HttpOperationBinding> FixedFieldMap => new()
{
{ "bindingVersion", (a, n) => { a.BindingVersion = n.GetScalarValue(); } },
{ "type", (a, n) => { a.Type = n.GetScalarValue().GetEnumFromDisplayName<HttpOperationType>(); } },
{ "method", (a, n) => { a.Method = n.GetScalarValue(); } },
{ "query", (a, n) => { a.Query = JsonSchemaDeserializer.LoadSchema(n); } },
};

public override string BindingKey => "http";
}
}
Loading