158 lines
5.8 KiB
C#
158 lines
5.8 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using StellaOps.Plugin.Abstractions;
|
|
using StellaOps.Plugin.Abstractions.Capabilities;
|
|
using StellaOps.Router.Common.Plugins;
|
|
|
|
namespace StellaOps.Router.Plugin.Unified;
|
|
|
|
|
|
/// <summary>
|
|
/// Factory for creating unified transport plugin adapters from existing router transport plugins.
|
|
/// </summary>
|
|
public sealed class TransportPluginAdapterFactory
|
|
{
|
|
private readonly IEnumerable<IRouterTransportPlugin> _plugins;
|
|
private readonly Dictionary<string, TransportPluginAdapter> _adapters = new(StringComparer.OrdinalIgnoreCase);
|
|
private readonly object _lock = new();
|
|
|
|
/// <summary>
|
|
/// Known transport protocols for each transport type.
|
|
/// </summary>
|
|
private static readonly Dictionary<string, TransportProtocol> KnownProtocols = new(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
["tcp"] = TransportProtocol.Tcp,
|
|
["tls"] = TransportProtocol.Tls,
|
|
["udp"] = TransportProtocol.Udp,
|
|
["rabbitmq"] = TransportProtocol.Amqp,
|
|
["valkey"] = TransportProtocol.Redis,
|
|
["redis"] = TransportProtocol.Redis,
|
|
["inmemory"] = TransportProtocol.InMemory
|
|
};
|
|
|
|
/// <summary>
|
|
/// Known features for each transport type.
|
|
/// </summary>
|
|
private static readonly Dictionary<string, TransportFeatures> KnownFeatures = new(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
["tcp"] = TransportFeatures.RequestReply | TransportFeatures.Streaming | TransportFeatures.ConnectionPooling,
|
|
["tls"] = TransportFeatures.RequestReply | TransportFeatures.Streaming | TransportFeatures.TlsSupport | TransportFeatures.ConnectionPooling,
|
|
["udp"] = TransportFeatures.None, // UDP is connectionless, fire-and-forget
|
|
["rabbitmq"] = TransportFeatures.RequestReply | TransportFeatures.PubSub | TransportFeatures.Queuing | TransportFeatures.Acknowledgment | TransportFeatures.AutoReconnect,
|
|
["valkey"] = TransportFeatures.PubSub | TransportFeatures.Queuing | TransportFeatures.AutoReconnect,
|
|
["redis"] = TransportFeatures.PubSub | TransportFeatures.Queuing | TransportFeatures.AutoReconnect,
|
|
["inmemory"] = TransportFeatures.RequestReply | TransportFeatures.Streaming
|
|
};
|
|
|
|
/// <summary>
|
|
/// Creates a new factory instance.
|
|
/// </summary>
|
|
/// <param name="plugins">The available router transport plugins.</param>
|
|
public TransportPluginAdapterFactory(IEnumerable<IRouterTransportPlugin> plugins)
|
|
{
|
|
_plugins = plugins ?? throw new ArgumentNullException(nameof(plugins));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all available unified transport plugins.
|
|
/// </summary>
|
|
/// <param name="serviceProvider">Service provider for availability checking.</param>
|
|
/// <returns>List of unified transport plugins.</returns>
|
|
public IReadOnlyList<IPlugin> GetAllPlugins(IServiceProvider serviceProvider)
|
|
{
|
|
var result = new List<IPlugin>();
|
|
|
|
foreach (var plugin in _plugins)
|
|
{
|
|
if (plugin.IsAvailable(serviceProvider))
|
|
{
|
|
var adapter = GetOrCreateAdapter(plugin);
|
|
if (adapter != null)
|
|
{
|
|
result.Add(adapter);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a unified transport plugin by transport name.
|
|
/// </summary>
|
|
/// <param name="transportName">Transport name (e.g., "tcp", "tls", "rabbitmq").</param>
|
|
/// <returns>Unified transport plugin, or null if not found.</returns>
|
|
public IPlugin? GetPlugin(string transportName)
|
|
{
|
|
var plugin = _plugins.FirstOrDefault(p =>
|
|
p.TransportName.Equals(transportName, StringComparison.OrdinalIgnoreCase));
|
|
|
|
if (plugin == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return GetOrCreateAdapter(plugin);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the transport capability for a transport.
|
|
/// </summary>
|
|
/// <param name="transportName">Transport name.</param>
|
|
/// <returns>Transport capability, or null if not found.</returns>
|
|
public ITransportCapability? GetCapability(string transportName)
|
|
{
|
|
return GetPlugin(transportName) as ITransportCapability;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all available transport names.
|
|
/// </summary>
|
|
/// <returns>List of transport names.</returns>
|
|
public IReadOnlyList<string> GetAvailableTransports()
|
|
{
|
|
return _plugins.Select(p => p.TransportName).ToList();
|
|
}
|
|
|
|
private TransportPluginAdapter? GetOrCreateAdapter(IRouterTransportPlugin plugin)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (_adapters.TryGetValue(plugin.TransportName, out var existing))
|
|
{
|
|
return existing;
|
|
}
|
|
|
|
var protocol = KnownProtocols.TryGetValue(plugin.TransportName, out var p)
|
|
? p
|
|
: TransportProtocol.Tcp; // Default to TCP
|
|
|
|
var features = KnownFeatures.TryGetValue(plugin.TransportName, out var f)
|
|
? f
|
|
: TransportFeatures.RequestReply; // Default to request/reply
|
|
|
|
var adapter = new TransportPluginAdapter(plugin, protocol, features);
|
|
_adapters[plugin.TransportName] = adapter;
|
|
|
|
return adapter;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extension methods for registering unified transport plugin services.
|
|
/// </summary>
|
|
public static class TransportPluginAdapterExtensions
|
|
{
|
|
/// <summary>
|
|
/// Adds unified transport plugin adapter services to the service collection.
|
|
/// </summary>
|
|
/// <param name="services">Service collection.</param>
|
|
/// <returns>Service collection for chaining.</returns>
|
|
public static IServiceCollection AddUnifiedTransportPlugins(this IServiceCollection services)
|
|
{
|
|
services.AddSingleton<TransportPluginAdapterFactory>();
|
|
|
|
return services;
|
|
}
|
|
}
|