From 0aa2ae1eb52c4661d63b6958444dfca6b5146895 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Tue, 8 Oct 2024 15:10:27 -0700 Subject: [PATCH] CU-868a3neq0 trying to fix eventing issue. --- .../Providers/IRabbitInboundEventProvider.cs | 2 +- .../RabbitConnection.cs | 24 +- .../RabbitInboundEventProvider.cs | 138 +++++------ .../RabbitInboundQueueProvider.cs | 8 +- .../RabbitOutboundQueueProvider.cs | 22 +- .../RabbitTopicProvider.cs | 32 +-- .../OutboundEventProvider.cs | 110 ++++++++- Web/Resgrid.Web.Eventing/Hubs/EventingHub.cs | 16 +- Web/Resgrid.Web.Eventing/Program.cs | 58 ++++- .../Services/EventingHubService.cs | 228 +++++++++--------- Web/Resgrid.Web.Eventing/Startup.cs | 4 +- Web/Resgrid.Web.Eventing/Worker.cs | 59 ++++- .../appsettings.Development.json | 3 + Web/Resgrid.Web.Eventing/appsettings.json | 3 + .../Controllers/v4/CalendarController.cs | 2 +- .../Controllers/v4/CallsController.cs | 7 +- .../User/Controllers/DispatchController.cs | 20 +- .../common/signalr/resgrid.common.signalr.js | 22 +- .../Tasks/AuditQueuesProcessorTask.cs | 2 +- .../Tasks/PaymentQueueProcessorTask.cs | 2 +- .../PersonnelLocationQueuesProcessorTask.cs | 2 +- .../Tasks/QueuesProcessorTask.cs | 2 +- .../Tasks/SystemQueueProcessorTask.cs | 2 +- .../Tasks/UnitLocationQueuesProcessorTask.cs | 2 +- 24 files changed, 480 insertions(+), 290 deletions(-) diff --git a/Core/Resgrid.Model/Providers/IRabbitInboundEventProvider.cs b/Core/Resgrid.Model/Providers/IRabbitInboundEventProvider.cs index 67658056..b9c3b76d 100644 --- a/Core/Resgrid.Model/Providers/IRabbitInboundEventProvider.cs +++ b/Core/Resgrid.Model/Providers/IRabbitInboundEventProvider.cs @@ -6,7 +6,7 @@ namespace Resgrid.Model.Providers { public interface IRabbitInboundEventProvider { - Task Start(); + Task Start(string clientName, string queueName); void RegisterForEvents(Func personnelStatusChanged, Func unitStatusChanged, Func callStatusChanged, diff --git a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitConnection.cs b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitConnection.cs index fd129329..1e8d7f71 100644 --- a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitConnection.cs +++ b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitConnection.cs @@ -9,19 +9,18 @@ internal class RabbitConnection { private static IConnection _connection { get; set; } private static ConnectionFactory _factory { get; set; } - private static object LOCK = new object(); + private readonly static object LOCK = new object(); - public static bool VerifyAndCreateClients() + public static bool VerifyAndCreateClients(string clientName) { if (_connection != null && !_connection.IsOpen) { - _connection?.Dispose(); - + _connection.Dispose(); _connection = null; _factory = null; } - + if (_connection == null) { lock (LOCK) @@ -29,7 +28,7 @@ public static bool VerifyAndCreateClients() try { _factory = new ConnectionFactory() { HostName = ServiceBusConfig.RabbitHostname, UserName = ServiceBusConfig.RabbitUsername, Password = ServiceBusConfig.RabbbitPassword }; - _connection = _factory.CreateConnection(); + _connection = _factory.CreateConnection(clientName); } catch (Exception ex) { @@ -40,7 +39,7 @@ public static bool VerifyAndCreateClients() try { _factory = new ConnectionFactory() { HostName = ServiceBusConfig.RabbitHostname2, UserName = ServiceBusConfig.RabbitUsername, Password = ServiceBusConfig.RabbbitPassword }; - _connection = _factory.CreateConnection(); + _connection = _factory.CreateConnection(clientName); } catch (Exception ex2) { @@ -51,7 +50,7 @@ public static bool VerifyAndCreateClients() try { _factory = new ConnectionFactory() { HostName = ServiceBusConfig.RabbitHostname3, UserName = ServiceBusConfig.RabbitUsername, Password = ServiceBusConfig.RabbbitPassword }; - _connection = _factory.CreateConnection(); + _connection = _factory.CreateConnection(clientName); } catch (Exception ex3) { @@ -155,19 +154,18 @@ public static bool VerifyAndCreateClients() return false; } - public static IConnection CreateConnection() + public static IConnection CreateConnection(string clientName) { if (_connection == null) - VerifyAndCreateClients(); + VerifyAndCreateClients(clientName); if (!_connection.IsOpen) { - _connection?.Dispose(); - + _connection.Dispose(); _connection = null; _factory = null; - VerifyAndCreateClients(); + VerifyAndCreateClients(clientName); } return _connection; diff --git a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundEventProvider.cs b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundEventProvider.cs index e08813fd..d099bf8c 100644 --- a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundEventProvider.cs +++ b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundEventProvider.cs @@ -1,6 +1,7 @@ using System; using System.Text; using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; using Newtonsoft.Json; using RabbitMQ.Client; @@ -15,7 +16,6 @@ namespace Resgrid.Providers.Bus.Rabbit { public class RabbitInboundEventProvider : IRabbitInboundEventProvider { - //private ConnectionFactory _factory; private IConnection _connection; private IModel _channel; @@ -28,17 +28,17 @@ public class RabbitInboundEventProvider : IRabbitInboundEventProvider public Func PersonnelLocationUpdated; public Func UnitLocationUpdated; - public async Task Start() + public async Task Start(string clientName, string queueName) { - VerifyAndCreateClients(); - await StartMonitoring(); + VerifyAndCreateClients(clientName); + await StartMonitoring(queueName); } - private void VerifyAndCreateClients() + private void VerifyAndCreateClients(string clientName) { try { - _connection = RabbitConnection.CreateConnection(); + _connection = RabbitConnection.CreateConnection(clientName); if (_connection != null) { @@ -46,7 +46,7 @@ private void VerifyAndCreateClients() if (_channel != null) { - _channel.ExchangeDeclare(SetQueueNameForEnv(Topics.EventingTopic), "fanout"); + _channel.ExchangeDeclare(RabbitConnection.SetQueueNameForEnv(Topics.EventingTopic), "fanout"); } } } @@ -56,69 +56,69 @@ private void VerifyAndCreateClients() } } - private async Task StartMonitoring() + private async Task StartMonitoring(string queueName) { - if (SystemBehaviorConfig.ServiceBusType == ServiceBusTypes.Rabbit) - { - var queueName = _channel.QueueDeclare().QueueName; + //var queueName = _channel.QueueDeclare().QueueName; - _channel.QueueBind(queue: queueName, - exchange: SetQueueNameForEnv(Topics.EventingTopic), - routingKey: ""); + var queue = _channel.QueueDeclare(RabbitConnection.SetQueueNameForEnv(queueName), durable: true, + autoDelete: false, exclusive: false); - var consumer = new EventingBasicConsumer(_channel); - consumer.Received += async (model, ea) => - { - var body = ea.Body.ToArray(); - var message = Encoding.UTF8.GetString(body); + _channel.QueueBind(queue: queue.QueueName, + exchange: RabbitConnection.SetQueueNameForEnv(Topics.EventingTopic), + routingKey: ""); + + var consumer = new EventingBasicConsumer(_channel); + consumer.Received += async (model, ea) => + { + var body = ea.Body.ToArray(); + var message = Encoding.UTF8.GetString(body); - var eventingMessage = JsonConvert.DeserializeObject(message); + var eventingMessage = JsonConvert.DeserializeObject(message); - if (eventingMessage != null) + if (eventingMessage != null) + { + switch ((EventingTypes)eventingMessage.Type) { - switch ((EventingTypes)eventingMessage.Type) - { - case EventingTypes.PersonnelStatusUpdated: - if (ProcessPersonnelStatusChanged != null) - await ProcessPersonnelStatusChanged(eventingMessage.DepartmentId, eventingMessage.ItemId); - break; - case EventingTypes.UnitStatusUpdated: - if (ProcessUnitStatusChanged != null) - await ProcessUnitStatusChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); - break; - case EventingTypes.CallsUpdated: - if (ProcessCallStatusChanged != null) - await ProcessCallStatusChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); - break; - case EventingTypes.CallAdded: - if (ProcessCallStatusChanged != null) - await ProcessCallStatusChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); - break; - case EventingTypes.CallClosed: - if (ProcessCallStatusChanged != null) - await ProcessCallStatusChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); - break; - case EventingTypes.PersonnelStaffingUpdated: - if (ProcessPersonnelStaffingChanged != null) - await ProcessPersonnelStaffingChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); - break; - case EventingTypes.PersonnelLocationUpdated: - if (PersonnelLocationUpdated != null) - await PersonnelLocationUpdated.Invoke(eventingMessage.DepartmentId, JsonConvert.DeserializeObject(eventingMessage.Payload)); - break; - case EventingTypes.UnitLocationUpdated: - if (UnitLocationUpdated != null) - await UnitLocationUpdated.Invoke(eventingMessage.DepartmentId, JsonConvert.DeserializeObject(eventingMessage.Payload)); - break; - default: - throw new ArgumentOutOfRangeException(); - } + case EventingTypes.PersonnelStatusUpdated: + if (ProcessPersonnelStatusChanged != null) + await ProcessPersonnelStatusChanged(eventingMessage.DepartmentId, eventingMessage.ItemId); + break; + case EventingTypes.UnitStatusUpdated: + if (ProcessUnitStatusChanged != null) + await ProcessUnitStatusChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); + break; + case EventingTypes.CallsUpdated: + if (ProcessCallStatusChanged != null) + await ProcessCallStatusChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); + break; + case EventingTypes.CallAdded: + if (ProcessCallAdded != null) + await ProcessCallAdded.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); + break; + case EventingTypes.CallClosed: + if (ProcessCallClosed != null) + await ProcessCallClosed.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); + break; + case EventingTypes.PersonnelStaffingUpdated: + if (ProcessPersonnelStaffingChanged != null) + await ProcessPersonnelStaffingChanged.Invoke(eventingMessage.DepartmentId, eventingMessage.ItemId); + break; + case EventingTypes.PersonnelLocationUpdated: + if (PersonnelLocationUpdated != null) + await PersonnelLocationUpdated.Invoke(eventingMessage.DepartmentId, JsonConvert.DeserializeObject(eventingMessage.Payload)); + break; + case EventingTypes.UnitLocationUpdated: + if (UnitLocationUpdated != null) + await UnitLocationUpdated.Invoke(eventingMessage.DepartmentId, JsonConvert.DeserializeObject(eventingMessage.Payload)); + break; + default: + throw new ArgumentOutOfRangeException(); } - }; - _channel.BasicConsume(queue: queueName, - autoAck: true, - consumer: consumer); - } + } + }; + _channel.BasicConsume(queue: queue.QueueName, + autoAck: true, + consumer: consumer); } public bool IsConnected() @@ -147,17 +147,5 @@ public void RegisterForEvents(Func personnelStatusChanged, PersonnelLocationUpdated = personnelLocationUpdated; UnitLocationUpdated = unitLocationUpdated; } - - private static string SetQueueNameForEnv(string cacheKey) - { - if (Config.SystemBehaviorConfig.Environment == SystemEnvironment.Dev) - return $"DEV{cacheKey}"; - else if (Config.SystemBehaviorConfig.Environment == SystemEnvironment.QA) - return $"QA{cacheKey}"; - else if (Config.SystemBehaviorConfig.Environment == SystemEnvironment.Staging) - return $"ST{cacheKey}"; - - return cacheKey; - } } } diff --git a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundQueueProvider.cs b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundQueueProvider.cs index ce004750..719a3635 100644 --- a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundQueueProvider.cs +++ b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitInboundQueueProvider.cs @@ -14,6 +14,7 @@ namespace Resgrid.Providers.Bus.Rabbit { public class RabbitInboundQueueProvider { + private string _clientName; private IModel _channel; public Func CallQueueReceived; public Func MessageQueueReceived; @@ -32,9 +33,10 @@ public RabbitInboundQueueProvider() RabbitOutboundQueueProvider provider = new RabbitOutboundQueueProvider(); } - public async Task Start() + public async Task Start(string clientName) { - var connection = RabbitConnection.CreateConnection(); + _clientName = clientName; + var connection = RabbitConnection.CreateConnection(clientName); if (connection != null) { @@ -584,7 +586,7 @@ private bool RetryQueueItem(BasicDeliverEventArgs ea, Exception mex) //var factory = new ConnectionFactory() { HostName = ServiceBusConfig.RabbitHostname, UserName = ServiceBusConfig.RabbitUsername, Password = ServiceBusConfig.RabbbitPassword }; //using (var connection = RabbitConnection.CreateConnection()) //{ - var connection = RabbitConnection.CreateConnection(); + var connection = RabbitConnection.CreateConnection(_clientName); if (connection != null) { using (var channel = connection.CreateModel()) diff --git a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitOutboundQueueProvider.cs b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitOutboundQueueProvider.cs index fdee23ec..76183dc5 100644 --- a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitOutboundQueueProvider.cs +++ b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitOutboundQueueProvider.cs @@ -13,6 +13,8 @@ namespace Resgrid.Providers.Bus.Rabbit { public class RabbitOutboundQueueProvider : IRabbitOutboundQueueProvider { + private readonly string _clientName = "Resgrid-Outbound"; + public bool EnqueueCall(CallQueueItem callQueue) { string serializedObject = ObjectSerialization.Serialize(callQueue); @@ -97,11 +99,6 @@ public bool EnqueueSecurityRefreshEvent(SecurityRefreshEvent securityRefreshEven return SendMessage(ServiceBusConfig.SecurityRefreshQueueName, serializedObject, false, "300000"); } - public bool VerifyAndCreateClients() - { - return RabbitConnection.VerifyAndCreateClients(); - } - private bool SendMessage(string queueName, string message, bool durable = true, string expiration = "36000000") { if (String.IsNullOrWhiteSpace(queueName)) @@ -110,15 +107,9 @@ private bool SendMessage(string queueName, string message, bool durable = true, if (String.IsNullOrWhiteSpace(message)) throw new ArgumentNullException("message"); - //if (SystemBehaviorConfig.ServiceBusType == ServiceBusTypes.Rabbit) - //{ try { - // TODO: Maybe? https://github.com/EasyNetQ/EasyNetQ -SJ - //var factory = new ConnectionFactory() { HostName = ServiceBusConfig.RabbitHostname, UserName = ServiceBusConfig.RabbitUsername, Password = ServiceBusConfig.RabbbitPassword }; - //using (var connection = RabbitConnection.CreateConnection()) - //{ - var connection = RabbitConnection.CreateConnection(); + var connection = RabbitConnection.CreateConnection(_clientName); if (connection != null) { using (var channel = connection.CreateModel()) @@ -157,16 +148,17 @@ private bool SendMessage(string queueName, string message, bool durable = true, } return false; - //} } catch (Exception ex) { Logging.LogException(ex); return false; } - //} + } - //return false; + bool IRabbitOutboundQueueProvider.VerifyAndCreateClients() + { + return RabbitConnection.VerifyAndCreateClients(_clientName); } } } diff --git a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitTopicProvider.cs b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitTopicProvider.cs index 40ef89ce..ea27f96c 100644 --- a/Providers/Resgrid.Providers.Bus.Rabbit/RabbitTopicProvider.cs +++ b/Providers/Resgrid.Providers.Bus.Rabbit/RabbitTopicProvider.cs @@ -12,10 +12,7 @@ namespace Resgrid.Providers.Bus.Rabbit { public class RabbitTopicProvider { - public RabbitTopicProvider() - { - VerifyAndCreateClients(); - } + private readonly string _clientName = "Resgrid-Topic"; public bool PersonnelStatusChanged(UserStatusEvent message) { @@ -115,19 +112,17 @@ public bool UnitLocationUpdatedChanged(UnitLocationUpdatedEvent message) }.SerializeJson()); } - private static void VerifyAndCreateClients() + private static void VerifyAndCreateClients(string clientName) { try { - //var factory = new ConnectionFactory() { HostName = ServiceBusConfig.RabbitHostname, UserName = ServiceBusConfig.RabbitUsername, Password = ServiceBusConfig.RabbbitPassword }; - //using (var connection = factory.CreateConnection()) - var connection = RabbitConnection.CreateConnection(); + var connection = RabbitConnection.CreateConnection(clientName); if (connection != null) { using (var channel = connection.CreateModel()) { - channel.ExchangeDeclare(SetQueueNameForEnv(Topics.EventingTopic), "fanout"); + channel.ExchangeDeclare(RabbitConnection.SetQueueNameForEnv(Topics.EventingTopic), "fanout"); } } } @@ -139,15 +134,16 @@ private static void VerifyAndCreateClients() private bool SendMessage(string topicName, string message) { + VerifyAndCreateClients(_clientName); + try { - //using (var connection = RabbitConnection.CreateConnection()) - var connection = RabbitConnection.CreateConnection(); + var connection = RabbitConnection.CreateConnection(_clientName); if (connection != null) { using (var channel = connection.CreateModel()) { - channel.BasicPublish(exchange: SetQueueNameForEnv(topicName), + channel.BasicPublish(exchange: RabbitConnection.SetQueueNameForEnv(topicName), routingKey: "", basicProperties: null, body: Encoding.ASCII.GetBytes(message)); @@ -163,17 +159,5 @@ private bool SendMessage(string topicName, string message) return false; } - - private static string SetQueueNameForEnv(string cacheKey) - { - if (Config.SystemBehaviorConfig.Environment == SystemEnvironment.Dev) - return $"DEV{cacheKey}"; - else if (Config.SystemBehaviorConfig.Environment == SystemEnvironment.QA) - return $"QA{cacheKey}"; - else if (Config.SystemBehaviorConfig.Environment == SystemEnvironment.Staging) - return $"ST{cacheKey}"; - - return cacheKey; - } } } diff --git a/Providers/Resgrid.Providers.Bus/OutboundEventProvider.cs b/Providers/Resgrid.Providers.Bus/OutboundEventProvider.cs index 9cfd49e2..196e7545 100644 --- a/Providers/Resgrid.Providers.Bus/OutboundEventProvider.cs +++ b/Providers/Resgrid.Providers.Bus/OutboundEventProvider.cs @@ -21,8 +21,6 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro _outboundQueueProvider = outboundQueueProvider; _signalrProvider = signalrProvider; - _rabbitTopicProvider = new RabbitTopicProvider(); - _eventAggregator.AddListener(unitStatusHandler); _eventAggregator.AddListener(unitTypeGroupAvailabilityHandler); _eventAggregator.AddListener(unitTypeDepartmentAvailabilityHandler); @@ -64,6 +62,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action unitStatusHandler = async delegate (UnitStatusEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousState = 0; @@ -90,6 +91,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action unitTypeGroupAvailabilityHandler = async delegate (UnitStatusEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousState = 0; @@ -108,6 +112,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action unitTypeDepartmentAvailabilityHandler = async delegate (UnitStatusEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousState = 0; @@ -126,6 +133,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action userStaffingHandler = async delegate (UserStaffingEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousStaffing = 0; @@ -144,6 +154,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action userRoleGroupAvailabilityHandler = async delegate (UserStaffingEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousStaffing = 0; @@ -163,6 +176,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action userRoleDepartmentAvailabilityHandler = async delegate (UserStaffingEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousStaffing = 0; @@ -183,6 +199,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action personnelStatusChangedHandler = async delegate (UserStatusEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousStatus = 0; @@ -201,6 +220,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action userCreatedHandler = async delegate (UserCreatedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.UserCreated; @@ -213,6 +235,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action userAssignedToGroupHandler = async delegate (UserAssignedToGroupEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); int previousGroup = 0; @@ -231,6 +256,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action calendarEventUpcomingHandler = async delegate (CalendarEventUpcomingEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.CalendarEventUpcoming; @@ -243,6 +271,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action calendarEventAddedHandler = async delegate (CalendarEventAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.CalendarEventAdded; @@ -255,6 +286,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action calendarEventUpdatedHandler = async delegate (CalendarEventUpdatedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.CalendarEventUpdated; @@ -267,6 +301,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action documentAddedHandler = async delegate (DocumentAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.DocumentAdded; @@ -279,6 +316,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action noteAddedHandler = async delegate (NoteAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.NoteAdded; @@ -291,6 +331,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action unitAddedHandler = async delegate (UnitAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.UnitAdded; @@ -303,6 +346,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action logAddedHandler = async delegate (LogAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.LogAdded; @@ -315,6 +361,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action resourceOrderAddedHandler = async delegate (ResourceOrderAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.ResourceOrderAdded; @@ -327,6 +376,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action shiftTradeRequestedHandler = async delegate (ShiftTradeRequestedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -341,6 +393,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action shiftTradeRejectedEventHandler = async delegate (ShiftTradeRejectedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -356,6 +411,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action shiftTradeProposedEventHandler = async delegate (ShiftTradeProposedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -371,6 +429,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action shiftTradeFilledEventHandler = async delegate (ShiftTradeFilledEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -386,6 +447,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action shiftCreatedEventHandler = async delegate (ShiftCreatedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -400,6 +464,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action shiftUpdatedEventHandler = async delegate (ShiftUpdatedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -414,6 +481,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action shiftDaysAddedEventHandler = async delegate (ShiftDaysAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -428,6 +498,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro private Action auditEventHandler = async delegate (AuditEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -436,6 +509,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro private Action securityRefreshEventHandler = async delegate (SecurityRefreshEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + if (_outboundQueueProvider == null) _outboundQueueProvider = new OutboundQueueProvider(); @@ -445,6 +521,9 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro #region Topic Based Events public Action departmentSettingsChangedHandler = async delegate (DepartmentSettingsChangedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + var nqi = new NotificationItem(); nqi.Type = (int)EventTypes.DepartmentSettingsChanged; @@ -467,43 +546,66 @@ public OutboundEventProvider(IEventAggregator eventAggregator, IOutboundQueuePro public Action personnelStatusChangedTopicHandler = async delegate (UserStatusEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + _rabbitTopicProvider.PersonnelStatusChanged(message); }; public Action personnelStaffingChangedTopicHandler = async delegate (UserStaffingEvent message) { - if (SystemBehaviorConfig.ServiceBusType == ServiceBusTypes.Rabbit) - _rabbitTopicProvider.PersonnelStaffingChanged(message); + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + + _rabbitTopicProvider.PersonnelStaffingChanged(message); }; public Action unitStatusTopicHandler = async delegate (UnitStatusEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + _rabbitTopicProvider.UnitStatusChanged(message); }; public Action callAddedTopicHandler = async delegate (CallAddedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + _rabbitTopicProvider.CallAdded(message); }; public Action callUpdatedTopicHandler = async delegate (CallUpdatedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + _rabbitTopicProvider.CallUpdated(message); }; public Action callClosedTopicHandler = async delegate (CallClosedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + _rabbitTopicProvider.CallClosed(message); }; public Action personnelLocationUpdatedTopicHandler = async delegate (PersonnelLocationUpdatedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + _rabbitTopicProvider.PersonnelLocationUnidatedChanged(message); }; public Action unitLocationUpdatedTopicHandler = async delegate (UnitLocationUpdatedEvent message) { + if (_rabbitTopicProvider == null) + _rabbitTopicProvider = new RabbitTopicProvider(); + _rabbitTopicProvider.UnitLocationUpdatedChanged(message); }; #endregion Topic Based Events diff --git a/Web/Resgrid.Web.Eventing/Hubs/EventingHub.cs b/Web/Resgrid.Web.Eventing/Hubs/EventingHub.cs index 87ab1ffb..673d22f0 100644 --- a/Web/Resgrid.Web.Eventing/Hubs/EventingHub.cs +++ b/Web/Resgrid.Web.Eventing/Hubs/EventingHub.cs @@ -73,7 +73,7 @@ public async Task PersonnelStatusUpdated(int departmentId, int id) var group = Clients.Group(departmentId.ToString()); if (group != null) - await group.SendAsync("personnelStatusUpdated", id); + await group.SendAsync("PersonnelStatusUpdated", id); } public async Task PersonnelStaffingUpdated(int departmentId, int id) @@ -81,7 +81,7 @@ public async Task PersonnelStaffingUpdated(int departmentId, int id) var group = Clients.Group(departmentId.ToString()); if (group != null) - await group.SendAsync("personnelStaffingUpdated", id); + await group.SendAsync("PersonnelStaffingUpdated", id); } public async Task UnitStatusUpdated(int departmentId, int id) @@ -89,7 +89,7 @@ public async Task UnitStatusUpdated(int departmentId, int id) var group = Clients.Group(departmentId.ToString()); if (group != null) - await group.SendAsync("unitStatusUpdated", id); + await group.SendAsync("UnitStatusUpdated", id); } public async Task CallsUpdated(int departmentId, int id) @@ -97,7 +97,7 @@ public async Task CallsUpdated(int departmentId, int id) var group = Clients.Group(departmentId.ToString()); if (group != null) - await group.SendAsync("callsUpdated", id); + await group.SendAsync("CallsUpdated", id); } public async Task DepartmentUpdated(int departmentId) @@ -105,7 +105,7 @@ public async Task DepartmentUpdated(int departmentId) var group = Clients.Group(departmentId.ToString()); if (group != null) - await group.SendAsync("departmentUpdated"); + await group.SendAsync("DepartmentUpdated"); } public async Task SubscribeToCall(int callId) @@ -123,7 +123,7 @@ public async Task CallDataUpdated(int callId) var group = Clients.Group($"CallUpdated:${callId}"); if (group != null) - await group.SendAsync("callDataUpdated", callId); + await group.SendAsync("CallDataUpdated", callId); } public async Task CallAdded(int departmentId, int id) @@ -131,7 +131,7 @@ public async Task CallAdded(int departmentId, int id) var group = Clients.Group(departmentId.ToString()); if (group != null) - await group.SendAsync("callAdded", id); + await group.SendAsync("CallAdded", id); } public async Task CallClosed(int departmentId, int id) @@ -139,7 +139,7 @@ public async Task CallClosed(int departmentId, int id) var group = Clients.Group(departmentId.ToString()); if (group != null) - await group.SendAsync("callClosed", id); + await group.SendAsync("CallClosed", id); } } } diff --git a/Web/Resgrid.Web.Eventing/Program.cs b/Web/Resgrid.Web.Eventing/Program.cs index 193ee226..c3137a8c 100644 --- a/Web/Resgrid.Web.Eventing/Program.cs +++ b/Web/Resgrid.Web.Eventing/Program.cs @@ -1,8 +1,13 @@ using System.IO; +using System.Reflection; using Autofac.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Resgrid.Config; +using Sentry.Profiling; namespace Resgrid.Web.Eventing { @@ -24,6 +29,57 @@ public static IHostBuilder CreateHostBuilder(string[] args) => }) .ConfigureWebHostDefaults(webBuilder => { + var builder = new Microsoft.Extensions.Configuration.ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) + .AddEnvironmentVariables(); + var config = builder.Build(); + + bool configResult = ConfigProcessor.LoadAndProcessConfig(config["AppOptions:ConfigPath"]); + bool envConfigResult = ConfigProcessor.LoadAndProcessEnvVariables(config.AsEnumerable()); + + if (!string.IsNullOrWhiteSpace(Config.ExternalErrorConfig.ExternalErrorServiceUrlForEventing)) + { + webBuilder.UseSentry(options => + { + //options.MinimumBreadcrumbLevel = LogEventLevel.Debug; + //options.MinimumEventLevel = LogEventLevel.Error; + options.Dsn = Config.ExternalErrorConfig.ExternalErrorServiceUrlForEventing; + options.AttachStacktrace = true; + options.SendDefaultPii = true; + + if (ExternalErrorConfig.SentryPerfSampleRate > 0) + options.EnableTracing = true; + + options.TracesSampleRate = ExternalErrorConfig.SentryPerfSampleRate; + options.Environment = ExternalErrorConfig.Environment; + options.AutoSessionTracking = true; + options.Release = Assembly.GetEntryAssembly().GetName().Version.ToString(); + options.ProfilesSampleRate = ExternalErrorConfig.SentryProfilingSampleRate; + + // Requires NuGet package: Sentry.Profiling + // Note: By default, the profiler is initialized asynchronously. This can be tuned by passing a desired initialization timeout to the constructor. + options.AddIntegration(new ProfilingIntegration( + // During startup, wait up to 500ms to profile the app startup code. This could make launching the app a bit slower so comment it out if your prefer profiling to start asynchronously + //TimeSpan.FromMilliseconds(500) + )); + + options.TracesSampler = samplingContext => + { + if (samplingContext != null && samplingContext.CustomSamplingContext != null) + { + if (samplingContext.CustomSamplingContext.ContainsKey("__HttpPath") && + samplingContext.CustomSamplingContext["__HttpPath"].ToString().ToLower() == "/health/getcurrent") + { + return 0; + } + } + + return ExternalErrorConfig.SentryPerfSampleRate; + }; + }); + } + webBuilder.ConfigureKestrel(serverOptions => { serverOptions.Limits.MaxRequestBufferSize = 302768; @@ -31,6 +87,6 @@ public static IHostBuilder CreateHostBuilder(string[] args) => }); webBuilder.UseStartup(); - }); + }).ConfigureServices(services => services.AddHostedService()); } } diff --git a/Web/Resgrid.Web.Eventing/Services/EventingHubService.cs b/Web/Resgrid.Web.Eventing/Services/EventingHubService.cs index f21771f8..b781b503 100644 --- a/Web/Resgrid.Web.Eventing/Services/EventingHubService.cs +++ b/Web/Resgrid.Web.Eventing/Services/EventingHubService.cs @@ -1,115 +1,115 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.SignalR; -using Resgrid.Config; -using Resgrid.Model; -using Resgrid.Model.Events; -using Resgrid.Model.Providers; -using Resgrid.Model.Services; -using Resgrid.Web.Eventing.Hubs; -using Resgrid.Web.Eventing.Hubs.Models; - -namespace Resgrid.Web.Eventing.Services -{ - public class EventingHubService - { - private readonly IHubContext _eventingHub; - private readonly IHubContext _geolocationHub; - private readonly IRabbitInboundEventProvider _rabbitInboundEventProvider; - - public EventingHubService(IHubContext eventingHub, IHubContext geolocationHub, - IRabbitInboundEventProvider rabbitInboundEventProvider) - { - _eventingHub = eventingHub; - _geolocationHub = geolocationHub; - _rabbitInboundEventProvider = rabbitInboundEventProvider; - _rabbitInboundEventProvider.RegisterForEvents(PersonnelStatusUpdated, UnitStatusUpdated, CallsUpdated, - PersonnelStaffingUpdated, CallAdded, CallClosed, PersonnelLocationUpdated, UnitLocationUpdated); - } +//using System.Threading.Tasks; +//using Microsoft.AspNetCore.SignalR; +//using Resgrid.Config; +//using Resgrid.Model; +//using Resgrid.Model.Events; +//using Resgrid.Model.Providers; +//using Resgrid.Model.Services; +//using Resgrid.Web.Eventing.Hubs; +//using Resgrid.Web.Eventing.Hubs.Models; + +//namespace Resgrid.Web.Eventing.Services +//{ +// public class EventingHubService +// { +// private readonly IHubContext _eventingHub; +// private readonly IHubContext _geolocationHub; +// private readonly IRabbitInboundEventProvider _rabbitInboundEventProvider; + +// public EventingHubService(IHubContext eventingHub, IHubContext geolocationHub, +// IRabbitInboundEventProvider rabbitInboundEventProvider) +// { +// _eventingHub = eventingHub; +// _geolocationHub = geolocationHub; +// _rabbitInboundEventProvider = rabbitInboundEventProvider; +// _rabbitInboundEventProvider.RegisterForEvents(PersonnelStatusUpdated, UnitStatusUpdated, CallsUpdated, +// PersonnelStaffingUpdated, CallAdded, CallClosed, PersonnelLocationUpdated, UnitLocationUpdated); +// } - public async Task PersonnelStatusUpdated(int departmentId, string id) - { - var group = _eventingHub.Clients.Group(departmentId.ToString()); - - if (group != null) - await group.SendAsync("personnelStatusUpdated", id); - } - - public async Task PersonnelStaffingUpdated(int departmentId, string id) - { - var group = _eventingHub.Clients.Group(departmentId.ToString()); - - if (group != null) - await group.SendAsync("personnelStaffingUpdated", id); - } - - public async Task UnitStatusUpdated(int departmentId, string id) - { - var group = _eventingHub.Clients.Group(departmentId.ToString()); - - if (group != null) - await group.SendAsync("unitStatusUpdated", id); - } - - public async Task CallsUpdated(int departmentId, string id) - { - var group = _eventingHub.Clients.Group(departmentId.ToString()); - - if (group != null) - await group.SendAsync("callsUpdated", id); - } - - public async Task DepartmentUpdated(int departmentId) - { - var group = _eventingHub.Clients.Group(departmentId.ToString()); - - if (group != null) - await group.SendAsync("departmentUpdated"); - } - - public async Task CallAdded(int departmentId, string id) - { - var group = _eventingHub.Clients.Group(departmentId.ToString()); - - if (group != null) - await group.SendAsync("callAdded", id); - } - - public async Task CallClosed(int departmentId, string id) - { - var group = _eventingHub.Clients.Group(departmentId.ToString()); - - if (group != null) - await group.SendAsync("callClosed", id); - } - - public async Task PersonnelLocationUpdated(int departmentId, PersonnelLocationUpdatedEvent update) - { - var group = _geolocationHub.Clients.Group(departmentId.ToString()); - - var location = new PersonnelLocationUpdate(); - location.DepartmentId = update.DepartmentId; - location.UserId = update.UserId; - location.Latitude = update.Latitude; - location.Longitude = update.Longitude; - location.RecordId = update.RecordId; - - if (group != null) - await group.SendAsync("onPersonnelLocationUpdated", location); - } - - public async Task UnitLocationUpdated(int departmentId, UnitLocationUpdatedEvent update) - { - var group = _geolocationHub.Clients.Group(departmentId.ToString()); - - var location = new UnitLocationUpdate(); - location.DepartmentId = update.DepartmentId; - location.UnitId = update.UnitId; - location.Latitude = update.Latitude; - location.Longitude = update.Longitude; - location.RecordId = update.RecordId; - - if (group != null) - await group.SendAsync("onUnitLocationUpdated", location); - } - } -} +// public async Task PersonnelStatusUpdated(int departmentId, string id) +// { +// var group = _eventingHub.Clients.Group(departmentId.ToString()); + +// if (group != null) +// await group.SendAsync("personnelStatusUpdated", id); +// } + +// public async Task PersonnelStaffingUpdated(int departmentId, string id) +// { +// var group = _eventingHub.Clients.Group(departmentId.ToString()); + +// if (group != null) +// await group.SendAsync("personnelStaffingUpdated", id); +// } + +// public async Task UnitStatusUpdated(int departmentId, string id) +// { +// var group = _eventingHub.Clients.Group(departmentId.ToString()); + +// if (group != null) +// await group.SendAsync("unitStatusUpdated", id); +// } + +// public async Task CallsUpdated(int departmentId, string id) +// { +// var group = _eventingHub.Clients.Group(departmentId.ToString()); + +// if (group != null) +// await group.SendAsync("callsUpdated", id); +// } + +// public async Task DepartmentUpdated(int departmentId) +// { +// var group = _eventingHub.Clients.Group(departmentId.ToString()); + +// if (group != null) +// await group.SendAsync("departmentUpdated"); +// } + +// public async Task CallAdded(int departmentId, string id) +// { +// var group = _eventingHub.Clients.Group(departmentId.ToString()); + +// if (group != null) +// await group.SendAsync("callAdded", id); +// } + +// public async Task CallClosed(int departmentId, string id) +// { +// var group = _eventingHub.Clients.Group(departmentId.ToString()); + +// if (group != null) +// await group.SendAsync("callClosed", id); +// } + +// public async Task PersonnelLocationUpdated(int departmentId, PersonnelLocationUpdatedEvent update) +// { +// var group = _geolocationHub.Clients.Group(departmentId.ToString()); + +// var location = new PersonnelLocationUpdate(); +// location.DepartmentId = update.DepartmentId; +// location.UserId = update.UserId; +// location.Latitude = update.Latitude; +// location.Longitude = update.Longitude; +// location.RecordId = update.RecordId; + +// if (group != null) +// await group.SendAsync("onPersonnelLocationUpdated", location); +// } + +// public async Task UnitLocationUpdated(int departmentId, UnitLocationUpdatedEvent update) +// { +// var group = _geolocationHub.Clients.Group(departmentId.ToString()); + +// var location = new UnitLocationUpdate(); +// location.DepartmentId = update.DepartmentId; +// location.UnitId = update.UnitId; +// location.Latitude = update.Latitude; +// location.Longitude = update.Longitude; +// location.RecordId = update.RecordId; + +// if (group != null) +// await group.SendAsync("onUnitLocationUpdated", location); +// } +// } +//} diff --git a/Web/Resgrid.Web.Eventing/Startup.cs b/Web/Resgrid.Web.Eventing/Startup.cs index 6ce3cc55..6bd2ea1e 100644 --- a/Web/Resgrid.Web.Eventing/Startup.cs +++ b/Web/Resgrid.Web.Eventing/Startup.cs @@ -35,7 +35,6 @@ using Resgrid.Repositories.DataRepository; using Resgrid.Services; using Resgrid.Web.Eventing.Hubs; -using Resgrid.Web.Eventing.Services; using System.Security.Claims; using OpenIddict.Validation; using static OpenIddict.Abstractions.OpenIddictConstants; @@ -317,7 +316,7 @@ public void ConfigureServices(IServiceCollection services) }; }); - services.AddHostedService(); + //services.AddHostedService(); } public void ConfigureContainer(ContainerBuilder builder) @@ -365,7 +364,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) var eventAggregator = this.AutofacContainer.Resolve(); var outbound = this.AutofacContainer.Resolve(); var eventService = this.AutofacContainer.Resolve(); - //var eventingHubService = this.AutofacContainer.Resolve(); this.Locator = new AutofacServiceLocator(this.AutofacContainer); ServiceLocator.SetLocatorProvider(() => this.Locator); diff --git a/Web/Resgrid.Web.Eventing/Worker.cs b/Web/Resgrid.Web.Eventing/Worker.cs index 5dc08df1..fdd0d68b 100644 --- a/Web/Resgrid.Web.Eventing/Worker.cs +++ b/Web/Resgrid.Web.Eventing/Worker.cs @@ -16,33 +16,64 @@ namespace Resgrid.Web.Eventing { - public class Worker : IHostedService + public class Worker : BackgroundService { private readonly IHubContext _eventingHub; private readonly IHubContext _geolocationHub; private readonly IServiceProvider _serviceProvider; + private readonly IRabbitInboundEventProvider _rabbitInboundEventProvider; public Worker(IServiceProvider serviceProvider, IHubContext eventingHub, IHubContext geolocationHub) { _serviceProvider = serviceProvider; _eventingHub = eventingHub; _geolocationHub = geolocationHub; + + using var scope = _serviceProvider.CreateScope(); + _rabbitInboundEventProvider = scope.ServiceProvider.GetRequiredService(); } - public async Task StartAsync(CancellationToken cancellationToken) + protected override Task ExecuteAsync(CancellationToken stoppingToken = default) { - using var scope = _serviceProvider.CreateScope(); + Console.WriteLine("Starting Eventing Worker"); + stoppingToken.ThrowIfCancellationRequested(); - var rabbitInboundEventProvider = scope.ServiceProvider.GetRequiredService(); + _rabbitInboundEventProvider.RegisterForEvents(PersonnelStatusUpdated, + UnitStatusUpdated, + CallsUpdated, + PersonnelStaffingUpdated, + CallAdded, + CallClosed, + PersonnelLocationUpdated, + UnitLocationUpdated); - rabbitInboundEventProvider.RegisterForEvents(PersonnelStatusUpdated, UnitStatusUpdated, CallsUpdated, - PersonnelStaffingUpdated, CallAdded, CallClosed, PersonnelLocationUpdated, UnitLocationUpdated); + _rabbitInboundEventProvider.Start("Eventing-Web", "EventingWeb").ConfigureAwait(false); - await rabbitInboundEventProvider.Start(); + return Task.CompletedTask; } + //public async Task StartAsync(CancellationToken cancellationToken = default) + //{ + // Console.WriteLine("Starting Eventing Worker"); + + // cancellationToken.ThrowIfCancellationRequested(); + + // _rabbitInboundEventProvider.RegisterForEvents(PersonnelStatusUpdated, + // UnitStatusUpdated, + // CallsUpdated, + // PersonnelStaffingUpdated, + // CallAdded, + // CallClosed, + // PersonnelLocationUpdated, + // UnitLocationUpdated); + + // await _rabbitInboundEventProvider.Start(); + //} + public async Task PersonnelStatusUpdated(int departmentId, string id) { + Console.WriteLine($"Processing RabbitMQ PersonnelStatusUpdated Event For {departmentId}"); + var group = _eventingHub.Clients.Group(departmentId.ToString()); if (group != null) @@ -51,6 +82,8 @@ public async Task PersonnelStatusUpdated(int departmentId, string id) public async Task PersonnelStaffingUpdated(int departmentId, string id) { + Console.WriteLine($"Processing RabbitMQ PersonnelStaffingUpdated Event For {departmentId}"); + var group = _eventingHub.Clients.Group(departmentId.ToString()); if (group != null) @@ -59,6 +92,8 @@ public async Task PersonnelStaffingUpdated(int departmentId, string id) public async Task UnitStatusUpdated(int departmentId, string id) { + Console.WriteLine($"Processing RabbitMQ UnitStatusUpdated Event For {departmentId}"); + var group = _eventingHub.Clients.Group(departmentId.ToString()); if (group != null) @@ -67,6 +102,8 @@ public async Task UnitStatusUpdated(int departmentId, string id) public async Task CallsUpdated(int departmentId, string id) { + Console.WriteLine($"Processing RabbitMQ CallsUpdated Event For {departmentId}"); + var group = _eventingHub.Clients.Group(departmentId.ToString()); if (group != null) @@ -75,6 +112,8 @@ public async Task CallsUpdated(int departmentId, string id) public async Task DepartmentUpdated(int departmentId) { + Console.WriteLine($"Processing RabbitMQ DepartmentUpdated Event For {departmentId}"); + var group = _eventingHub.Clients.Group(departmentId.ToString()); if (group != null) @@ -83,6 +122,8 @@ public async Task DepartmentUpdated(int departmentId) public async Task CallAdded(int departmentId, string id) { + Console.WriteLine($"Processing RabbitMQ CallAdded Event For {departmentId}"); + var group = _eventingHub.Clients.Group(departmentId.ToString()); if (group != null) @@ -91,6 +132,8 @@ public async Task CallAdded(int departmentId, string id) public async Task CallClosed(int departmentId, string id) { + Console.WriteLine($"Processing RabbitMQ CallClosed Event For {departmentId}"); + var group = _eventingHub.Clients.Group(departmentId.ToString()); if (group != null) @@ -128,5 +171,7 @@ public async Task UnitLocationUpdated(int departmentId, UnitLocationUpdatedEvent } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; + + } } diff --git a/Web/Resgrid.Web.Eventing/appsettings.Development.json b/Web/Resgrid.Web.Eventing/appsettings.Development.json index d9d9a9bf..ffc2bbed 100644 --- a/Web/Resgrid.Web.Eventing/appsettings.Development.json +++ b/Web/Resgrid.Web.Eventing/appsettings.Development.json @@ -1,4 +1,7 @@ { + "AppOptions": { + "ConfigPath": "C:\\Resgrid\\Config\\ResgridConfig.json" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/Web/Resgrid.Web.Eventing/appsettings.json b/Web/Resgrid.Web.Eventing/appsettings.json index d9d9a9bf..ffc2bbed 100644 --- a/Web/Resgrid.Web.Eventing/appsettings.json +++ b/Web/Resgrid.Web.Eventing/appsettings.json @@ -1,4 +1,7 @@ { + "AppOptions": { + "ConfigPath": "C:\\Resgrid\\Config\\ResgridConfig.json" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/Web/Resgrid.Web.ServicesCore/Controllers/v4/CalendarController.cs b/Web/Resgrid.Web.ServicesCore/Controllers/v4/CalendarController.cs index 914c9e2b..789e6aaf 100644 --- a/Web/Resgrid.Web.ServicesCore/Controllers/v4/CalendarController.cs +++ b/Web/Resgrid.Web.ServicesCore/Controllers/v4/CalendarController.cs @@ -59,7 +59,7 @@ public async Task> GetDepartmentCalendarI if (items != null && items.Any()) { - + items = items.OrderBy(x => x.Start).ToList(); foreach (var item in items) { if (item.ItemType > 0) diff --git a/Web/Resgrid.Web.ServicesCore/Controllers/v4/CallsController.cs b/Web/Resgrid.Web.ServicesCore/Controllers/v4/CallsController.cs index acf34724..2b96fee9 100644 --- a/Web/Resgrid.Web.ServicesCore/Controllers/v4/CallsController.cs +++ b/Web/Resgrid.Web.ServicesCore/Controllers/v4/CallsController.cs @@ -1089,7 +1089,7 @@ public async Task> EditCall([FromBody] EditCallInpu await _queueService.EnqueueCallBroadcastAsync(cqi, cancellationToken); } - _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = call }); + _eventAggregator.SendMessage(new CallUpdatedEvent() { DepartmentId = DepartmentId, Call = call }); result.Id = call.CallId.ToString(); result.PageSize = 0; @@ -1138,6 +1138,7 @@ public async Task> UpdateSchedul call.HasBeenDispatched = false; var savedCall = await _callsService.SaveCallAsync(call); + _eventAggregator.SendMessage(new CallUpdatedEvent() { DepartmentId = DepartmentId, Call = savedCall }); result.Id = savedCall.CallId.ToString(); result.PageSize = 0; @@ -1185,6 +1186,8 @@ public async Task> DeleteCall(string callId) call.IsDeleted = true; var savedCall = await _callsService.SaveCallAsync(call); + _eventAggregator.SendMessage(new CallUpdatedEvent() { DepartmentId = DepartmentId, Call = savedCall }); + result.Id = savedCall.CallId.ToString(); result.PageSize = 0; result.Status = ResponseHelper.Deleted; @@ -1234,7 +1237,7 @@ public async Task> CloseCall([FromBody] CloseCallI var savedCall = await _callsService.SaveCallAsync(call, cancellationToken); - _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = call }); + _eventAggregator.SendMessage(new CallClosedEvent() { DepartmentId = DepartmentId, Call = savedCall }); result.Id = savedCall.CallId.ToString(); result.PageSize = 0; diff --git a/Web/Resgrid.WebCore/Areas/User/Controllers/DispatchController.cs b/Web/Resgrid.WebCore/Areas/User/Controllers/DispatchController.cs index bdbe5c97..545d8241 100644 --- a/Web/Resgrid.WebCore/Areas/User/Controllers/DispatchController.cs +++ b/Web/Resgrid.WebCore/Areas/User/Controllers/DispatchController.cs @@ -33,6 +33,7 @@ using System.Web; using Resgrid.WebCore.Areas.User.Models.Dispatch; using System.Text; +using Resgrid.Localization.Areas.User.Dispatch; namespace Resgrid.Web.Areas.User.Controllers { @@ -138,7 +139,7 @@ await _geoLocationProvider.GetLatLonFromAddress(string.Format("{0} {1} {2} {3} { } } - model.NewCall = new Call(); + model.NewCall = new Resgrid.Model.Call(); return View(model); } @@ -171,7 +172,7 @@ public async Task NewCall() Unauthorized(); var model = new NewCallView(); - model.Call = new Call(); + model.Call = new Resgrid.Model.Call(); model = await FillNewCallView(model); return View(model); @@ -711,6 +712,7 @@ public async Task UpdateCall(UpdateCallView model, IFormCollectio } await _callsService.SaveCallAsync(call, cancellationToken); + _eventAggregator.SendMessage(new CallUpdatedEvent() { DepartmentId = DepartmentId, Call = call }); if (model.RebroadcastCall) { @@ -728,9 +730,6 @@ public async Task UpdateCall(UpdateCallView model, IFormCollectio if (dispatchingUserIds.Any() || dispatchingGroupIds.Any() || dispatchingUnitIds.Any() || dispatchingRoleIds.Any()) await _queueService.EnqueueCallBroadcastAsync(cqi, cancellationToken); - - - _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = call }); } // scope.Complete(); @@ -770,6 +769,8 @@ public async Task DeleteCall(DeleteCallView model, CancellationTo call.IsDeleted = true; await _callsService.SaveCallAsync(call, cancellationToken); + + _eventAggregator.SendMessage(new CallUpdatedEvent() { DepartmentId = DepartmentId, Call = call }); } return RedirectToAction("Dashboard", "Dispatch", new { Area = "User" }); @@ -818,7 +819,7 @@ public async Task ViewCall(int callId) public async Task AddArchivedCall() { var model = new NewCallView(); - model.Call = new Call(); + model.Call = new Resgrid.Model.Call(); model = await FillNewCallView(model); model.Call.LoggedOn = DateTime.UtcNow.TimeConverter(model.Department); model.Call.ReportingUserId = UserId; @@ -984,6 +985,7 @@ public async Task AddArchivedCall(NewCallView model, IFormCollect catch { /* If No addy, no addy */ } } var call = await _callsService.SaveCallAsync(model.Call, cancellationToken); + _eventAggregator.SendMessage(new CallAddedEvent() { DepartmentId = DepartmentId, Call = call }); if (model.ReCalcuateCallNumbers) { @@ -1064,6 +1066,7 @@ public async Task CloseCall(CloseCallView model, CancellationToke call.State = (int)model.CallState; await _callsService.SaveCallAsync(call, cancellationToken); + _eventAggregator.SendMessage(new CallClosedEvent() { DepartmentId = DepartmentId, Call = call }); return RedirectToAction("Dashboard", "Dispatch", new { Area = "User" }); } @@ -1417,7 +1420,8 @@ public async Task ReOpenCall(int callId, CancellationToken cancel if (!await _authorizationService.CanUserViewCallAsync(UserId, callId)) Unauthorized(); - await _callsService.ReOpenCallByIdAsync(callId, cancellationToken); + var call = await _callsService.ReOpenCallByIdAsync(callId, cancellationToken); + _eventAggregator.SendMessage(new CallUpdatedEvent() { DepartmentId = DepartmentId, Call = call }); return RedirectToAction("Dashboard", "Dispatch", new { Area = "User" }); } @@ -1778,7 +1782,7 @@ public async Task GetArchivedCallsList(string year) { List callsJson = new List(); - List calls; + List calls; if (String.IsNullOrWhiteSpace(year)) calls = await _callsService.GetClosedCallsByDepartmentAsync(DepartmentId); else diff --git a/Web/Resgrid.WebCore/wwwroot/js/app/common/signalr/resgrid.common.signalr.js b/Web/Resgrid.WebCore/wwwroot/js/app/common/signalr/resgrid.common.signalr.js index e739e31a..381fa20e 100644 --- a/Web/Resgrid.WebCore/wwwroot/js/app/common/signalr/resgrid.common.signalr.js +++ b/Web/Resgrid.WebCore/wwwroot/js/app/common/signalr/resgrid.common.signalr.js @@ -78,31 +78,43 @@ var resgrid; //connectionId = id; }); - eventHub.on("personnelStatusUpdated", function (id) { + eventHub.on("PersonnelStatusUpdated", function (id) { if (personnelActionUpdatedCallback) { personnelActionUpdatedCallback(); } }); - eventHub.on("personnelStaffingUpdated", function (id) { + eventHub.on("PersonnelStaffingUpdated", function (id) { if (personnelStaffingUpdatedCallback) { personnelStaffingUpdatedCallback(); } }); - eventHub.on("unitStatusUpdated", function (id) { + eventHub.on("UnitStatusUpdated", function (id) { if (unitStatusUpdatedCallback) { unitStatusUpdatedCallback(); } }); - eventHub.on("callsUpdated", function (id) { + eventHub.on("CallsUpdated", function (id) { if (callsUpdatedCallback) { callsUpdatedCallback(id); } }); - eventHub.on("departmentUpdated", function (id) { + eventHub.on("CallAdded", function (id) { + if (callsUpdatedCallback) { + callsUpdatedCallback(id); + } + }); + + eventHub.on("CallClosed", function (id) { + if (callsUpdatedCallback) { + callsUpdatedCallback(id); + } + }); + + eventHub.on("DepartmentUpdated", function (id) { }); diff --git a/Workers/Resgrid.Workers.Console/Tasks/AuditQueuesProcessorTask.cs b/Workers/Resgrid.Workers.Console/Tasks/AuditQueuesProcessorTask.cs index 046c4246..76e8a302 100644 --- a/Workers/Resgrid.Workers.Console/Tasks/AuditQueuesProcessorTask.cs +++ b/Workers/Resgrid.Workers.Console/Tasks/AuditQueuesProcessorTask.cs @@ -31,7 +31,7 @@ public async Task ProcessAsync(AuditQueueProcessorCommand command, IQuidjiboProg RabbitInboundQueueProvider queue = new RabbitInboundQueueProvider(); queue.AuditEventQueueReceived += OnAuditEventQueueReceived; - await queue.Start(); + await queue.Start("QueueProcessor-Audit"); while (!cancellationToken.IsCancellationRequested) { diff --git a/Workers/Resgrid.Workers.Console/Tasks/PaymentQueueProcessorTask.cs b/Workers/Resgrid.Workers.Console/Tasks/PaymentQueueProcessorTask.cs index 2b0b6a85..5eac7cda 100644 --- a/Workers/Resgrid.Workers.Console/Tasks/PaymentQueueProcessorTask.cs +++ b/Workers/Resgrid.Workers.Console/Tasks/PaymentQueueProcessorTask.cs @@ -30,7 +30,7 @@ public async Task ProcessAsync(PaymentQueueProcessorCommand command, IQuidjiboPr RabbitInboundQueueProvider queue = new RabbitInboundQueueProvider(); queue.PaymentEventQueueReceived += OnPaymentEventQueueReceived; - await queue.Start(); + await queue.Start("QueueProcessor-Payment"); while (!cancellationToken.IsCancellationRequested) { diff --git a/Workers/Resgrid.Workers.Console/Tasks/PersonnelLocationQueuesProcessorTask.cs b/Workers/Resgrid.Workers.Console/Tasks/PersonnelLocationQueuesProcessorTask.cs index 3a3d64b9..15879d79 100644 --- a/Workers/Resgrid.Workers.Console/Tasks/PersonnelLocationQueuesProcessorTask.cs +++ b/Workers/Resgrid.Workers.Console/Tasks/PersonnelLocationQueuesProcessorTask.cs @@ -31,7 +31,7 @@ public async Task ProcessAsync(PersonnelLocationQueueProcessorCommand command, I RabbitInboundQueueProvider queue = new RabbitInboundQueueProvider(); queue.PersonnelLocationEventQueueReceived += OnPersonnelLocationEventQueueReceived; - await queue.Start(); + await queue.Start("QueueProcessor-PersonnelLocation"); while (!cancellationToken.IsCancellationRequested) { diff --git a/Workers/Resgrid.Workers.Console/Tasks/QueuesProcessorTask.cs b/Workers/Resgrid.Workers.Console/Tasks/QueuesProcessorTask.cs index 8354f690..225b96c0 100644 --- a/Workers/Resgrid.Workers.Console/Tasks/QueuesProcessorTask.cs +++ b/Workers/Resgrid.Workers.Console/Tasks/QueuesProcessorTask.cs @@ -51,7 +51,7 @@ public async Task ProcessAsync(QueuesProcessorCommand command, IQuidjiboProgress queue.PersonnelLocationEventQueueReceived += OnPersonnelLocationEventQueueReceived; queue.SecurityRefreshEventQueueReceived += OnSecurityRefreshEventQueueReceived; - await queue.Start(); + await queue.Start("QueueProcessor-CQRS"); while (!_cancellationToken.IsCancellationRequested) { diff --git a/Workers/Resgrid.Workers.Console/Tasks/SystemQueueProcessorTask.cs b/Workers/Resgrid.Workers.Console/Tasks/SystemQueueProcessorTask.cs index b740d0e1..2fbdf3a1 100644 --- a/Workers/Resgrid.Workers.Console/Tasks/SystemQueueProcessorTask.cs +++ b/Workers/Resgrid.Workers.Console/Tasks/SystemQueueProcessorTask.cs @@ -31,7 +31,7 @@ public async Task ProcessAsync(SystemQueueProcessorCommand command, IQuidjiboPro RabbitInboundQueueProvider queue = new RabbitInboundQueueProvider(); queue.CqrsEventQueueReceived += OnCqrsEventQueueReceived; - await queue.Start(); + await queue.Start("QueueProcessor-System"); while (!cancellationToken.IsCancellationRequested) { diff --git a/Workers/Resgrid.Workers.Console/Tasks/UnitLocationQueuesProcessorTask.cs b/Workers/Resgrid.Workers.Console/Tasks/UnitLocationQueuesProcessorTask.cs index 628fa54f..19de57ea 100644 --- a/Workers/Resgrid.Workers.Console/Tasks/UnitLocationQueuesProcessorTask.cs +++ b/Workers/Resgrid.Workers.Console/Tasks/UnitLocationQueuesProcessorTask.cs @@ -31,7 +31,7 @@ public async Task ProcessAsync(UnitLocationQueueProcessorCommand command, IQuidj RabbitInboundQueueProvider queue = new RabbitInboundQueueProvider(); queue.UnitLocationEventQueueReceived += OnUnitLocationEventQueueReceived; - await queue.Start(); + await queue.Start("QueueProcessor-UnitLocation"); while (!cancellationToken.IsCancellationRequested) {