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 1/6] 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"])) From d940d9a65d08d025d38b095ce26f76df6039ba74 Mon Sep 17 00:00:00 2001 From: espent1004 Date: Tue, 4 Feb 2020 19:50:01 +0100 Subject: [PATCH 2/6] WIP --- .../EventBus/Abstractions/IEventBus.cs | 8 +- .../EventBus/Abstractions/IMultiEventBus.cs | 15 ++++ .../EventBus/IEventBusSubscriptionsManager.cs | 16 ++-- .../InMemoryEventBusSubscriptionsManager.cs | 90 +++++++++++-------- .../EventBusRabbitMQ/EventBusRabbitMQ.cs | 28 +++--- .../EventBusRabbitMQ/MultiEventBusRabbitMQ.cs | 36 ++++++++ src/Services/Basket/Basket.API/Startup.cs | 34 +++++-- 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 | 2 +- .../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 +- 16 files changed, 166 insertions(+), 79 deletions(-) create mode 100644 src/BuildingBlocks/EventBus/EventBus/Abstractions/IMultiEventBus.cs create mode 100644 src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs diff --git a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs index dde05e1e3..368629681 100644 --- a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs +++ b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs @@ -7,17 +7,17 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions { void Publish(IntegrationEvent @event); - void Subscribe() + void Subscribe(String vHost) where T : IntegrationEvent where TH : IIntegrationEventHandler; - void SubscribeDynamic(string eventName) + void SubscribeDynamic(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler; - void UnsubscribeDynamic(string eventName) + void UnsubscribeDynamic(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler; - void Unsubscribe() + void Unsubscribe(String vHost) where TH : IIntegrationEventHandler where T : IntegrationEvent; } diff --git a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IMultiEventBus.cs b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IMultiEventBus.cs new file mode 100644 index 000000000..4057b261e --- /dev/null +++ b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IMultiEventBus.cs @@ -0,0 +1,15 @@ +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; + +namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions +{ + public interface IMultiEventBus + { + void AddEventBus(IEventBus eventBus); + + void Publish(IntegrationEvent @event); + + void Subscribe() + where T : IntegrationEvent + where TH : IIntegrationEventHandler; + } +} \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBus/IEventBusSubscriptionsManager.cs b/src/BuildingBlocks/EventBus/EventBus/IEventBusSubscriptionsManager.cs index c83c505b1..0c791816e 100644 --- a/src/BuildingBlocks/EventBus/EventBus/IEventBusSubscriptionsManager.cs +++ b/src/BuildingBlocks/EventBus/EventBus/IEventBusSubscriptionsManager.cs @@ -10,25 +10,25 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus { bool IsEmpty { get; } event EventHandler OnEventRemoved; - void AddDynamicSubscription(string eventName) + void AddDynamicSubscription(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler; - void AddSubscription() + void AddSubscription(String vHost) where T : IntegrationEvent where TH : IIntegrationEventHandler; - void RemoveSubscription() + void RemoveSubscription(String vHost) where TH : IIntegrationEventHandler where T : IntegrationEvent; - void RemoveDynamicSubscription(string eventName) + void RemoveDynamicSubscription(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler; - bool HasSubscriptionsForEvent() where T : IntegrationEvent; - bool HasSubscriptionsForEvent(string eventName); + bool HasSubscriptionsForEvent(String vHost) where T : IntegrationEvent; + bool HasSubscriptionsForEvent(string eventName, String vHost); Type GetEventTypeByName(string eventName); void Clear(); - IEnumerable GetHandlersForEvent() where T : IntegrationEvent; - IEnumerable GetHandlersForEvent(string eventName); + IEnumerable GetHandlersForEvent(String vHost) where T : IntegrationEvent; + IEnumerable GetHandlersForEvent(string eventName, String vHost); string GetEventKey(); } } \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs b/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs index ea1aca61e..dee3add48 100644 --- a/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs +++ b/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs @@ -10,48 +10,52 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus { - private readonly Dictionary> _handlers; + //private readonly Dictionary> _handlers; + private readonly Dictionary> _handlers; private readonly List _eventTypes; public event EventHandler OnEventRemoved; public InMemoryEventBusSubscriptionsManager() { - _handlers = new Dictionary>(); + //_handlers = new Dictionary>(); + _handlers = new Dictionary>(); _eventTypes = new List(); } public bool IsEmpty => !_handlers.Keys.Any(); public void Clear() => _handlers.Clear(); - public void AddDynamicSubscription(string eventName) + public void AddDynamicSubscription(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler { - DoAddSubscription(typeof(TH), eventName, isDynamic: true); + DoAddSubscription(typeof(TH), eventName, isDynamic: true, vHost); } - public void AddSubscription() + public void AddSubscription(String vHost) where T : IntegrationEvent where TH : IIntegrationEventHandler { var eventName = GetEventKey(); - DoAddSubscription(typeof(TH), eventName, isDynamic: false); - + DoAddSubscription(typeof(TH), eventName, isDynamic: false, vHost); + if (!_eventTypes.Contains(typeof(T))) { _eventTypes.Add(typeof(T)); } } - private void DoAddSubscription(Type handlerType, string eventName, bool isDynamic) + private void DoAddSubscription(Type handlerType, string eventName, bool isDynamic, String vHost) { - if (!HasSubscriptionsForEvent(eventName)) + var compositeHandler = new CompositeHandler{TenantVHostName = vHost, EventName = eventName}; + + if (!HasSubscriptionsForEvent(eventName, vHost)) { - _handlers.Add(eventName, new List()); + _handlers.Add(compositeHandler, new List()); } - if (_handlers[eventName].Any(s => s.HandlerType == handlerType)) + if (_handlers[compositeHandler].Any(s => s.HandlerType == handlerType)) { throw new ArgumentException( $"Handler Type {handlerType.Name} already registered for '{eventName}'", nameof(handlerType)); @@ -59,41 +63,43 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus if (isDynamic) { - _handlers[eventName].Add(SubscriptionInfo.Dynamic(handlerType)); + _handlers[compositeHandler].Add(SubscriptionInfo.Dynamic(handlerType)); } else { - _handlers[eventName].Add(SubscriptionInfo.Typed(handlerType)); + _handlers[compositeHandler].Add(SubscriptionInfo.Typed(handlerType)); } } - public void RemoveDynamicSubscription(string eventName) + public void RemoveDynamicSubscription(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler { - var handlerToRemove = FindDynamicSubscriptionToRemove(eventName); - DoRemoveHandler(eventName, handlerToRemove); + var handlerToRemove = FindDynamicSubscriptionToRemove(eventName, vHost); + DoRemoveHandler(eventName, handlerToRemove, vHost); } - public void RemoveSubscription() + public void RemoveSubscription(String vHost) where TH : IIntegrationEventHandler where T : IntegrationEvent { - var handlerToRemove = FindSubscriptionToRemove(); + var handlerToRemove = FindSubscriptionToRemove(vHost); var eventName = GetEventKey(); - DoRemoveHandler(eventName, handlerToRemove); + DoRemoveHandler(eventName, handlerToRemove, vHost); } - private void DoRemoveHandler(string eventName, SubscriptionInfo subsToRemove) + private void DoRemoveHandler(string eventName, SubscriptionInfo subsToRemove, String vHost) { if (subsToRemove != null) { - _handlers[eventName].Remove(subsToRemove); - if (!_handlers[eventName].Any()) + + var compositeHandler = new CompositeHandler{EventName = eventName, TenantVHostName = vHost}; + _handlers[compositeHandler].Remove(subsToRemove); + if (!_handlers[compositeHandler].Any()) { - _handlers.Remove(eventName); + _handlers.Remove(compositeHandler); var eventType = _eventTypes.SingleOrDefault(e => e.Name == eventName); if (eventType != null) { @@ -105,12 +111,12 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus } } - public IEnumerable GetHandlersForEvent() where T : IntegrationEvent + public IEnumerable GetHandlersForEvent(String vHost) where T : IntegrationEvent { var key = GetEventKey(); - return GetHandlersForEvent(key); + return GetHandlersForEvent(key, vHost); } - public IEnumerable GetHandlersForEvent(string eventName) => _handlers[eventName]; + public IEnumerable GetHandlersForEvent(string eventName, String vHost) => _handlers[new CompositeHandler{EventName = eventName, TenantVHostName = vHost}]; private void RaiseOnEventRemoved(string eventName) { @@ -119,38 +125,43 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus } - private SubscriptionInfo FindDynamicSubscriptionToRemove(string eventName) + private SubscriptionInfo FindDynamicSubscriptionToRemove(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler { - return DoFindSubscriptionToRemove(eventName, typeof(TH)); + return DoFindSubscriptionToRemove(eventName, typeof(TH), vHost); } - private SubscriptionInfo FindSubscriptionToRemove() + private SubscriptionInfo FindSubscriptionToRemove(String vHost) where T : IntegrationEvent where TH : IIntegrationEventHandler { var eventName = GetEventKey(); - return DoFindSubscriptionToRemove(eventName, typeof(TH)); + + return DoFindSubscriptionToRemove(eventName, typeof(TH), vHost); } - private SubscriptionInfo DoFindSubscriptionToRemove(string eventName, Type handlerType) + private SubscriptionInfo DoFindSubscriptionToRemove(string eventName, Type handlerType, String vHost) { - if (!HasSubscriptionsForEvent(eventName)) + + if (!HasSubscriptionsForEvent(eventName, vHost)) { return null; } + + var compositeHandler = new CompositeHandler{EventName = eventName, TenantVHostName = vHost}; - return _handlers[eventName].SingleOrDefault(s => s.HandlerType == handlerType); + return _handlers[compositeHandler].SingleOrDefault(s => s.HandlerType == handlerType); } - public bool HasSubscriptionsForEvent() where T : IntegrationEvent + public bool HasSubscriptionsForEvent(String vHost) where T : IntegrationEvent { var key = GetEventKey(); - return HasSubscriptionsForEvent(key); + + return HasSubscriptionsForEvent(key, vHost); } - public bool HasSubscriptionsForEvent(string eventName) => _handlers.ContainsKey(eventName); + public bool HasSubscriptionsForEvent(string eventName, String vHost) => _handlers.ContainsKey(new CompositeHandler{EventName = eventName, TenantVHostName = vHost}); public Type GetEventTypeByName(string eventName) => _eventTypes.SingleOrDefault(t => t.Name == eventName); @@ -160,3 +171,10 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus } } } + + +class CompositeHandler +{ + public String TenantVHostName { get; set; } + public String EventName { get; set; } +} \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index 5f68648d8..c9d148aaf 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -12,12 +12,8 @@ using RabbitMQ.Client; using RabbitMQ.Client.Events; using RabbitMQ.Client.Exceptions; using System; -using System.Collections; using System.Collections.Generic; -using System.Diagnostics; -using System.Net; using System.Net.Http; -using System.Net.Mime; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; @@ -130,34 +126,34 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ } } - public void SubscribeDynamic(string eventName) + public void SubscribeDynamic(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler { _logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName()); - DoInternalSubscription(eventName); - _subsManager.AddDynamicSubscription(eventName); + DoInternalSubscription(eventName, vHost); + _subsManager.AddDynamicSubscription(eventName, vHost); StartBasicConsume(); } - public void Subscribe() + public void Subscribe(String vHost) where T : IntegrationEvent where TH : IIntegrationEventHandler { var eventName = _subsManager.GetEventKey(); - DoInternalSubscription(eventName); + DoInternalSubscription(eventName, vHost); _logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName()); - _subsManager.AddSubscription(); + _subsManager.AddSubscription(vHost); StartBasicConsume(); } - private void DoInternalSubscription(string eventName) + private void DoInternalSubscription(string eventName, String vHost) { - var containsKey = _subsManager.HasSubscriptionsForEvent(eventName); + var containsKey = _subsManager.HasSubscriptionsForEvent(eventName, vHost); if (!containsKey) { if (!_persistentConnection.IsConnected) @@ -174,7 +170,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ } } - public void Unsubscribe() + public void Unsubscribe(String vHost) where T : IntegrationEvent where TH : IIntegrationEventHandler { @@ -182,13 +178,13 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _logger.LogInformation("Unsubscribing from event {EventName}", eventName); - _subsManager.RemoveSubscription(); + _subsManager.RemoveSubscription(vHost); } - public void UnsubscribeDynamic(string eventName) + public void UnsubscribeDynamic(string eventName, String vHost) where TH : IDynamicIntegrationEventHandler { - _subsManager.RemoveDynamicSubscription(eventName); + _subsManager.RemoveDynamicSubscription(eventName, vHost); } public void Dispose() diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs new file mode 100644 index 000000000..17e161c09 --- /dev/null +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; + +namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ +{ + public class MultiEventBusRabbitMQ : IMultiEventBus + { + + private List _eventBuses; + + public MultiEventBusRabbitMQ(List eventBuses) + { + _eventBuses = eventBuses; + } + + public void AddEventBus(IEventBus eventBus) + { + _eventBuses.Add(eventBus); + } + + public void Publish(IntegrationEvent @event) + { + + throw new System.NotImplementedException(); + } + + public void Subscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler + { + _eventBuses.ForEach(e => + { + e.Subscribe(); + }); + } + } +} \ 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 20a8e1d20..731ae3d2c 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -120,7 +120,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API factory.Password = Configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + //factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) @@ -138,7 +138,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API services.AddSingleton(sp => { IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); - connections.AddConnection(GenerateConnection("customisation", sp)); + connections.AddConnection(GenerateConnection("TenantA", sp)); + connections.AddConnection(GenerateConnection("TenantB", sp)); connections.AddConnection(GenerateConnection("/", sp)); return connections; @@ -338,7 +339,30 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API } else { - services.AddSingleton(sp => + + services.AddSingleton(sp => + { + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + var iLifetimeScope = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubcriptionsManager = sp.GetRequiredService(); + + var retryCount = 5; + if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) + { + retryCount = int.Parse(Configuration["EventBusRetryCount"]); + } + List eventBuses = new List(); + + multiRabbitMqPersistentConnections.GetConnections().ForEach(conn => + { + eventBuses.Add(new EventBusRabbitMQ(conn, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount)); + }); + + return new MultiEventBusRabbitMQ(eventBuses); + }); + + /* services.AddSingleton(sp => { var rabbitMQPersistentConnection = sp.GetRequiredService(); var iLifetimeScope = sp.GetRequiredService(); @@ -363,7 +387,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API Console.WriteLine(testing); return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); - }); + });*/ } @@ -375,7 +399,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API private void ConfigureEventBus(IApplicationBuilder app) { - var eventBus = app.ApplicationServices.GetRequiredService(); + var eventBus = app.ApplicationServices.GetRequiredService(); eventBus.Subscribe(); eventBus.Subscribe(); diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index e619aaf07..36abdc927 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -311,7 +311,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API factory.Password = configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + //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 bf9b1a700..71ebf1fa7 100644 --- a/src/Services/Location/Locations.API/Startup.cs +++ b/src/Services/Location/Locations.API/Startup.cs @@ -91,7 +91,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API factory.Password = Configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + //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 156edf98a..9db283bb5 100644 --- a/src/Services/Marketing/Marketing.API/Startup.cs +++ b/src/Services/Marketing/Marketing.API/Startup.cs @@ -115,7 +115,7 @@ factory.Password = Configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + // 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 bd242274d..e3852dac8 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -319,7 +319,7 @@ factory.Password = configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + //factory.VirtualHost = "customisation"; var retryCount = 5; diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs index d0f661299..4da64452d 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs @@ -82,8 +82,6 @@ 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 ce283428d..f69ac78f3 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs @@ -94,7 +94,7 @@ namespace Ordering.SignalrHub factory.Password = Configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + //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 82bee3955..1e0a35e42 100644 --- a/src/Services/Payment/Payment.API/Startup.cs +++ b/src/Services/Payment/Payment.API/Startup.cs @@ -72,7 +72,7 @@ namespace Payment.API factory.Password = Configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + // 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 19521e8b3..f99fc8be0 100644 --- a/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs +++ b/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs @@ -311,7 +311,7 @@ factory.Password = configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + //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 eb357ce1e..8599657f9 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -336,7 +336,7 @@ namespace Webhooks.API factory.Password = configuration["EventBusPassword"]; } - factory.VirtualHost = "customisation"; + //factory.VirtualHost = "customisation"; var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) From 2a42053817d096e3434745f5d9d904840421f8ce Mon Sep 17 00:00:00 2001 From: espent1004 Date: Tue, 4 Feb 2020 23:25:10 +0100 Subject: [PATCH 3/6] Implementing MultiEventBusRabbitMQ to allow for multiple connections to multiple virtual hosts in RabbitMQ, where it is intended to have one virtual host per tenant to achieve tenant isolation. TODO: Implement in all microservices, and fix selection of actualEventBus in the Publish method in MultiEventBusRabbitMQ --- .../EventBus/Abstractions/IEventBus.cs | 10 ++++--- .../InMemoryEventBusSubscriptionsManager.cs | 21 ++++++++++++++ .../EventBusRabbitMQ/EventBusRabbitMQ.cs | 29 ++++++++++++------- .../EventBusRabbitMQ/MultiEventBusRabbitMQ.cs | 18 +++++++----- .../EventBusServiceBus/EventBusServiceBus.cs | 3 +- .../Controllers/BasketController.cs | 4 +-- src/Services/Basket/Basket.API/Startup.cs | 27 ++++++++++------- src/Services/Catalog/Catalog.API/Startup.cs | 8 ++--- .../Location/Locations.API/Startup.cs | 8 ++--- .../Marketing/Marketing.API/Startup.cs | 8 ++--- src/Services/Ordering/Ordering.API/Startup.cs | 8 ++--- .../Ordering/Ordering.API/appsettings.json | 4 +-- .../Ordering.BackgroundTasks/Startup.cs | 8 +++-- .../Ordering/Ordering.SignalrHub/Startup.cs | 8 ++--- src/Services/Payment/Payment.API/Startup.cs | 8 ++--- .../TenantACustomisations/Startup.cs | 8 ++--- src/Services/Webhooks/Webhooks.API/Startup.cs | 8 ++--- 17 files changed, 115 insertions(+), 73 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs index 368629681..3b58f2e49 100644 --- a/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs +++ b/src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs @@ -7,18 +7,20 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions { void Publish(IntegrationEvent @event); - void Subscribe(String vHost) + void Subscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler; - void SubscribeDynamic(string eventName, String vHost) + void SubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler; - void UnsubscribeDynamic(string eventName, String vHost) + void UnsubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler; - void Unsubscribe(String vHost) + void Unsubscribe() where TH : IIntegrationEventHandler where T : IntegrationEvent; + + String GetVHost(); } } diff --git a/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs b/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs index dee3add48..e13881fbe 100644 --- a/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs +++ b/src/BuildingBlocks/EventBus/EventBus/InMemoryEventBusSubscriptionsManager.cs @@ -177,4 +177,25 @@ class CompositeHandler { public String TenantVHostName { get; set; } public String EventName { get; set; } + + protected bool Equals(CompositeHandler other) + { + return TenantVHostName == other.TenantVHostName && EventName == other.EventName; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((CompositeHandler) obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((TenantVHostName != null ? TenantVHostName.GetHashCode() : 0) * 397) ^ (EventName != null ? EventName.GetHashCode() : 0); + } + } } \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index c9d148aaf..84d39c979 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -33,14 +33,15 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ private static readonly String tenantACustomisationUrl = @"http://tenantacustomisation/"; private static readonly String tenantManagerUrl = @"http://tenantmanager/"; private readonly int _retryCount; - private readonly Dictionary _tenantInfo; + private readonly Dictionary _tenantInfo; + public String vHost { get; set; } private IModel _consumerChannel; private string _queueName; public EventBusRabbitMQ(IRabbitMQPersistentConnection persistentConnection, ILogger logger, - ILifetimeScope autofac, IEventBusSubscriptionsManager subsManager, string queueName = null, + ILifetimeScope autofac, IEventBusSubscriptionsManager subsManager, String vhost, string queueName = null, int retryCount = 5) { _persistentConnection = @@ -55,6 +56,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _tenantInfo = new Dictionary(); _tenantInfo.Add(1, "TenantA"); _tenantInfo.Add(2, "TenantB"); + vHost = vhost; } private void SubsManager_OnEventRemoved(object sender, string eventName) @@ -126,23 +128,23 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ } } - public void SubscribeDynamic(string eventName, String vHost) + public void SubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler { _logger.LogInformation("Subscribing to dynamic event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName()); - DoInternalSubscription(eventName, vHost); + DoInternalSubscription(eventName); _subsManager.AddDynamicSubscription(eventName, vHost); StartBasicConsume(); } - public void Subscribe(String vHost) + public void Subscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler { var eventName = _subsManager.GetEventKey(); - DoInternalSubscription(eventName, vHost); + DoInternalSubscription(eventName); _logger.LogInformation("Subscribing to event {EventName} with {EventHandler}", eventName, typeof(TH).GetGenericTypeName()); @@ -151,7 +153,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ StartBasicConsume(); } - private void DoInternalSubscription(string eventName, String vHost) + private void DoInternalSubscription(string eventName) { var containsKey = _subsManager.HasSubscriptionsForEvent(eventName, vHost); if (!containsKey) @@ -170,7 +172,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ } } - public void Unsubscribe(String vHost) + public void Unsubscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler { @@ -181,7 +183,12 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _subsManager.RemoveSubscription(vHost); } - public void UnsubscribeDynamic(string eventName, String vHost) + public string GetVHost() + { + return vHost; + } + + public void UnsubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler { _subsManager.RemoveDynamicSubscription(eventName, vHost); @@ -337,11 +344,11 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ { _logger.LogWarning("Processing RabbitMQ event: {EventName}", eventName); - if (_subsManager.HasSubscriptionsForEvent(eventName)) + if (_subsManager.HasSubscriptionsForEvent(eventName, vHost)) { using (var scope = _autofac.BeginLifetimeScope(AUTOFAC_SCOPE_NAME)) { - var subscriptions = _subsManager.GetHandlersForEvent(eventName); + var subscriptions = _subsManager.GetHandlersForEvent(eventName, vHost); foreach (var subscription in subscriptions) { if (subscription.IsDynamic) diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs index 17e161c09..9a92a1eb7 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; @@ -6,7 +7,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ { public class MultiEventBusRabbitMQ : IMultiEventBus { - private List _eventBuses; public MultiEventBusRabbitMQ(List eventBuses) @@ -21,16 +21,20 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ public void Publish(IntegrationEvent @event) { + //TODO + var actualEventBus = _eventBuses.Find(e => e.GetVHost().Equals("TenantA")); + + if (actualEventBus == null) + { + throw new Exception(); + } - throw new System.NotImplementedException(); + actualEventBus.Publish(@event); } public void Subscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler { - _eventBuses.ForEach(e => - { - e.Subscribe(); - }); + _eventBuses.ForEach(e => { e.Subscribe(); }); } } } \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs index 53ae33ae0..f88361688 100644 --- a/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs +++ b/src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.cs @@ -1,4 +1,4 @@ -namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus +/*namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus { using Autofac; using Microsoft.Azure.ServiceBus; @@ -206,3 +206,4 @@ } } } +*/ \ No newline at end of file diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index c69d82a89..10036c283 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -21,14 +21,14 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers { private readonly IBasketRepository _repository; private readonly IIdentityService _identityService; - private readonly IEventBus _eventBus; + private readonly IMultiEventBus _eventBus; private readonly ILogger _logger; public BasketController( ILogger logger, IBasketRepository repository, IIdentityService identityService, - IEventBus eventBus) + IMultiEventBus eventBus) { _logger = logger; _repository = repository; diff --git a/src/Services/Basket/Basket.API/Startup.cs b/src/Services/Basket/Basket.API/Startup.cs index 731ae3d2c..8892b812a 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -86,7 +86,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API }); - if (Configuration.GetValue("AzureServiceBusEnabled")) + +/* if (Configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -97,8 +98,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); }); - } - else + }*/ +/* else { services.AddSingleton(sp => { @@ -120,7 +121,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API factory.Password = Configuration["EventBusPassword"]; } - //factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) @@ -133,7 +134,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); + });*/ services.AddSingleton(sp => { @@ -146,7 +147,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API }); - } + //} RegisterEventBus(services); @@ -324,7 +325,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API { var subscriptionClientName = Configuration["SubscriptionClientName"]; - if (Configuration.GetValue("AzureServiceBusEnabled")) + /*if (Configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -338,7 +339,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API }); } else - { + {*/ services.AddSingleton(sp => { @@ -354,10 +355,14 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API } List eventBuses = new List(); - multiRabbitMqPersistentConnections.GetConnections().ForEach(conn => + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + + + /*multiRabbitMqPersistentConnections.GetConnections().ForEach(conn => { eventBuses.Add(new EventBusRabbitMQ(conn, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount)); - }); + });*/ return new MultiEventBusRabbitMQ(eventBuses); }); @@ -389,7 +394,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API 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 36abdc927..c9955b7ac 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -311,7 +311,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API factory.Password = configuration["EventBusPassword"]; } - //factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) @@ -330,7 +330,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API { var subscriptionClientName = configuration["SubscriptionClientName"]; - if (configuration.GetValue("AzureServiceBusEnabled")) +/* if (configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -344,7 +344,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API }); } - else + else*/ { services.AddSingleton(sp => { @@ -359,7 +359,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API retryCount = int.Parse(configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/Location/Locations.API/Startup.cs b/src/Services/Location/Locations.API/Startup.cs index 71ebf1fa7..06f9d55af 100644 --- a/src/Services/Location/Locations.API/Startup.cs +++ b/src/Services/Location/Locations.API/Startup.cs @@ -91,7 +91,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API factory.Password = Configuration["EventBusPassword"]; } - //factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) @@ -246,7 +246,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API { var subscriptionClientName = Configuration["SubscriptionClientName"]; - if (Configuration.GetValue("AzureServiceBusEnabled")) +/* if (Configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -259,7 +259,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); }); } - else + else*/ { services.AddSingleton(sp => { @@ -274,7 +274,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API retryCount = int.Parse(Configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/Marketing/Marketing.API/Startup.cs b/src/Services/Marketing/Marketing.API/Startup.cs index 9db283bb5..4d190be1a 100644 --- a/src/Services/Marketing/Marketing.API/Startup.cs +++ b/src/Services/Marketing/Marketing.API/Startup.cs @@ -115,7 +115,7 @@ factory.Password = Configuration["EventBusPassword"]; } - // factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) @@ -260,7 +260,7 @@ { var subscriptionClientName = Configuration["SubscriptionClientName"]; - if (Configuration.GetValue("AzureServiceBusEnabled")) +/* if (Configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -273,7 +273,7 @@ eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); }); } - else + else*/ { services.AddSingleton(sp => { @@ -288,7 +288,7 @@ retryCount = int.Parse(Configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs index e3852dac8..9c4e25aea 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -319,7 +319,7 @@ factory.Password = configuration["EventBusPassword"]; } - //factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; @@ -364,7 +364,7 @@ { var subscriptionClientName = configuration["SubscriptionClientName"]; - if (configuration.GetValue("AzureServiceBusEnabled")) +/* if (configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -377,7 +377,7 @@ eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); }); } - else + else*/ { services.AddSingleton(sp => { @@ -392,7 +392,7 @@ retryCount = int.Parse(configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/Ordering/Ordering.API/appsettings.json b/src/Services/Ordering/Ordering.API/appsettings.json index f74c312b1..ddb377d46 100644 --- a/src/Services/Ordering/Ordering.API/appsettings.json +++ b/src/Services/Ordering/Ordering.API/appsettings.json @@ -6,10 +6,10 @@ "SeqServerUrl": null, "LogstashgUrl": null, "MinimumLevel": { - "Default": "Information", + "Default": "Verbose", "Override": { "Microsoft": "Warning", - "Microsoft.eShopOnContainers": "Information", + "Microsoft.eShopOnContainers": "Verbose", "System": "Warning" } } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs index 4da64452d..408cf42cd 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 = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) @@ -123,7 +125,7 @@ namespace Ordering.BackgroundTasks { var subscriptionClientName = Configuration["SubscriptionClientName"]; - if (Configuration.GetValue("AzureServiceBusEnabled")) +/* if (Configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -136,7 +138,7 @@ namespace Ordering.BackgroundTasks eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); }); } - else + else*/ { services.AddSingleton(sp => { @@ -151,7 +153,7 @@ namespace Ordering.BackgroundTasks retryCount = int.Parse(Configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs index f69ac78f3..4929ffed0 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs @@ -94,7 +94,7 @@ namespace Ordering.SignalrHub factory.Password = Configuration["EventBusPassword"]; } - //factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) @@ -195,7 +195,7 @@ namespace Ordering.SignalrHub { var subscriptionClientName = Configuration["SubscriptionClientName"]; - if (Configuration.GetValue("AzureServiceBusEnabled")) +/* if (Configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -208,7 +208,7 @@ namespace Ordering.SignalrHub eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); }); } - else + else*/ { services.AddSingleton(sp => { @@ -223,7 +223,7 @@ namespace Ordering.SignalrHub retryCount = int.Parse(Configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/Payment/Payment.API/Startup.cs b/src/Services/Payment/Payment.API/Startup.cs index 1e0a35e42..5692f6826 100644 --- a/src/Services/Payment/Payment.API/Startup.cs +++ b/src/Services/Payment/Payment.API/Startup.cs @@ -72,7 +72,7 @@ namespace Payment.API factory.Password = Configuration["EventBusPassword"]; } - // factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) @@ -140,7 +140,7 @@ namespace Payment.API { var subscriptionClientName = Configuration["SubscriptionClientName"]; - if (Configuration.GetValue("AzureServiceBusEnabled")) +/* if (Configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -153,7 +153,7 @@ namespace Payment.API eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); }); } - else + else*/ { services.AddSingleton(sp => { @@ -168,7 +168,7 @@ namespace Payment.API retryCount = int.Parse(Configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs b/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs index f99fc8be0..b61568d67 100644 --- a/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs +++ b/src/Services/TenantCustomisations/TenantACustomisations/Startup.cs @@ -311,7 +311,7 @@ factory.Password = configuration["EventBusPassword"]; } - //factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) @@ -355,7 +355,7 @@ { var subscriptionClientName = configuration["SubscriptionClientName"]; - if (configuration.GetValue("AzureServiceBusEnabled")) +/* if (configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -368,7 +368,7 @@ eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); }); } - else + else*/ { services.AddSingleton(sp => { @@ -383,7 +383,7 @@ retryCount = int.Parse(configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs index 8599657f9..e54163bc6 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -232,7 +232,7 @@ namespace Webhooks.API { var subscriptionClientName = configuration["SubscriptionClientName"]; - if (configuration.GetValue("AzureServiceBusEnabled")) +/* if (configuration.GetValue("AzureServiceBusEnabled")) { services.AddSingleton(sp => { @@ -246,7 +246,7 @@ namespace Webhooks.API }); } - else + else*/ { services.AddSingleton(sp => { @@ -261,7 +261,7 @@ namespace Webhooks.API retryCount = int.Parse(configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); + return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); }); } @@ -336,7 +336,7 @@ namespace Webhooks.API factory.Password = configuration["EventBusPassword"]; } - //factory.VirtualHost = "customisation"; + factory.VirtualHost = "TenantA"; var retryCount = 5; if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) From 748a0596d314619fe279089ffa667a639863f7d1 Mon Sep 17 00:00:00 2001 From: espent1004 Date: Wed, 5 Feb 2020 22:15:48 +0100 Subject: [PATCH 4/6] Implementing IMultiEventBus in all baseline microservices. Still need to ensure that tenantId is set for all events. --- .../EventBusRabbitMQ/MultiEventBusRabbitMQ.cs | 18 +- src/Services/Basket/Basket.API/Startup.cs | 204 +++++------------- .../CatalogIntegrationEventService.cs | 4 +- src/Services/Catalog/Catalog.API/Startup.cs | 105 +++++---- .../Services/LocationsService.cs | 4 +- .../Location/Locations.API/Startup.cs | 189 ++++++++-------- .../Marketing/Marketing.API/Startup.cs | 117 +++++----- ...CheckoutAcceptedIntegrationEventHandler.cs | 4 +- .../OrderingIntegrationEventService.cs | 4 +- src/Services/Ordering/Ordering.API/Startup.cs | 103 ++++----- .../Ordering.BackgroundTasks/Startup.cs | 140 ++++++------ .../Tasks/GracePeriodManagerTask.cs | 4 +- .../Ordering/Ordering.SignalrHub/Startup.cs | 180 ++++++++-------- ...ToStockConfirmedIntegrationEventHandler.cs | 4 +- src/Services/Payment/Payment.API/Startup.cs | 140 ++++++------ src/Services/Webhooks/Webhooks.API/Startup.cs | 113 +++++----- 16 files changed, 602 insertions(+), 731 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs index 9a92a1eb7..f386f9b41 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs @@ -8,10 +8,12 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ public class MultiEventBusRabbitMQ : IMultiEventBus { private List _eventBuses; + private Dictionary _tenants; - public MultiEventBusRabbitMQ(List eventBuses) + public MultiEventBusRabbitMQ(List eventBuses, Dictionary tenants) { _eventBuses = eventBuses; + _tenants = tenants; } public void AddEventBus(IEventBus eventBus) @@ -21,13 +23,17 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ public void Publish(IntegrationEvent @event) { - //TODO - var actualEventBus = _eventBuses.Find(e => e.GetVHost().Equals("TenantA")); - - if (actualEventBus == null) + if (@event.TenantId == 0)//System wide event? { - throw new Exception(); + _eventBuses.ForEach(eventBus => + { + eventBus.Publish(@event); + }); } + + //TODO requires ALL events to have tenantId set! + _tenants.TryGetValue(@event.TenantId, out String tenantName); + var actualEventBus = _eventBuses.Find(e => e.GetVHost().Equals(tenantName)); actualEventBus.Publish(@event); } diff --git a/src/Services/Basket/Basket.API/Startup.cs b/src/Services/Basket/Basket.API/Startup.cs index 8892b812a..11413e929 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -5,7 +5,6 @@ using Basket.API.Infrastructure.Middlewares; using Basket.API.IntegrationEvents.EventHandling; using Basket.API.IntegrationEvents.Events; using HealthChecks.UI.Client; - using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.ServiceFabric; using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -58,7 +57,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); options.Filters.Add(typeof(ValidateModelStateFilter)); - }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddControllersAsServices(); @@ -85,69 +83,15 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API return ConnectionMultiplexer.Connect(configuration); }); - - -/* if (Configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var serviceBusConnectionString = Configuration["EventBusConnection"]; - var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); - - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - }*/ -/* else + services.AddSingleton(sp => { - services.AddSingleton(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 = "TenantA"; - - 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("TenantA", sp)); - connections.AddConnection(GenerateConnection("TenantB", sp)); - connections.AddConnection(GenerateConnection("/", sp)); - - return connections; - }); + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp)); + connections.AddConnection(GenerateConnection("TenantB", sp)); + return connections; + }); - //} RegisterEventBus(services); @@ -170,7 +114,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API TokenUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/token", Scopes = new Dictionary() { - { "basket", "Basket API" } + {"basket", "Basket API"} } }); @@ -181,10 +125,10 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API { options.AddPolicy("CorsPolicy", builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); + .SetIsOriginAllowed((host) => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials()); }); services.AddSingleton(); services.AddTransient(); @@ -226,9 +170,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API { retryCount = int.Parse(Configuration["EventBusRetryCount"]); } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); + return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -254,7 +197,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API Predicate = r => r.Name.Contains("self") }); - app.UseStaticFiles(); + app.UseStaticFiles(); app.UseCors("CorsPolicy"); ConfigureAuth(app); @@ -262,27 +205,29 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API app.UseMvcWithDefaultRoute(); app.UseSwagger() - .UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Basket.API V1"); - c.OAuthClientId ("basketswaggerui"); - c.OAuthAppName("Basket Swagger UI"); - }); + .UseSwaggerUI(c => + { + c.SwaggerEndpoint( + $"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", + "Basket.API V1"); + c.OAuthClientId("basketswaggerui"); + c.OAuthAppName("Basket Swagger UI"); + }); ConfigureEventBus(app); - } private void RegisterAppInsights(IServiceCollection services) { services.AddApplicationInsightsTelemetry(Configuration); var orchestratorType = Configuration.GetValue("OrchestratorType"); - + if (orchestratorType?.ToUpper() == "K8S") { // Enable K8s telemetry initializer services.AddApplicationInsightsKubernetesEnricher(); } + if (orchestratorType?.ToUpper() == "SF") { // Enable SF telemetry initializer @@ -296,13 +241,12 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API // prevent from mapping "sub" claim to nameidentifier. JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - var identityUrl = Configuration.GetValue("IdentityUrl"); - + var identityUrl = Configuration.GetValue("IdentityUrl"); + services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }).AddJwtBearer(options => { options.Authority = identityUrl; @@ -325,76 +269,31 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API { var subscriptionClientName = Configuration["SubscriptionClientName"]; - /*if (Configuration.GetValue("AzureServiceBusEnabled")) + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - } - else - {*/ - - services.AddSingleton(sp => - { - var multiRabbitMqPersistentConnections = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + var iLifetimeScope = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubcriptionsManager = sp.GetRequiredService(); - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - List eventBuses = new List(); - - eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); - eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); - - - /*multiRabbitMqPersistentConnections.GetConnections().ForEach(conn => - { - eventBuses.Add(new EventBusRabbitMQ(conn, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount)); - });*/ - - return new MultiEventBusRabbitMQ(eventBuses); - }); - - /* services.AddSingleton(sp => + var retryCount = 5; + if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + retryCount = int.Parse(Configuration["EventBusRetryCount"]); + } - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } + List eventBuses = new List(); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); - 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); - });*/ - - //} + return new MultiEventBusRabbitMQ(eventBuses, tenants); + }); services.AddSingleton(); @@ -408,22 +307,23 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API eventBus.Subscribe(); eventBus.Subscribe(); - } + } } public static class CustomExtensionMethods { - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, + IConfiguration configuration) { var hcBuilder = services.AddHealthChecks(); hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); - hcBuilder + hcBuilder .AddRedis( configuration["ConnectionString"], name: "redis-check", - tags: new string[] { "redis" }); + tags: new string[] {"redis"}); if (configuration.GetValue("AzureServiceBusEnabled")) { @@ -432,7 +332,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API configuration["EventBusConnection"], topicName: "eshop_event_bus", name: "basket-servicebus-check", - tags: new string[] { "servicebus" }); + tags: new string[] {"servicebus"}); } else { @@ -440,10 +340,10 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API .AddRabbitMQ( $"amqp://{configuration["EventBusConnection"]}", name: "basket-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); + tags: new string[] {"rabbitmqbus"}); } return services; } } -} +} \ No newline at end of file diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs index bb3a23d40..ce4d12728 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs @@ -17,14 +17,14 @@ namespace Catalog.API.IntegrationEvents public class CatalogIntegrationEventService : ICatalogIntegrationEventService { private readonly Func _integrationEventLogServiceFactory; - private readonly IEventBus _eventBus; + private readonly IMultiEventBus _eventBus; private readonly CatalogContext _catalogContext; private readonly IIntegrationEventLogService _eventLogService; private readonly ILogger _logger; public CatalogIntegrationEventService( ILogger logger, - IEventBus eventBus, + IMultiEventBus eventBus, CatalogContext catalogContext, Func integrationEventLogServiceFactory) { diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index c9955b7ac..ca9a24457 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -26,6 +26,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using RabbitMQ.Client; using System; +using System.Collections.Generic; using System.Data.Common; using System.Reflection; using HealthChecks.UI.Client; @@ -101,7 +102,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API protected virtual void ConfigureEventBus(IApplicationBuilder app) { - var eventBus = app.ApplicationServices.GetRequiredService(); + var eventBus = app.ApplicationServices.GetRequiredService(); eventBus.Subscribe(); eventBus.Subscribe(); } @@ -275,21 +276,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API sp => (DbConnection c) => new IntegrationEventLogService(c)); services.AddTransient(); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var settings = sp.GetRequiredService>().Value; - var logger = sp.GetRequiredService>(); - - var serviceBusConnection = new ServiceBusConnectionStringBuilder(settings.EventBusConnection); - - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { + services.AddSingleton(sp => { var settings = sp.GetRequiredService>().Value; @@ -321,47 +308,79 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); }); - } + + services.AddSingleton(sp => + { + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp, configuration)); + connections.AddConnection(GenerateConnection("TenantB", sp, configuration)); + return connections; + }); return services; } - public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) + + private static IRabbitMQPersistentConnection GenerateConnection(String vHost, IServiceProvider sp, IConfiguration configuration) { - var subscriptionClientName = configuration["SubscriptionClientName"]; + var logger = sp.GetRequiredService>(); -/* if (configuration.GetValue("AzureServiceBusEnabled")) + var factory = new ConnectionFactory() { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + HostName = configuration["EventBusConnection"], + DispatchConsumersAsync = true + }; - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); + 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"]); } - else*/ + + return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); + } + + public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) + { + var subscriptionClientName = configuration["SubscriptionClientName"]; + + services.AddSingleton(sp => { - services.AddSingleton(sp => + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + var iLifetimeScope = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubcriptionsManager = sp.GetRequiredService(); + + var retryCount = 5; + if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + retryCount = int.Parse(configuration["EventBusRetryCount"]); + } - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } + List eventBuses = new List(); - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); - }); - } + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); + }); services.AddSingleton(); services.AddTransient(); diff --git a/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs b/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs index f6b9ed708..27eb53dc9 100644 --- a/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs +++ b/src/Services/Location/Locations.API/Infrastructure/Services/LocationsService.cs @@ -14,12 +14,12 @@ public class LocationsService : ILocationsService { private readonly ILocationsRepository _locationsRepository; - private readonly IEventBus _eventBus; + private readonly IMultiEventBus _eventBus; private readonly ILogger _logger; public LocationsService( ILocationsRepository locationsRepository, - IEventBus eventBus, + IMultiEventBus eventBus, ILogger logger) { _locationsRepository = locationsRepository ?? throw new ArgumentNullException(nameof(locationsRepository)); diff --git a/src/Services/Location/Locations.API/Startup.cs b/src/Services/Location/Locations.API/Startup.cs index 06f9d55af..742dd18ac 100644 --- a/src/Services/Location/Locations.API/Startup.cs +++ b/src/Services/Location/Locations.API/Startup.cs @@ -46,10 +46,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API services .AddCustomHealthCheck(Configuration) - .AddMvc(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }) + .AddMvc(options => { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddControllersAsServices(); @@ -57,51 +54,14 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API services.Configure(Configuration); - if (Configuration.GetValue("AzureServiceBusEnabled")) + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var serviceBusConnectionString = Configuration["EventBusConnection"]; - var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); - - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = Configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; - - if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) - { - factory.UserName = Configuration["EventBusUserName"]; - } + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp)); + connections.AddConnection(GenerateConnection("TenantB", sp)); - if (!string.IsNullOrEmpty(Configuration["EventBusPassword"])) - { - factory.Password = Configuration["EventBusPassword"]; - } - - factory.VirtualHost = "TenantA"; - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } + return connections; + }); RegisterEventBus(services); @@ -125,22 +85,21 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API TokenUrl = $"{Configuration.GetValue("IdentityUrlExternal")}/connect/token", Scopes = new Dictionary() { - { "locations", "Locations API" } + {"locations", "Locations API"} } }); options.OperationFilter(); - }); services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); + .SetIsOriginAllowed((host) => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials()); }); services.AddSingleton(); @@ -155,6 +114,38 @@ namespace Microsoft.eShopOnContainers.Services.Locations.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) { @@ -185,12 +176,14 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API app.UseMvcWithDefaultRoute(); app.UseSwagger() - .UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Locations.API V1"); - c.OAuthClientId("locationsswaggerui"); - c.OAuthAppName("Locations Swagger UI"); - }); + .UseSwaggerUI(c => + { + c.SwaggerEndpoint( + $"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", + "Locations.API V1"); + c.OAuthClientId("locationsswaggerui"); + c.OAuthAppName("Locations Swagger UI"); + }); LocationsContextSeed.SeedAsync(app, loggerFactory) .Wait(); @@ -206,6 +199,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API // Enable K8s telemetry initializer services.AddApplicationInsightsKubernetesEnricher(); } + if (orchestratorType?.ToUpper() == "SF") { // Enable SF telemetry initializer @@ -220,16 +214,16 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddJwtBearer(options => - { - options.Authority = Configuration.GetValue("IdentityUrl"); - options.Audience = "locations"; - options.RequireHttpsMetadata = false; - }); + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(options => + { + options.Authority = Configuration.GetValue("IdentityUrl"); + options.Audience = "locations"; + options.RequireHttpsMetadata = false; + }); } protected virtual void ConfigureAuth(IApplicationBuilder app) @@ -246,37 +240,31 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API { var subscriptionClientName = Configuration["SubscriptionClientName"]; -/* if (Configuration.GetValue("AzureServiceBusEnabled")) + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + var iLifetimeScope = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubcriptionsManager = sp.GetRequiredService(); - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - } - else*/ - { - services.AddSingleton(sp => + var retryCount = 5; + if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); + retryCount = int.Parse(Configuration["EventBusRetryCount"]); + } - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } + List eventBuses = new List(); - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); - }); - } + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); + }); services.AddSingleton(); } @@ -284,7 +272,8 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API public static class CustomExtensionMethods { - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, + IConfiguration configuration) { var hcBuilder = services.AddHealthChecks(); @@ -294,7 +283,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API .AddMongoDb( configuration["ConnectionString"], name: "locations-mongodb-check", - tags: new string[] { "mongodb" }); + tags: new string[] {"mongodb"}); if (configuration.GetValue("AzureServiceBusEnabled")) { @@ -303,7 +292,7 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API configuration["EventBusConnection"], topicName: "eshop_event_bus", name: "locations-servicebus-check", - tags: new string[] { "servicebus" }); + tags: new string[] {"servicebus"}); } else { @@ -311,10 +300,10 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API .AddRabbitMQ( $"amqp://{configuration["EventBusConnection"]}", name: "locations-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); + tags: new string[] {"rabbitmqbus"}); } return services; } } -} +} \ No newline at end of file diff --git a/src/Services/Marketing/Marketing.API/Startup.cs b/src/Services/Marketing/Marketing.API/Startup.cs index 4d190be1a..533f2adc2 100644 --- a/src/Services/Marketing/Marketing.API/Startup.cs +++ b/src/Services/Marketing/Marketing.API/Startup.cs @@ -80,52 +80,17 @@ options.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval }); - - if (Configuration.GetValue("AzureServiceBusEnabled")) + + + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp)); + connections.AddConnection(GenerateConnection("TenantB", sp)); - var serviceBusConnectionString = Configuration["EventBusConnection"]; - var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); - - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { - services.AddSingleton(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 = "TenantA"; - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } + return connections; + }); + // Add framework services. services.AddSwaggerGen(options => @@ -259,25 +224,10 @@ private void RegisterEventBus(IServiceCollection services) { var subscriptionClientName = Configuration["SubscriptionClientName"]; - -/* if (Configuration.GetValue("AzureServiceBusEnabled")) { - services.AddSingleton(sp => + services.AddSingleton(sp => { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - } - else*/ - { - services.AddSingleton(sp => - { - var rabbitMQPersistentConnection = sp.GetRequiredService(); + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); var iLifetimeScope = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); var eventBusSubcriptionsManager = sp.GetRequiredService(); @@ -288,17 +238,58 @@ retryCount = int.Parse(Configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); + List eventBuses = new List(); + + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); }); } services.AddSingleton(); services.AddTransient(); } + + 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); + } private void ConfigureEventBus(IApplicationBuilder app) { - var eventBus = app.ApplicationServices.GetRequiredService(); + var eventBus = app.ApplicationServices.GetRequiredService(); eventBus.Subscribe(); } diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs index 6b8ed53e4..f67661450 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/UserCheckoutAcceptedIntegrationEventHandler.cs @@ -15,12 +15,12 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling public class UserCheckoutAcceptedIntegrationEventHandler : IIntegrationEventHandler { private readonly IMediator _mediator; - private readonly IEventBus _eventBus; + private readonly IMultiEventBus _eventBus; private readonly ILogger _logger; public UserCheckoutAcceptedIntegrationEventHandler( IMediator mediator, - ILogger logger, IEventBus eventBus) + ILogger logger, IMultiEventBus eventBus) { _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs index cb7ce5513..08fa966b3 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs @@ -19,13 +19,13 @@ namespace Ordering.API.Application.IntegrationEvents public class OrderingIntegrationEventService : IOrderingIntegrationEventService { private readonly Func _integrationEventLogServiceFactory; - private readonly IEventBus _eventBus; + private readonly IMultiEventBus _eventBus; private readonly OrderingContext _orderingContext; private readonly IntegrationEventLogContext _eventLogContext; private readonly IIntegrationEventLogService _eventLogService; private readonly ILogger _logger; - public OrderingIntegrationEventService(IEventBus eventBus, + public OrderingIntegrationEventService(IMultiEventBus eventBus, OrderingContext orderingContext, IntegrationEventLogContext eventLogContext, Func integrationEventLogServiceFactory, diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs index 9c4e25aea..d4fe19ea3 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -115,7 +115,7 @@ private void ConfigureEventBus(IApplicationBuilder app) { - var eventBus = app.ApplicationServices.GetRequiredService(); + var eventBus = app.ApplicationServices.GetRequiredService(); eventBus.Subscribe>(); eventBus.Subscribe>(); @@ -284,55 +284,47 @@ services.AddTransient(); - if (configuration.GetValue("AzureServiceBusEnabled")) + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var serviceBusConnectionString = configuration["EventBusConnection"]; - var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); - - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp, configuration)); + connections.AddConnection(GenerateConnection("TenantB", sp, configuration)); + return connections; + }); - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; + return services; + } + + private static IRabbitMQPersistentConnection GenerateConnection(String vHost, IServiceProvider sp, IConfiguration configuration) + { + var logger = sp.GetRequiredService>(); - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } + var factory = new ConnectionFactory() + { + HostName = configuration["EventBusConnection"], + DispatchConsumersAsync = true + }; - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - factory.VirtualHost = "TenantA"; + if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) + { + factory.UserName = configuration["EventBusUserName"]; + } + if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) + { + factory.Password = configuration["EventBusPassword"]; + } - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } + factory.VirtualHost = vHost; - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); + var retryCount = 5; + if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + { + retryCount = int.Parse(configuration["EventBusRetryCount"]); } - return services; + return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); } public static IServiceCollection AddCustomConfiguration(this IServiceCollection services, IConfiguration configuration) @@ -363,25 +355,12 @@ public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) { var subscriptionClientName = configuration["SubscriptionClientName"]; - -/* if (configuration.GetValue("AzureServiceBusEnabled")) + { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - } - else*/ - { - services.AddSingleton(sp => + services.AddSingleton(sp => { - var rabbitMQPersistentConnection = sp.GetRequiredService(); + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); var iLifetimeScope = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); var eventBusSubcriptionsManager = sp.GetRequiredService(); @@ -392,7 +371,17 @@ retryCount = int.Parse(configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); + List eventBuses = new List(); + + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); }); } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs index 408cf42cd..7d39ead70 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs @@ -15,6 +15,7 @@ using Ordering.BackgroundTasks.Configuration; using Ordering.BackgroundTasks.Tasks; using RabbitMQ.Client; using System; +using System.Collections.Generic; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -46,53 +47,16 @@ namespace Ordering.BackgroundTasks services.AddSingleton(); //configure event bus related services - - if (Configuration.GetValue("AzureServiceBusEnabled")) + + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var serviceBusConnectionString = Configuration["EventBusConnection"]; - var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp)); + connections.AddConnection(GenerateConnection("TenantB", sp)); - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { - services.AddSingleton(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 = "TenantA"; - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } + return connections; + }); + RegisterEventBus(services); @@ -104,6 +68,37 @@ namespace Ordering.BackgroundTasks 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) @@ -124,38 +119,33 @@ namespace Ordering.BackgroundTasks private void RegisterEventBus(IServiceCollection services) { var subscriptionClientName = Configuration["SubscriptionClientName"]; - -/* if (Configuration.GetValue("AzureServiceBusEnabled")) + + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - } - else*/ - { - services.AddSingleton(sp => + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + var iLifetimeScope = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubcriptionsManager = sp.GetRequiredService(); + + var retryCount = 5; + if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); - }); - } + retryCount = int.Parse(Configuration["EventBusRetryCount"]); + } + + List eventBuses = new List(); + + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); + }); + services.AddSingleton(); } diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Tasks/GracePeriodManagerTask.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Tasks/GracePeriodManagerTask.cs index b667615fb..6f8282350 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Tasks/GracePeriodManagerTask.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Tasks/GracePeriodManagerTask.cs @@ -21,12 +21,12 @@ namespace Ordering.BackgroundTasks.Tasks { private readonly ILogger _logger; private readonly BackgroundTaskSettings _settings; - private readonly IEventBus _eventBus; + private readonly IMultiEventBus _eventBus; private static readonly String identityUrl = @"http://identity.api/"; public GracePeriodManagerService( IOptions settings, - IEventBus eventBus, + IMultiEventBus eventBus, ILogger logger) { _settings = settings?.Value ?? throw new ArgumentNullException(nameof(settings)); diff --git a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs index 4929ffed0..f335f3986 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs @@ -16,6 +16,7 @@ using Ordering.SignalrHub.IntegrationEvents.EventHandling; using Ordering.SignalrHub.IntegrationEvents.Events; using RabbitMQ.Client; using System; +using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Diagnostics.HealthChecks; @@ -42,10 +43,10 @@ namespace Ordering.SignalrHub { options.AddPolicy("CorsPolicy", builder => builder - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed((host) => true) - .AllowCredentials()); + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed((host) => true) + .AllowCredentials()); }); if (Configuration.GetValue("IsClusterEnv") == bool.TrueString) @@ -59,52 +60,14 @@ namespace Ordering.SignalrHub services.AddSignalR(); } - if (Configuration.GetValue("AzureServiceBusEnabled")) + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var serviceBusConnectionString = Configuration["EventBusConnection"]; - var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp)); + connections.AddConnection(GenerateConnection("TenantB", sp)); - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { - services.AddSingleton(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 = "TenantA"; - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } + return connections; + }); ConfigureAuthService(services); @@ -120,6 +83,38 @@ namespace Ordering.SignalrHub 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, ILoggerFactory loggerFactory) { @@ -161,14 +156,25 @@ namespace Ordering.SignalrHub private void ConfigureEventBus(IApplicationBuilder app) { - var eventBus = app.ApplicationServices.GetRequiredService(); - - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); - eventBus.Subscribe(); + var eventBus = app.ApplicationServices.GetRequiredService(); + + eventBus + .Subscribe(); + eventBus + .Subscribe(); + eventBus + .Subscribe(); + eventBus + .Subscribe(); + eventBus + .Subscribe(); + eventBus + .Subscribe(); } private void ConfigureAuthService(IServiceCollection services) @@ -182,7 +188,6 @@ namespace Ordering.SignalrHub { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }).AddJwtBearer(options => { options.Authority = identityUrl; @@ -195,37 +200,33 @@ namespace Ordering.SignalrHub { var subscriptionClientName = Configuration["SubscriptionClientName"]; -/* if (Configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - } - else*/ + services.AddSingleton(sp => { - services.AddSingleton(sp => + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + var iLifetimeScope = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubcriptionsManager = sp.GetRequiredService(); + + var retryCount = 5; + if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); - }); - } + retryCount = int.Parse(Configuration["EventBusRetryCount"]); + } + + List eventBuses = new List(); + + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); + }); + services.AddSingleton(); } @@ -233,7 +234,8 @@ namespace Ordering.SignalrHub public static class CustomExtensionMethods { - public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, + IConfiguration configuration) { var hcBuilder = services.AddHealthChecks(); @@ -246,7 +248,7 @@ namespace Ordering.SignalrHub configuration["EventBusConnection"], topicName: "eshop_event_bus", name: "signalr-servicebus-check", - tags: new string[] { "servicebus" }); + tags: new string[] {"servicebus"}); } else { @@ -254,10 +256,10 @@ namespace Ordering.SignalrHub .AddRabbitMQ( $"amqp://{configuration["EventBusConnection"]}", name: "signalr-rabbitmqbus-check", - tags: new string[] { "rabbitmqbus" }); + tags: new string[] {"rabbitmqbus"}); } return services; } } -} +} \ No newline at end of file diff --git a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index c2f31b4cf..e8e81e082 100644 --- a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -11,12 +11,12 @@ public class OrderStatusChangedToStockConfirmedIntegrationEventHandler : IIntegrationEventHandler { - private readonly IEventBus _eventBus; + private readonly IMultiEventBus _eventBus; private readonly PaymentSettings _settings; private readonly ILogger _logger; public OrderStatusChangedToStockConfirmedIntegrationEventHandler( - IEventBus eventBus, + IMultiEventBus eventBus, IOptionsSnapshot settings, ILogger logger) { diff --git a/src/Services/Payment/Payment.API/Startup.cs b/src/Services/Payment/Payment.API/Startup.cs index 5692f6826..cdc7ebb63 100644 --- a/src/Services/Payment/Payment.API/Startup.cs +++ b/src/Services/Payment/Payment.API/Startup.cs @@ -16,6 +16,7 @@ using Payment.API.IntegrationEvents.EventHandling; using Payment.API.IntegrationEvents.Events; using RabbitMQ.Client; using System; +using System.Collections.Generic; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -38,52 +39,16 @@ namespace Payment.API services.Configure(Configuration); RegisterAppInsights(services); - - if (Configuration.GetValue("AzureServiceBusEnabled")) + + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - - var serviceBusConnectionString = Configuration["EventBusConnection"]; - var serviceBusConnection = new ServiceBusConnectionStringBuilder(serviceBusConnectionString); - - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { - services.AddSingleton(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 = "TenantA"; - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp)); + connections.AddConnection(GenerateConnection("TenantB", sp)); + return connections; + }); + RegisterEventBus(services); var container = new ContainerBuilder(); @@ -91,6 +56,37 @@ namespace Payment.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) { @@ -140,37 +136,33 @@ namespace Payment.API { var subscriptionClientName = Configuration["SubscriptionClientName"]; -/* if (Configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - } - else*/ + + services.AddSingleton(sp => { - services.AddSingleton(sp => + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); + var iLifetimeScope = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + var eventBusSubcriptionsManager = sp.GetRequiredService(); + + var retryCount = 5; + if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(Configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); - }); - } + retryCount = int.Parse(Configuration["EventBusRetryCount"]); + } + + List eventBuses = new List(); + + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); + }); + services.AddTransient(); services.AddSingleton(); @@ -178,7 +170,7 @@ namespace Payment.API private void ConfigureEventBus(IApplicationBuilder app) { - var eventBus = app.ApplicationServices.GetRequiredService(); + var eventBus = app.ApplicationServices.GetRequiredService(); eventBus.Subscribe(); } } diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs index e54163bc6..8186f1cde 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -126,7 +126,7 @@ namespace Webhooks.API protected virtual void ConfigureEventBus(IApplicationBuilder app) { - var eventBus = app.ApplicationServices.GetRequiredService(); + var eventBus = app.ApplicationServices.GetRequiredService(); eventBus.Subscribe(); eventBus.Subscribe(); eventBus.Subscribe(); @@ -231,26 +231,10 @@ namespace Webhooks.API public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) { var subscriptionClientName = configuration["SubscriptionClientName"]; - -/* if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); - - } - else*/ - { - services.AddSingleton(sp => + + services.AddSingleton(sp => { - var rabbitMQPersistentConnection = sp.GetRequiredService(); + var multiRabbitMqPersistentConnections = sp.GetRequiredService(); var iLifetimeScope = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); var eventBusSubcriptionsManager = sp.GetRequiredService(); @@ -261,9 +245,19 @@ namespace Webhooks.API retryCount = int.Parse(configuration["EventBusRetryCount"]); } - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount); + List eventBuses = new List(); + + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[0], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantA", subscriptionClientName, retryCount)); + eventBuses.Add(new EventBusRabbitMQ(multiRabbitMqPersistentConnections.GetConnections()[1], logger, + iLifetimeScope, eventBusSubcriptionsManager, "TenantB", subscriptionClientName, retryCount)); + Dictionary tenants = new Dictionary(); + tenants.Add(1, "TenantA"); + tenants.Add(2, "TenantB"); + + return new MultiEventBusRabbitMQ(eventBuses, tenants); }); - } + services.AddSingleton(); services.AddTransient(); @@ -304,53 +298,52 @@ namespace Webhooks.API { services.AddTransient>( sp => (DbConnection c) => new IntegrationEventLogService(c)); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); - var serviceBusConnection = new ServiceBusConnectionStringBuilder(configuration["EventBusConnection"]); - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else + + + services.AddSingleton(sp => { - services.AddSingleton(sp => - { - var logger = sp.GetRequiredService>(); + IMultiRabbitMQPersistentConnections connections = new MultiRabbitMQPersistentConnections(); + connections.AddConnection(GenerateConnection("TenantA", sp, configuration)); + connections.AddConnection(GenerateConnection("TenantB", sp, configuration)); - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"], - DispatchConsumersAsync = true - }; + return connections; + }); + - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } + return services; + } - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - factory.VirtualHost = "TenantA"; + private static IRabbitMQPersistentConnection GenerateConnection(String vHost, IServiceProvider sp, IConfiguration configuration) + { + var logger = sp.GetRequiredService>(); - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } + var factory = new ConnectionFactory() + { + HostName = configuration["EventBusConnection"], + DispatchConsumersAsync = true + }; - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); + if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) + { + factory.UserName = configuration["EventBusUserName"]; } - return services; - } + 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); + } + public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) { // prevent from mapping "sub" claim to nameidentifier. From 24949c2bafaa332a4c30ea2faf63954f5e5abe6f Mon Sep 17 00:00:00 2001 From: espent1004 Date: Wed, 5 Feb 2020 22:17:46 +0100 Subject: [PATCH 5/6] Changing implementation to not get the actualEventBus if it is system-wide event. --- .../EventBusRabbitMQ/MultiEventBusRabbitMQ.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs index f386f9b41..f2c9fd0c5 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/MultiEventBusRabbitMQ.cs @@ -30,12 +30,15 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ eventBus.Publish(@event); }); } - - //TODO requires ALL events to have tenantId set! - _tenants.TryGetValue(@event.TenantId, out String tenantName); - var actualEventBus = _eventBuses.Find(e => e.GetVHost().Equals(tenantName)); + else + { + //TODO requires ALL events to have tenantId set! + _tenants.TryGetValue(@event.TenantId, out String tenantName); + var actualEventBus = _eventBuses.Find(e => e.GetVHost().Equals(tenantName)); + + actualEventBus.Publish(@event); + } - actualEventBus.Publish(@event); } public void Subscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler From f5f871fc94b0a0dfc262c00044e8077625e864c4 Mon Sep 17 00:00:00 2001 From: espent1004 Date: Sat, 8 Feb 2020 22:24:24 +0100 Subject: [PATCH 6/6] TenantId added to all events in main flow --- ...usChangedToAwaitingValidationIntegrationEventHandler.cs | 2 ++ .../Commands/SetStockConfirmedOrderStatusCommand.cs | 5 ++++- .../Commands/SetStockConfirmedOrderStatusCommandHandler.cs | 2 +- ...OrderStatusChangedToStockConfirmedDomainEventHandler.cs | 2 ++ .../OrderStockConfirmedIntegrationEventHandler.cs | 2 +- .../AggregatesModel/OrderAggregate/Order.cs | 4 ++-- .../OrderStatusChangedToStockConfirmedDomainEvent.cs | 7 +++++++ ...StatusChangedToStockConfirmedIntegrationEventHandler.cs | 5 ++++- 8 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 493a271cc..b402f48b6 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -49,6 +49,8 @@ ? (IntegrationEvent)new OrderStockRejectedIntegrationEvent(@event.OrderId, confirmedOrderStockItems) : new OrderStockConfirmedIntegrationEvent(@event.OrderId); + confirmedIntegrationEvent.TenantId = @event.TenantId; + await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent); await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent); diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommand.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommand.cs index 74f002e21..8668214e4 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommand.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommand.cs @@ -12,10 +12,13 @@ namespace Ordering.API.Application.Commands [DataMember] public int OrderNumber { get; private set; } + [DataMember] + public int TenantId { get; private set; } - public SetStockConfirmedOrderStatusCommand(int orderNumber) + public SetStockConfirmedOrderStatusCommand(int orderNumber, int tenantId) { OrderNumber = orderNumber; + TenantId = tenantId; } } } \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs index b76c16ec6..f82b37aca 100644 --- a/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs @@ -35,7 +35,7 @@ namespace Ordering.API.Application.Commands return false; } - orderToUpdate.SetStockConfirmedStatus(); + orderToUpdate.SetStockConfirmedStatus(command.TenantId); return await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); } } diff --git a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs index 0e9ca4f08..6c4bb4dad 100644 --- a/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs @@ -41,6 +41,8 @@ var buyer = await _buyerRepository.FindByIdAsync(order.GetBuyerId.Value.ToString()); var orderStatusChangedToStockConfirmedIntegrationEvent = new OrderStatusChangedToStockConfirmedIntegrationEvent(order.Id, order.OrderStatus.Name, buyer.Name); + orderStatusChangedToStockConfirmedIntegrationEvent.TenantId = + orderStatusChangedToStockConfirmedDomainEvent.TenantId; await _orderingIntegrationEventService.AddAndSaveEventAsync(orderStatusChangedToStockConfirmedIntegrationEvent); } } diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs index 6438b01d0..c1b79ed54 100644 --- a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs @@ -33,7 +33,7 @@ { _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); - var command = new SetStockConfirmedOrderStatusCommand(@event.OrderId); + var command = new SetStockConfirmedOrderStatusCommand(@event.OrderId, @event.TenantId); _logger.LogInformation( "----- Sending command: {CommandName} - {IdProperty}: {CommandId} ({@Command})", diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs index 59c981935..e2ac9f134 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs @@ -114,11 +114,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O } } - public void SetStockConfirmedStatus() + public void SetStockConfirmedStatus(int tenantId) { if (_orderStatusId == OrderStatus.AwaitingValidation.Id) { - AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id)); + AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id).withTenantId(tenantId)); _orderStatusId = OrderStatus.StockConfirmed.Id; _description = "All the items were confirmed with available stock."; diff --git a/src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToStockConfirmedDomainEvent.cs b/src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToStockConfirmedDomainEvent.cs index b16bebbcc..c68a69855 100644 --- a/src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToStockConfirmedDomainEvent.cs +++ b/src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToStockConfirmedDomainEvent.cs @@ -9,8 +9,15 @@ : INotification { public int OrderId { get; } + public int TenantId { get; set; } public OrderStatusChangedToStockConfirmedDomainEvent(int orderId) => OrderId = orderId; + + public OrderStatusChangedToStockConfirmedDomainEvent withTenantId(int tenantId) + { + this.TenantId = tenantId; + return this; + } } } \ No newline at end of file diff --git a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs index e8e81e082..31d126cd0 100644 --- a/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs +++ b/src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs @@ -1,4 +1,6 @@ -namespace Payment.API.IntegrationEvents.EventHandling +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Extensions; + +namespace Payment.API.IntegrationEvents.EventHandling { using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; @@ -50,6 +52,7 @@ orderPaymentIntegrationEvent = new OrderPaymentFailedIntegrationEvent(@event.OrderId); } + orderPaymentIntegrationEvent.TenantId = @event.TenantId; _logger.LogInformation("----- Publishing integration event: {IntegrationEventId} from {AppName} - ({@IntegrationEvent})", orderPaymentIntegrationEvent.Id, Program.AppName, orderPaymentIntegrationEvent); _eventBus.Publish(orderPaymentIntegrationEvent);