Example #1
0
        public static PublicationAddress ToPublicationAddress(this Uri uri, RabbitChannelGroupConfiguration config)
        {
            if (uri == ChannelEnvelope.LoopbackAddress)
            {
                return(new PublicationAddress(ExchangeType.Direct, string.Empty, config.InputQueue));
            }

            if (uri == ChannelEnvelope.DeadLetterAddress)
            {
                return(config.DeadLetterExchange);
            }

            if (uri == ChannelEnvelope.UnhandledMessageAddress)
            {
                return(config.UnhandledMessageExchange);
            }

            if (uri == ChannelEnvelope.UnroutableMessageAddress)
            {
                return(config.UnroutableMessageExchange);
            }

            var address = PublicationAddress.Parse(uri.ToString());

            return(address.ExchangeName.NormalizeName() == "default"
                                ? new PublicationAddress(ExchangeType.Direct, string.Empty, address.RoutingKey) : address);
        }
        public void ShouldDeserializeWithoutExchange()
        {
            //Act
            var addr = PublicationAddress.Parse(":///routing-key");

            //Assert
            Assert.Null(addr);
        }
Example #3
0
        public void Copying()
        {
            const String appId           = "app-id";
            const String clusterId       = "cluster-id";
            const String type            = "type";
            const String contentEncoding = "UTF-8";
            const String contentType     = "application/xml";
            const String correlationId   = "123";
            const Byte   deliveryMode    = 2;
            const String expiration      = "60000";
            const String messageId       = "456";
            const Byte   priority        = 3;
            const String userId          = "me";
            const String replyTo         = "amqp://my.host";
            var          timestamp       = new AmqpTimestamp(1445843868L);

            var properties = new BasicProperties
            {
                AppId           = appId,
                ClusterId       = clusterId,
                Type            = type,
                ContentEncoding = contentEncoding,
                ContentType     = contentType,
                CorrelationId   = correlationId,
                DeliveryMode    = deliveryMode,
                Expiration      = expiration,
                MessageId       = messageId,
                Priority        = priority,
                UserId          = userId,
                ReplyTo         = replyTo,
                Headers         = new Dictionary <String, Object>
                {
                    { "h", "a" }
                },
                Timestamp = timestamp
            };
            var copy = properties.Copy();

            Assert.Equal(appId, copy.AppId);
            Assert.Equal(clusterId, copy.ClusterId);
            Assert.Equal(type, copy.Type);
            Assert.Equal(contentEncoding, copy.ContentEncoding);
            Assert.Equal(contentType, copy.ContentType);
            Assert.Equal(correlationId, copy.CorrelationId);
            Assert.Equal(deliveryMode, copy.DeliveryMode);
            Assert.Equal(expiration, copy.Expiration);
            Assert.Equal(messageId, copy.MessageId);
            Assert.Equal(priority, copy.Priority);
            Assert.Equal(userId, copy.UserId);
            Assert.Equal(replyTo, copy.ReplyTo);
            Assert.Equal(PublicationAddress.Parse(replyTo), copy.ReplyToAddress);
            Assert.Equal(1, copy.Headers.Count);
            Assert.True(copy.Headers.ContainsKey("h"));
            Assert.Equal("a", copy.Headers["h"]);
            Assert.Equal(timestamp, copy.Timestamp);
        }
        public void TestParseOk()
        {
            string             uriLike = "fanout://name/key";
            PublicationAddress addr    = PublicationAddress.Parse(uriLike);

            Assert.AreEqual(ExchangeType.Fanout, addr.ExchangeType);
            Assert.AreEqual("name", addr.ExchangeName);
            Assert.AreEqual("key", addr.RoutingKey);
            Assert.AreEqual(uriLike, addr.ToString());
        }
        public void TestEmptyRoutingKey()
        {
            string             uriLike = "direct://exch/";
            PublicationAddress addr    = PublicationAddress.Parse(uriLike);

            Assert.AreEqual(ExchangeType.Direct, addr.ExchangeType);
            Assert.AreEqual("exch", addr.ExchangeName);
            Assert.AreEqual("", addr.RoutingKey);
            Assert.AreEqual(uriLike, addr.ToString());
        }
        public void ShouldDeserializeWithExchange()
        {
            //Act
            var addr = PublicationAddress.Parse("exchange-type://exchange-name/routing-key");

            //Assert
            Assert.Equal("exchange-type", addr.ExchangeType);
            Assert.Equal("exchange-name", addr.ExchangeName);
            Assert.Equal("routing-key", addr.RoutingKey);
        }
Example #7
0
 public void Reply <TReplyMessage>(TReplyMessage responseMessage)
 {
     if (_basicProperties.ReplyTo != null)
     {
         PublicationAddress publicationAddress = PublicationAddress.Parse(_basicProperties.ReplyTo);
         var replyProperties = new BasicProperties();
         replyProperties.CorrelationId = _basicProperties.CorrelationId;
         _messagePublisher.PublishReply <TMessage, TReplyMessage>(publicationAddress, responseMessage, replyProperties);
     }
 }
        public void ShouldDeserializeWithoutExchangeName()
        {
            //Act
            var addr = PublicationAddress.Parse("default:///routing-key");

            //Assert
            Assert.Equal("default", addr.ExchangeType);
            Assert.Equal("", addr.ExchangeName);
            Assert.Equal("routing-key", addr.RoutingKey);
        }
Example #9
0
        public bool VerifyDestination(Destination destination, EndpointUsage usage, bool configureIfRequired, out string error)
        {
            try
            {
                var publish = PublicationAddress.Parse(destination.Publish) ?? new PublicationAddress("topic", destination.Publish, "");;
                using (IConnection connection = m_Factory.CreateConnection())
                {
                    using (IModel channel = connection.CreateModel())
                    {
                        if ((usage & EndpointUsage.Publish) == EndpointUsage.Publish)
                        {
                            if (configureIfRequired)
                            {
                                channel.ExchangeDeclare(publish.ExchangeName, publish.ExchangeType, true);
                            }
                            else
                            {
                                channel.ExchangeDeclarePassive(publish.ExchangeName);
                            }
                        }

                        if ((usage & EndpointUsage.Subscribe) == EndpointUsage.Subscribe)
                        {
                            if (configureIfRequired)
                            {
                                channel.QueueDeclare(destination.Subscribe, true, false, false, null);
                            }
                            else
                            {
                                channel.QueueDeclarePassive(destination.Subscribe);
                            }

                            if (configureIfRequired)
                            {
                                channel.QueueBind(destination.Subscribe, publish.ExchangeName, publish.RoutingKey == "" ? "#" : publish.RoutingKey);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (!e.GetType().Namespace.StartsWith("RabbitMQ") || e.GetType().Assembly != typeof(OperationInterruptedException).Assembly)
                {
                    throw;
                }
                error = e.Message;
                return(false);
            }
            error = null;
            return(true);
        }
Example #10
0
        public Task <Message <U> > SendCommand <T, U>(string commandQueueName, Message <T> command) where U : new()
        {
            var n = PublicationAddress.Parse(commandQueueName);

            lock (_channel)
            {
                _channel.ExchangeDeclare(exchange: n.ExchangeName, n.ExchangeType, false, true, null);

                var replyQueueName = _channel.QueueDeclare().QueueName;
                _channel.QueueDeclare(n.ExchangeName, durable: false, exclusive: false, autoDelete: true, arguments: null);

                TaskCompletionSource <Message <U> > result = new TaskCompletionSource <Message <U> >();

                var corrId   = Guid.NewGuid().ToString();
                var consumer = new EventingBasicConsumer(_channel);
                consumer.Received += (s, e) =>
                {
                    if (e.BasicProperties.CorrelationId == corrId)
                    {
                        try
                        {
                            _channel.BasicCancel(_consumerTag);

                            var ser = _payloadSerializer.GetSerializer(e.BasicProperties.ContentType);

                            var answer = new Message <U>(ser.Deserialize <U>(e.Body));
                            result.SetResult(answer);
                        }
                        catch (Exception exception)
                        {
                            result.SetException(exception);
                        }
                    }
                };
                _consumerTag = _channel.BasicConsume(queue: replyQueueName, autoAck: true, consumer: consumer);


                var props = _channel.CreateBasicProperties();
                props.ContentType   = Serializer.ContentType;
                props.ReplyTo       = replyQueueName;
                props.CorrelationId = corrId;
                props.Persistent    = command.Persistent;


                _channel.BasicPublish(exchange: "", n.ExchangeName, basicProperties: props, body: Serializer.Serialize(command.Payload));

                return(result.Task);
            }
        }
        public void TestExchangeTypeValidation()
        {
            string             uriLike = "direct:///";
            PublicationAddress addr    = PublicationAddress.Parse(uriLike);
            int found = 0;

            foreach (string exchangeType in ExchangeType.All())
            {
                if (exchangeType.Equals(addr.ExchangeType))
                {
                    found++;
                }
            }
            Assert.AreEqual(1, found);
        }
Example #12
0
        public void Start <T, U>(string queueName, Func <Message <T>, Message <U> > commandReceived) where T : new()
        {
            var n = PublicationAddress.Parse(queueName);

            _channel.QueueDeclare(n.ExchangeName, durable: false, exclusive: false, autoDelete: true, arguments: null);
            _channel.BasicQos(0, 1, false);

            var consumer = new EventingBasicConsumer(_channel);

            consumer.Received += (s, e) =>
            {
                try
                {
                    try
                    {
                        var ser = _payloadSerializer.GetSerializer(e.BasicProperties.ContentType);

                        var command = new Message <T>(ser.Deserialize <T>(e.Body))
                        {
                            Persistent    = e.BasicProperties.Persistent,
                            CorrelationId = e.BasicProperties.CorrelationId,
                            ReplyTo       = e.BasicProperties.ReplyTo
                        };

                        var response = commandReceived(command);

                        var replyProps = _channel.CreateBasicProperties();
                        replyProps.ContentType   = Serializer.ContentType;
                        replyProps.CorrelationId = e.BasicProperties.CorrelationId;
                        replyProps.Persistent    = response.Persistent;

                        _channel.BasicPublish(exchange: "", routingKey: e.BasicProperties.ReplyTo,
                                              basicProperties: replyProps, body: Serializer.Serialize(response.Payload));
                        _channel.BasicAck(deliveryTag: e.DeliveryTag, multiple: false);
                    }
                    catch (Exception)
                    {
                        _channel.BasicNack(e.DeliveryTag, false, false);
                    }
                }
                catch (Exception)
                {
                    _channel.BasicNack(e.DeliveryTag, false, true);
                }
            };
            _consumerToken = _channel.BasicConsume(queue: n.ExchangeName, autoAck: false, consumer: consumer);
        }
Example #13
0
        public IDisposable RegisterHandler(string destination, Func <BinaryMessage, BinaryMessage> handler, string messageType)
        {
            var subscription = subscribe(destination, (properties, bytes, acknowledge) =>
            {
                var correlationId = properties.CorrelationId;
                var responseBytes = handler(toBinaryMessage(properties, bytes));
                //If replyTo is not parsable we treat it as queue name and message is sent via default exchange  (http://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default)
                var publicationAddress = PublicationAddress.Parse(properties.ReplyTo) ?? new PublicationAddress("direct", "", properties.ReplyTo);
                send(publicationAddress, responseBytes, p =>
                {
                    if (correlationId != null)
                    {
                        p.CorrelationId = correlationId;
                    }
                });
                acknowledge(true);
            }, messageType);

            return(subscription);
        }
Example #14
0
        ///<summary>Process a single request received from our
        ///subscription.</summary>
        ///<remarks>
        ///<para>
        /// If the request's properties contain a non-null, non-empty
        /// CorrelationId string (see IBasicProperties), it is assumed
        /// to be a two-way call, requiring a response. The ReplyTo
        /// header property is used as the reply address (via
        /// PublicationAddress.Parse, unless that fails, in which case it
        /// is treated as a simple queue name), and the request is
        /// passed to HandleCall().
        ///</para>
        ///<para>
        /// If the CorrelationId is absent or empty, the request is
        /// treated as one-way asynchronous event, and is passed to
        /// HandleCast().
        ///</para>
        ///<para>
        /// Usually, overriding HandleCall(), HandleCast(), or one of
        /// their delegates is sufficient to implement a service, but
        /// in some cases overriding ProcessRequest() is
        /// required. Overriding ProcessRequest() gives the
        /// opportunity to implement schemes for detecting interaction
        /// patterns other than simple request/response or one-way
        /// communication.
        ///</para>
        ///</remarks>
        public virtual void ProcessRequest(BasicDeliverEventArgs evt)
        {
            IBasicProperties properties = evt.BasicProperties;

            if (properties.ReplyTo != null && properties.ReplyTo != "")
            {
                // It's a request.

                PublicationAddress replyAddress = PublicationAddress.Parse(properties.ReplyTo);
                if (replyAddress == null)
                {
                    replyAddress = new PublicationAddress(ExchangeType.Direct,
                                                          "",
                                                          properties.ReplyTo);
                }

                IBasicProperties replyProperties;
                byte[]           reply = HandleCall(evt.Redelivered,
                                                    properties,
                                                    evt.Body,
                                                    out replyProperties);
                if (replyProperties == null)
                {
                    replyProperties = m_subscription.Model.CreateBasicProperties();
                }

                replyProperties.CorrelationId = properties.CorrelationId;
                m_subscription.Model.BasicPublish(replyAddress,
                                                  replyProperties,
                                                  reply);
            }
            else
            {
                // It's an asynchronous message.
                HandleCast(evt.Redelivered, properties, evt.Body);
            }
        }
 public void TestMissingExchangeType()
 {
     Assert.IsNull(PublicationAddress.Parse("://exch/key"));
 }
Example #16
0
        public bool VerifyDestination(
            Destination destination,
            EndpointUsage usage,
            bool configureIfRequired,
            out string error)
        {
            try
            {
                var publish = PublicationAddress.Parse(destination.Publish) ?? new PublicationAddress("topic", destination.Publish, "");;
                using (IConnection connection = CreateConnection(false))
                {
                    using (IModel channel = connection.CreateModel())
                    {
                        if (publish.ExchangeName == "" && publish.ExchangeType.ToLower() == "direct")
                        {
                            //default exchange should not be verified since it always exists and publication to it is always possible
                        }
                        else
                        {
                            if (configureIfRequired)
                            {
                                channel.ExchangeDeclare(publish.ExchangeName, publish.ExchangeType, true);
                            }
                            else
                            {
                                channel.ExchangeDeclarePassive(publish.ExchangeName);
                            }
                        }

                        //temporary queue should not be verified since it is not supported by rmq client
                        if ((usage & EndpointUsage.Subscribe) == EndpointUsage.Subscribe && !destination.Subscribe.ToLower().StartsWith("amq."))
                        {
                            if (configureIfRequired)
                            {
                                channel.QueueDeclare(destination.Subscribe, true, false, false, null);
                            }
                            else
                            {
                                channel.QueueDeclarePassive(destination.Subscribe);
                            }

                            if (configureIfRequired)
                            {
                                channel.QueueBind(destination.Subscribe, publish.ExchangeName, publish.RoutingKey == "" ? "#" : publish.RoutingKey);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (!e.GetType().Namespace.StartsWith("RabbitMQ") || e.GetType().Assembly != typeof(OperationInterruptedException).Assembly)
                {
                    throw;
                }
                error = e.Message;
                return(false);
            }
            error = null;
            return(true);
        }
Example #17
0
        private void send(string destination, BinaryMessage message, Action <IBasicProperties> tuneMessage = null)
        {
            var publicationAddress = PublicationAddress.Parse(destination) ?? new PublicationAddress("direct", destination, "");

            send(publicationAddress, message, tuneMessage);
        }
Example #18
0
        public void Start <T>(string address, string queueName, Action <Message <T> > messageReceived) where T : new()
        {
            var n = PublicationAddress.Parse(address);

            Start(n.ExchangeType, n.ExchangeName, n.RoutingKey, queueName, messageReceived);
        }
 public void TestParseFailWithUnparseableInput()
 {
     Assert.IsNull(PublicationAddress.Parse("not a valid URI"));
 }
 public void TestParseFailWithANE()
 {
     Assert.That(() => PublicationAddress.Parse(null), Throws.ArgumentNullException);
 }
Example #21
0
        public void Send <T>(string queueName, Message <T> message)
        {
            var n = PublicationAddress.Parse(queueName);

            Send(n.ExchangeType, n.ExchangeName, n.RoutingKey, PayloadSerializerFactory.DefaultContentType, message);
        }
Example #22
0
 public void TestParseFail()
 {
     Assert.IsNull(PublicationAddress.Parse("not a valid uri"));
 }