From 1f040cb19add20e70477112bd7d0477e67d59477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Espen=20T=C3=B8nnessen=20Nordli?= Date: Mon, 3 Feb 2020 18:57:52 +0100 Subject: [PATCH] Work in progress to implement multiple connections to RabbitMQ with one virtual host per tenant in the application. Each tenant specific microservice would then only be given the credentials for their own channel, while the baseline product would have to create connections to all the different virtual hosts in RabbitMQ, and also have awareness of which connection should be used for publishing an event. --- .../IMultiRabbitMQPersistentConnections.cs | 12 ++++ .../MultiRabbitMQPersistentConnections.cs | 30 +++++++++ src/Services/Basket/Basket.API/Startup.cs | 63 ++++++++++++++++++- src/Services/Catalog/Catalog.API/Startup.cs | 2 + .../Location/Locations.API/Startup.cs | 2 + .../Marketing/Marketing.API/Startup.cs | 2 + src/Services/Ordering/Ordering.API/Startup.cs | 3 + .../Ordering.BackgroundTasks/Startup.cs | 2 + .../Ordering/Ordering.SignalrHub/Startup.cs | 2 + src/Services/Payment/Payment.API/Startup.cs | 2 + .../TenantACustomisations/Startup.cs | 2 + src/Services/Webhooks/Webhooks.API/Startup.cs | 2 + 12 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/BuildingBlocks/EventBus/EventBusRabbitMQ/IMultiRabbitMQPersistentConnections.cs create mode 100644 src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiRabbitMQPersistentConnections.cs diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/IMultiRabbitMQPersistentConnections.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/IMultiRabbitMQPersistentConnections.cs new file mode 100644 index 000000000..f74d6dea8 --- /dev/null +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/IMultiRabbitMQPersistentConnections.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ +{ + public interface IMultiRabbitMQPersistentConnections + { + List GetConnections(); + void AddConnection(IRabbitMQPersistentConnection connection); + void RemoveConnection(IRabbitMQPersistentConnection connection); + } +} \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiRabbitMQPersistentConnections.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiRabbitMQPersistentConnections.cs new file mode 100644 index 000000000..a2e794695 --- /dev/null +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiRabbitMQPersistentConnections.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; + +namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ +{ + public class MultiRabbitMQPersistentConnections : IMultiRabbitMQPersistentConnections + { + public List Connections; + + public MultiRabbitMQPersistentConnections() + { + Connections = new List(); + } + + + public List GetConnections() + { + return Connections; + } + + public void AddConnection(IRabbitMQPersistentConnection connection) + { + Connections.Add((connection)); + } + + public void RemoveConnection(IRabbitMQPersistentConnection connection) + { + Connections.Remove(connection); + } + } +} \ No newline at end of file diff --git a/src/Services/Basket/Basket.API/Startup.cs b/src/Services/Basket/Basket.API/Startup.cs index 9cfabf20a..20a8e1d20 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -120,14 +120,31 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API factory.Password = Configuration["EventBusPassword"]; } + factory.VirtualHost = "customisation"; + var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) { retryCount = int.Parse(Configuration["EventBusRetryCount"]); } + + + return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); + + }); + + services.AddSingleton(sp => + { + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("customisation", sp)); + connections.AddConnection(GenerateConnection("/", sp)); + + return connections; }); + + } RegisterEventBus(services); @@ -178,7 +195,39 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API return new AutofacServiceProvider(container.Build()); } - + + + private IRabbitMQPersistentConnection GenerateConnection(String vHost, IServiceProvider sp) + { + var logger = sp.GetRequiredService>(); + + var factory = new ConnectionFactory() + { + HostName = Configuration["EventBusConnection"], + DispatchConsumersAsync = true + }; + + if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) + { + factory.UserName = Configuration["EventBusUserName"]; + } + + if (!string.IsNullOrEmpty(Configuration["EventBusPassword"])) + { + factory.Password = Configuration["EventBusPassword"]; + } + + factory.VirtualHost = vHost; + + var retryCount = 5; + if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) + { + retryCount = int.Parse(Configuration["EventBusRetryCount"]); + } + + return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); + + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) @@ -302,8 +351,20 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API retryCount = int.Parse(Configuration["EventBusRetryCount"]); } + + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + List testing = new List(); + + multiRabbitMqPersistentConnections.GetConnections().ForEach(conn => + { + testing.Add(new EventBusRabbitMQ(conn, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount)); + }); + + Console.WriteLine(testing); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); }); + } services.AddSingleton(); diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index 1a51a86fb..e619aaf07 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -310,6 +310,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API { factory.Password = configuration["EventBusPassword"]; } + + factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) diff --git a/src/Services/Location/Locations.API/Startup.cs b/src/Services/Location/Locations.API/Startup.cs index 4664381d0..bf9b1a700 100644 --- a/src/Services/Location/Locations.API/Startup.cs +++ b/src/Services/Location/Locations.API/Startup.cs @@ -90,6 +90,8 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API { factory.Password = Configuration["EventBusPassword"]; } + + factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) diff --git a/src/Services/Marketing/Marketing.API/Startup.cs b/src/Services/Marketing/Marketing.API/Startup.cs index 7f990e3ad..156edf98a 100644 --- a/src/Services/Marketing/Marketing.API/Startup.cs +++ b/src/Services/Marketing/Marketing.API/Startup.cs @@ -115,6 +115,8 @@ factory.Password = Configuration["EventBusPassword"]; } + factory.VirtualHost = "customisation"; + var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) { diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs index 8be92a453..bd242274d 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -318,6 +318,9 @@ { factory.Password = configuration["EventBusPassword"]; } + + factory.VirtualHost = "customisation"; + var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs index 9d6a78e38..d0f661299 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs @@ -81,6 +81,8 @@ namespace Ordering.BackgroundTasks { factory.Password = Configuration["EventBusPassword"]; } + + factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) diff --git a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs index edcc80521..ce283428d 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs @@ -93,6 +93,8 @@ namespace Ordering.SignalrHub { factory.Password = Configuration["EventBusPassword"]; } + + factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) diff --git a/src/Services/Payment/Payment.API/Startup.cs b/src/Services/Payment/Payment.API/Startup.cs index 39bb78f91..82bee3955 100644 --- a/src/Services/Payment/Payment.API/Startup.cs +++ b/src/Services/Payment/Payment.API/Startup.cs @@ -71,6 +71,8 @@ namespace Payment.API { factory.Password = Configuration["EventBusPassword"]; } + + factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) diff --git a/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs b/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs index c8f551829..19521e8b3 100644 --- a/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs +++ b/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs @@ -311,6 +311,8 @@ factory.Password = configuration["EventBusPassword"]; } + factory.VirtualHost = "customisation"; + var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) { diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs index f1a89d329..eb357ce1e 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -335,6 +335,8 @@ namespace Webhooks.API { factory.Password = configuration["EventBusPassword"]; } + + factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))