Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
            }
        }