public Task <IEnumerable <IMessageListener> > StartListeningAsync( IConfiguration configuration, IServiceDefinition serviceDefinition, IDictionary <IMethodDefinition, IConfiguration> methodConfigMap, CancellationToken ct) { var resultListeners = new List <IMessageListener>(); var baseConnectionSettings = new ConnectionSettings(); configuration.Bind(baseConnectionSettings); var baseListenerSettings = RabbitMQCommunicationMethod.CreateMethodsDefaultSettings(); configuration.Bind(baseListenerSettings); IConnection baseConnection = null; IModel baseChannel = null; if (!baseListenerSettings.QueueName.Contains("{methodName}")) { baseConnection = _connectionManager.GetConnection(baseConnectionSettings); baseChannel = baseConnection.CreateModel(); baseChannel.ConfirmSelect(); } foreach (var methodDefinition in serviceDefinition.Methods) { if (methodDefinition.IsIgnored) { continue; } var connection = baseConnection; var channel = baseChannel; CommunicationSettings listenerSettings; ConnectionSettings connectionSettings; if (methodConfigMap.TryGetValue(methodDefinition, out var methodConfiguration)) { connectionSettings = new ConnectionSettings(); methodConfiguration.Bind(connectionSettings); listenerSettings = RabbitMQCommunicationMethod.CreateMethodsDefaultSettings(); methodConfiguration.Bind(listenerSettings); } else { connectionSettings = baseConnectionSettings; listenerSettings = baseListenerSettings; } if (connection == null) { connection = _connectionManager.GetConnection(connectionSettings); channel = connection.CreateModel(); channel.ConfirmSelect(); } var queueName = listenerSettings.QueueName .Replace("{serviceName}", serviceDefinition.Name) .Replace("{methodName}", methodDefinition.Name); var listener = _messageHandler.StartListeningQueue(channel, queueName); if (listener != null) { resultListeners.Add(listener); } } return(Task.FromResult <IEnumerable <IMessageListener> >(resultListeners)); }
public Task <IEnumerable <IMessageListener> > StartListeningAsync( IConfiguration configuration, IServiceDefinition serviceDefinition, IDictionary <IEventDefinition, IConfiguration> eventConfigMap, CancellationToken ct) { // TODO: there are many scenarios that are not supported by the following code. // For example, exchange's connection is different from services' queues. var baseConnectionSettings = new ConnectionSettings(); configuration.Bind(baseConnectionSettings); var baseConnection = _connectionManager.GetConnection(baseConnectionSettings); var baseChannel = baseConnection.CreateModel(); foreach (var eventDefinition in serviceDefinition.Events) { if (!eventConfigMap.TryGetValue(eventDefinition, out var eventConfiguration)) { eventConfiguration = configuration; } var listenerSettings = RabbitMQCommunicationMethod.CreateEventsDefaultSettings(); eventConfiguration.Bind(listenerSettings); var exchangeName = listenerSettings.ExchangeName .Replace("{serviceName}", serviceDefinition.Name) .Replace("{eventName}", eventDefinition.Name); // TODO: declare once? what's the penalty? baseChannel.ExchangeDeclare( exchangeName, type: "fanout", durable: true, autoDelete: false, arguments: null); var eventDesc = new EventDescriptor { Service = new ServiceId { Name = serviceDefinition.Name }, Event = _eventIdProvider.GetId(eventDefinition.EventInfo) }; foreach (var subscriber in _eventSubscriber.GetSubscribers(eventDesc)) { if (!_serviceResolver.TryResolve(subscriber.Service, out var subscriberServiceReference)) { continue; } if (!_methodResolver.TryResolve(subscriberServiceReference.Definition, subscriber.Method, out var subscriberMethodReference)) { continue; } var subscriberMethodConfiguration = _communicationModelConfiguration.GetMethodConfiguration(subscriberMethodReference.Definition, "communication"); var subscriberSettings = RabbitMQCommunicationMethod.CreateMethodsDefaultSettings(); subscriberMethodConfiguration.Bind(subscriberSettings); var subscriberQueueName = subscriberSettings.QueueName .Replace("{serviceName}", subscriberServiceReference.Definition.Name) .Replace("{methodName}", subscriberMethodReference.Definition.Name); // TODO: declare once? what's the penalty? baseChannel.QueueBind( queue: subscriberQueueName, exchange: exchangeName, routingKey: "", arguments: null); } } // No direct listeners to RabbitMQ Exchanges, just configure exchange-queue bindings. // TODO: if events (or subscribers) use a different connection, // need to create a queue and a listener in that RabbitMQ instance. return(Task.FromResult <IEnumerable <IMessageListener> >(Array.Empty <IMessageListener>())); }