public Task <IObservable <Message> > StartAsync() { _sequenceOfMessages = new Subject <Envelope>(); var commands = _sequenceOfMessages .Where(m => m != null) .Where(m => m.MessageType == MessageType.Command) .Select(GetCommandMessage) .Where(m => m != null) .Cast <Message>(); var events = _sequenceOfMessages .Where(m => m != null) .Where(m => m.MessageType == MessageType.Event) .Select(GetEventMessage) .Where(m => m != null) .Cast <Message>(); _isStarted = true; return(Task.FromResult(Observable.Merge(commands, events))); CommandMessage GetCommandMessage(Envelope incoming) { var incomingType = incoming.Type; if (_acceptedTypes.Contains(incomingType)) { return(_envelopeService.CreateCommandMessage(incoming, incomingType)); } if (_messageDescriptorStore.FindCommandTypeForDescriptor(incoming.Descriptor, out var outgoingType)) { return(_envelopeService.CreateCommandMessage(incoming, outgoingType)); } return(null); } EventMessage GetEventMessage(Envelope incoming) { var incomingType = incoming.Type; if (_acceptedTypes.Contains(incomingType)) { return(_envelopeService.CreateEventMessage(incoming, incomingType)); } if (_messageDescriptorStore.FindEventTypeForDescriptor(incoming.Descriptor, out var outgoingType)) { return(_envelopeService.CreateEventMessage(incoming, outgoingType)); } return(null); } }
public Task <IObservable <Message> > StartAsync() { _connection = _configuration.ConnectionFactory.CreateConnection(); _channel = _connection.CreateModel(); if (_configuration.UnackedMessageCountLimit.HasValue) { _channel.BasicQos(0, _configuration.UnackedMessageCountLimit.Value, true); } var hasEvents = _messageDescriptorStore.HasEvents(); var hasCommands = _messageDescriptorStore.HasCommands(); if (!hasEvents && !hasCommands) { return(Task.FromResult(Observable.Never <Message>())); } var queueToConsume = new List <string>(); if (hasEvents) { var eventQueue = _configuration.EventQueueFactory.CreateQueue(_channel); foreach (var type in _messageDescriptorStore.Events) { var exchangeName = MessageDescriptor.CreateFromType(type); _configuration.EventExchangeManager.EnsureExchangeExists(_channel, exchangeName, FanOutExchangeType); _channel.QueueBind(queue: eventQueue.QueueName, exchange: exchangeName, routingKey: string.Empty); } queueToConsume.Add(eventQueue.QueueName); } if (hasCommands) { var commandQueue = _configuration.CommandQueueFactory.CreateQueue(_channel); foreach (var type in _messageDescriptorStore.Commands) { var exchangeName = MessageDescriptor.CreateFromType(type); _configuration.CommandExchangeManager.EnsureExchangeExists(_channel, exchangeName, FanOutExchangeType); _channel.QueueBind(queue: commandQueue.QueueName, exchange: exchangeName, routingKey: string.Empty); } queueToConsume.Add(commandQueue.QueueName); } var sequence = from queue in queueToConsume.ToObservable() from args in SubscribeMessages(_channel, queue) let message = GetMessage(args) where message != null select message; return(Task.FromResult(sequence)); IObservable <BasicDeliverEventArgs> SubscribeMessages(IModel channel, string queueName) { var consumer = new ObservableConsumer(channel); consumer.ConsumeFrom(queueName); _consumers.Add(queueName, consumer); return(consumer); } Message GetMessage(BasicDeliverEventArgs args) { _logger.LogTrace($"Received message {args.DeliveryTag}"); _processingMessages.Add(args.DeliveryTag); var encoding = Encoding.GetEncoding(args.BasicProperties.ContentEncoding); var messageTypeName = args.BasicProperties.GetHeader(Nybus(Headers.MessageType), encoding); Message message = null; if (!MessageDescriptor.TryParse(messageTypeName, out var descriptor)) { NackMessage(args.DeliveryTag); return(null); } if (_messageDescriptorStore.FindCommandTypeForDescriptor(descriptor, out var commandType)) { var command = _configuration.Serializer.DeserializeObject(args.Body, commandType, encoding) as ICommand; message = CreateCommandMessage(command); } else if (_messageDescriptorStore.FindEventTypeForDescriptor(descriptor, out var eventType)) { var @event = _configuration.Serializer.DeserializeObject(args.Body, eventType, encoding) as IEvent; message = CreateEventMessage(@event); } else { NackMessage(args.DeliveryTag); return(null); } message.MessageId = args.BasicProperties.GetHeader(Nybus(Headers.MessageId), encoding); message.Headers = new HeaderBag { [Headers.CorrelationId] = args.BasicProperties.GetHeader(Nybus(Headers.CorrelationId), encoding), [Headers.SentOn] = args.BasicProperties.GetHeader(Nybus(Headers.SentOn), encoding), [Headers.RetryCount] = args.BasicProperties.GetHeader(Nybus(Headers.RetryCount), encoding), [RabbitMqHeaders.DeliveryTag] = args.DeliveryTag.ToString(), [RabbitMqHeaders.MessageId] = args.BasicProperties.MessageId }; foreach (var header in args.BasicProperties.Headers) { if (header.Key.StartsWith("Custom:")) { var headerKey = ParseCustom(header.Key); var value = args.BasicProperties.GetHeader(header.Key, encoding); message.Headers.Add(headerKey, value); } else if (header.Key.StartsWith("RabbitMq:")) { var value = args.BasicProperties.GetHeader(header.Key, encoding); message.Headers.Add(header.Key, value); } } return(message); } CommandMessage CreateCommandMessage(ICommand command) { var messageType = typeof(CommandMessage <>).MakeGenericType(command.GetType()); var message = Activator.CreateInstance(messageType) as CommandMessage; message?.SetCommand(command); return(message); } EventMessage CreateEventMessage(IEvent @event) { var messageType = typeof(EventMessage <>).MakeGenericType(@event.GetType()); var message = Activator.CreateInstance(messageType) as EventMessage; message?.SetEvent(@event); return(message); } }