Skip to content

Commit

Permalink
add union channels
Browse files Browse the repository at this point in the history
  • Loading branch information
yurvon-screamo committed Jul 9, 2024
1 parent ab74274 commit 4ca014d
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/Saunter/AsyncApiServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public static IServiceCollection AddAsyncApiSchemaGeneration(this IServiceCollec

services.TryAddSingleton<IAsyncApiDocumentCloner, AsyncApiDocumentSerializeCloner>();
services.TryAddSingleton<IAsyncApiSchemaGenerator, AsyncApiSchemaGenerator>();
services.TryAddSingleton<IAsyncApiChannelUnion, AsyncApiChannelUnion>();

services.TryAddTransient<IAsyncApiDocumentProvider, AttributeDocumentProvider>();

Expand Down
19 changes: 16 additions & 3 deletions src/Saunter/AttributeProvider/AttributeDocumentProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ internal class AttributeDocumentProvider : IAsyncApiDocumentProvider
{
private readonly IServiceProvider _serviceProvider;
private readonly IAsyncApiSchemaGenerator _schemaGenerator;
private readonly IAsyncApiChannelUnion _channelUnion;
private readonly IAsyncApiDocumentCloner _cloner;

public AttributeDocumentProvider(IServiceProvider serviceProvider, IAsyncApiSchemaGenerator schemaGenerator, IAsyncApiDocumentCloner cloner)
public AttributeDocumentProvider(IServiceProvider serviceProvider, IAsyncApiSchemaGenerator schemaGenerator, IAsyncApiChannelUnion channelUnion, IAsyncApiDocumentCloner cloner)
{
_serviceProvider = serviceProvider;
_schemaGenerator = schemaGenerator;
_channelUnion = channelUnion;
_cloner = cloner;
}

Expand Down Expand Up @@ -90,7 +92,13 @@ private void GenerateChannelsFromMethods(AsyncApiDocument document, AsyncApiOpti
: null,
};

document.Channels.Add(item.Channel.Name, channelItem);
if (!document.Channels.TryAdd(item.Channel.Name, channelItem))
{
document.Channels[item.Channel.Name] = _channelUnion.Union(
document.Channels[item.Channel.Name],
channelItem);
}

ApplyChannelFilters(options, item.Method, item.Channel, channelItem);
}
}
Expand Down Expand Up @@ -131,7 +139,12 @@ private void GenerateChannelsFromClasses(AsyncApiDocument document, AsyncApiOpti
: null,
};

document.Channels.Add(item.Channel.Name, channelItem);
if (!document.Channels.TryAdd(item.Channel.Name, channelItem))
{
document.Channels[item.Channel.Name] = _channelUnion.Union(
document.Channels[item.Channel.Name],
channelItem);
}

ApplyChannelFilters(options, item.Type, item.Channel, channelItem);
}
Expand Down
68 changes: 68 additions & 0 deletions src/Saunter/SharedKernel/AsyncApiChannelUnion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
using LEGO.AsyncAPI.Models;
using LEGO.AsyncAPI.Models.Interfaces;
using Saunter.SharedKernel.Interfaces;

namespace Saunter.SharedKernel
{
internal class AsyncApiChannelUnion : IAsyncApiChannelUnion
{
public AsyncApiChannel Union(AsyncApiChannel source, AsyncApiChannel additionaly)
{
if (source.Publish is not null && additionaly.Publish is not null)
{
throw new InvalidOperationException("Publish operation conflict");
}

if (source.Subscribe is not null && additionaly.Subscribe is not null)
{
throw new InvalidOperationException("Publish operation conflict");
}

if (source.Reference is not null && additionaly.Reference is not null)
{
throw new InvalidOperationException("Reference operation conflict");
}

var publishOperation = source.Publish ?? additionaly.Publish;
var subscribeOperation = source.Subscribe ?? additionaly.Subscribe;

var servers = source.Servers?.Any() == true
? source.Servers
: additionaly.Servers
?? new List<string>();

var bindings = source.Bindings?.Any() == true
? source.Bindings
: additionaly.Bindings
?? new();

var parameters = source.Parameters?.Any() == true
? source.Parameters
: additionaly.Parameters
?? new Dictionary<string, AsyncApiParameter>();

var extensions = source.Extensions?.Any() == true
? source.Extensions
: additionaly.Extensions
?? new Dictionary<string, IAsyncApiExtension>();

return new()
{
Publish = publishOperation,
Subscribe = subscribeOperation,
UnresolvedReference = source.UnresolvedReference,

Servers = servers,
Bindings = bindings,
Parameters = parameters,
Extensions = extensions,

Reference = source.Reference ?? additionaly.Reference,
Description = source.Description ?? additionaly.Description,
};
}
}
}
9 changes: 9 additions & 0 deletions src/Saunter/SharedKernel/Interfaces/IAsyncApiChannelUnion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using LEGO.AsyncAPI.Models;

namespace Saunter.SharedKernel.Interfaces
{
public interface IAsyncApiChannelUnion
{
AsyncApiChannel Union(AsyncApiChannel source, AsyncApiChannel additionaly);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static void Arrange(out AsyncApiOptions options, out AttributeDocumentPro
documentProvider = new AttributeDocumentProvider(
ActivatorServiceProvider.Instance,
new AsyncApiSchemaGenerator(),
new AsyncApiChannelUnion(),
new AsyncApiDocumentSerializeCloner(new FakeLogger<AsyncApiDocumentSerializeCloner>()));
}
}
Expand Down

0 comments on commit 4ca014d

Please sign in to comment.