public void Publish(IntegrationEvent evt) { if (!_persistentConnection.IsConnected) { _persistentConnection.TryConnect(); } var policy = RetryPolicy.Handle <BrokerUnreachableException>() .Or <SocketException>() .WaitAndRetry(_retryCount, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => { _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", evt.EventId, $"{time.TotalSeconds:n1}", ex.Message); }); var eventName = evt.GetNormalizeTypeName(); _logger.LogTrace("Creating RabbitMQ channel to publish event: {EventId} ({EventName})", evt.EventId, eventName); _logger.LogTrace("Declaring RabbitMQ exchange to publish event: {EventId}", evt.EventId); using var channel = GetChannelWithDeclare(evt.BusParams); channel.QueueBind(evt.BusParams.QueueName, evt.BusParams.ExchangeName, eventName); var message = JsonSerializer.Serialize(evt, evt.GetType(), new JsonSerializerOptions { WriteIndented = false, Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic) }); var body = Encoding.UTF8.GetBytes(message); policy.Execute(() => { var properties = channel.CreateBasicProperties(); properties.DeliveryMode = 2; // persistent _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", evt.EventId); channel.BasicPublish( exchange: evt.BusParams.ExchangeName, routingKey: eventName, mandatory: true, basicProperties: properties, body: body); }); }
private async Task ProcessEvent(IntegrationEvent iEvent) { var eventName = iEvent.GetNormalizeTypeName(); _logger.LogDebug("Processing event: {EventName}", eventName); if (_subsManager.HasSubscriptionsForEvent(eventName)) { var subscriptions = _subsManager.GetHandlersForEvent(eventName); foreach (var subscription in subscriptions) { var handler = subscription.HandlerType; if (handler == null) { continue; } var handlerConstructor = handler.GetConstructors(BindingFlags.Public | BindingFlags.Instance) .OrderByDescending(c => c.GetParameters().Length).First(); var parameters = handlerConstructor.GetParameters(); var arguments = parameters.Select(p => _serviceProvider.GetService(p.ParameterType)).ToArray(); dynamic objectHandler = handlerConstructor.Invoke(arguments); var eventType = _subsManager.GetEventTypeByName(eventName); var concreteType = typeof(IIntegrationEventHandler <>).MakeGenericType(eventType); await Task.Yield(); await(Task) concreteType.GetMethod("Handle").Invoke(objectHandler, new object[] { iEvent }); } } else { _logger.LogWarning("No subscription for event: {EventName}.", eventName); } }