public RabbitAckInfo(IConnection connection, RC.IModel channel, bool transacted, RC.BasicGetResult getResponse)
 {
     Connection = connection;
     Channel    = channel;
     Transacted = transacted;
     Response   = getResponse;
 }
        /// <summary>Converts from BasicProperties to MessageProperties.</summary>
        /// <param name="source">The source.</param>
        /// <param name="envelope">The envelope.</param>
        /// <param name="charset">The charset.</param>
        /// <returns>The message properties.</returns>
        public MessageProperties ToMessageProperties(IBasicProperties source, BasicGetResult envelope, string charset)
        {
            var target = new MessageProperties();
            var headers = source.Headers;
            if (headers != null && headers.Count > 0)
            {
                foreach (DictionaryEntry entry in headers)
                {
                    var value = entry.Value;

                    /*
                    if (value is LongString) 
                    {
                        value = this.convertLongString((LongString) value, charset);
                    }
                    */
                    target.Headers[(string)entry.Key] = value;
                }
            }

            target.Timestamp = source.Timestamp.ToDateTime();
            target.MessageId = source.MessageId;
            target.UserId = source.UserId;
            target.AppId = source.AppId;
            target.ClusterId = source.ClusterId;
            target.Type = source.Type;
            target.DeliveryMode = (MessageDeliveryMode)source.DeliveryMode;
            target.Expiration = source.Expiration;
            target.Priority = source.Priority;
            target.ContentType = source.ContentType;
            target.ContentEncoding = source.ContentEncoding;
            var correlationId = source.CorrelationId;
            if (correlationId != null)
            {
                try
                {
                    target.CorrelationId = source.CorrelationId.ToByteArrayWithEncoding(charset);
                }
                catch (Exception ex)
                {
                    throw new AmqpUnsupportedEncodingException(ex);
                }
            }

            var replyTo = source.ReplyTo;
            if (replyTo != null)
            {
                target.ReplyTo = replyTo;
            }

            if (envelope != null)
            {
                target.ReceivedExchange = envelope.Exchange;
                target.ReceivedRoutingKey = envelope.RoutingKey;
                target.Redelivered = envelope.Redelivered;
                target.DeliveryTag = (long)envelope.DeliveryTag;
            }

            return target;
        }
Example #3
0
 // Summary:
 //     Sets the new instance's properties from the arguments passed in.
 public BasicGetResult(RabbitMQ.Client.BasicGetResult result)
 {
     BasicProperties = result.BasicProperties;
     Body            = result.Body;
     DeliveryTag     = result.DeliveryTag;
     Exchange        = result.Exchange;
     MessageCount    = result.MessageCount;
     Redelivered     = result.Redelivered;
     RoutingKey      = result.RoutingKey;
 }
Example #4
0
        public void TestAck()
        {
            var config   = new ConfigurationBuilder().Build();
            var services = new ServiceCollection().BuildServiceProvider();
            var context  = new GenericApplicationContext(services, config);
            var channel  = new Mock <R.IModel>();

            channel.Setup(c => c.IsOpen).Returns(true);
            var props       = new MockRabbitBasicProperties();
            var getResponse = new R.BasicGetResult(123Ul, false, "ex", "rk", 0, props, Encoding.UTF8.GetBytes("foo"));

            channel.Setup(c => c.BasicGet("foo", false)).Returns(getResponse);
            var connection = new Mock <R.IConnection>();

            connection.Setup(c => c.IsOpen).Returns(true);
            connection.Setup(c => c.CreateModel()).Returns(channel.Object);
            var connectionFactory = new Mock <R.IConnectionFactory>();

            connectionFactory.Setup(f => f.CreateConnection(It.IsAny <string>())).Returns(connection.Object);

            var ccf    = new CachingConnectionFactory(connectionFactory.Object);
            var source = new RabbitMessageSource(context, ccf, "foo");

            source.RawMessageHeader = true;
            var received   = source.Receive();
            var rawMessage = received.Headers.Get <IMessage>(RabbitMessageHeaderErrorMessageStrategy.AMQP_RAW_MESSAGE);
            var sourceData = received.Headers.Get <IMessage>(IntegrationMessageHeaderAccessor.SOURCE_DATA);

            Assert.NotNull(rawMessage);
            Assert.Same(rawMessage, sourceData);
            Assert.Equal("foo", received.Headers.Get <string>(RabbitMessageHeaders.CONSUMER_QUEUE));

            // make sure channel is not cached
            var conn      = ccf.CreateConnection();
            var notCached = conn.CreateChannel(false);

            connection.Verify(c => c.CreateModel(), Times.Exactly(2));
            var callback = received.Headers.Get <IAcknowledgmentCallback>(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK);

            callback.Acknowledge(Status.ACCEPT);
            channel.Verify(c => c.BasicAck(123ul, false));
            var cached = conn.CreateChannel(false); // should have been "closed"

            connection.Verify(c => c.CreateModel(), Times.Exactly(2));
            notCached.Close();
            cached.Close();
            ccf.Destroy();
            channel.Verify(c => c.Close(), Times.Exactly(2));
            connection.Verify(c => c.Close(30000));
        }
Example #5
0
        public void TestBatch()
        {
            var bs      = new SimpleBatchingStrategy(2, 10_000, 10_000L);
            var headers = new RabbitHeaderAccessor();

            headers.ContentType = "test/plain";
            var message = Message.Create(Encoding.UTF8.GetBytes("test1"), headers.MessageHeaders);

            bs.AddToBatch("foo", "bar", message);
            message = Message.Create(Encoding.UTF8.GetBytes("test2"), headers.MessageHeaders);
            var batched = bs.AddToBatch("foo", "bar", message);

            Assert.True(batched.HasValue);
            var batchMessage    = batched.Value.Message;
            var batchHeaders    = batchMessage.Headers;
            var headerConverter = new DefaultMessageHeadersConverter();
            var props           = new MockRabbitBasicProperties();

            headerConverter.FromMessageHeaders(batchHeaders, props, Encoding.UTF8);
            props.ContentType = "text/plain";

            var config   = new ConfigurationBuilder().Build();
            var services = new ServiceCollection().BuildServiceProvider();
            var context  = new GenericApplicationContext(services, config);
            var channel  = new Mock <R.IModel>();

            channel.Setup(c => c.IsOpen).Returns(true);

            var getResponse = new R.BasicGetResult(123Ul, false, "ex", "rk", 0, props, (byte[])batchMessage.Payload);

            channel.Setup(c => c.BasicGet("foo", false)).Returns(getResponse);
            var connection = new Mock <R.IConnection>();

            connection.Setup(c => c.IsOpen).Returns(true);
            connection.Setup(c => c.CreateModel()).Returns(channel.Object);
            var connectionFactory = new Mock <R.IConnectionFactory>();

            connectionFactory.Setup(f => f.CreateConnection(It.IsAny <string>())).Returns(connection.Object);

            var ccf      = new CachingConnectionFactory(connectionFactory.Object);
            var source   = new RabbitMessageSource(context, ccf, "foo");
            var received = source.Receive();

            Assert.NotNull(received);
            var asList = received.Payload as List <object>;

            Assert.NotNull(asList);
            Assert.Contains("test1", asList);
            Assert.Contains("test2", asList);
        }
        public override void HandleBasicDeliver(
            string consumerTag, ulong deliveryTag, bool redelivered, string exchange,
            string routingKey, IBasicProperties properties, byte[] body)
        {
            var msgResult = new BasicGetResult(
                deliveryTag: deliveryTag,
                redelivered: redelivered,
                exchange: exchange,
                routingKey: routingKey,
                messageCount: 0, //Not available, received by RabbitMQ when declaring queue
                basicProperties: properties,
                body: body);

            queue.Enqueue(msgResult);
        }
Example #7
0
        private void TestNackOrRequeue(bool requeue)
        {
            var config   = new ConfigurationBuilder().Build();
            var services = new ServiceCollection().BuildServiceProvider();
            var context  = new GenericApplicationContext(services, config);

            var channel = new Mock <R.IModel>();

            channel.Setup(c => c.IsOpen).Returns(true);
            var props       = new MockRabbitBasicProperties();
            var getResponse = new R.BasicGetResult(123Ul, false, "ex", "rk", 0, props, Encoding.UTF8.GetBytes("bar"));

            channel.Setup(c => c.BasicGet("foo", false)).Returns(getResponse);
            var connection = new Mock <R.IConnection>();

            connection.Setup(c => c.IsOpen).Returns(true);
            connection.Setup(c => c.CreateModel()).Returns(channel.Object);
            var connectionFactory = new Mock <R.IConnectionFactory>();

            connectionFactory.Setup(f => f.CreateConnection(It.IsAny <string>())).Returns(connection.Object);

            var ccf      = new CachingConnectionFactory(connectionFactory.Object);
            var source   = new RabbitMessageSource(context, ccf, "foo");
            var received = source.Receive();

            connection.Verify(c => c.CreateModel());
            var callback = received.Headers.Get <IAcknowledgmentCallback>(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK);

            if (requeue)
            {
                callback.Acknowledge(Status.REQUEUE);
            }
            else
            {
                callback.Acknowledge(Status.REJECT);
            }

            channel.Verify(c => c.BasicReject(123ul, requeue));
            connection.Verify(c => c.CreateModel());
            ccf.Destroy();
            channel.Verify(c => c.Close());
            connection.Verify(c => c.Close(30000));
        }
Example #8
0
        protected void HandleReceivedMessage(IModel channel, SubscriptionConfiguration subscription, BasicGetResult result)
        {
            var messageProperties = BuildMessageProperties(channel, subscription, result.BasicProperties);

            ReceivedMessage message = null;
            try
            {
                OnMessageReceived(result.Body, result.Exchange, result.RoutingKey, messageProperties, out message);
            }
            catch (Exception e)
            {
                Logger.Log("Exception occureed while receiving message");
                Logger.Log("Message: " + e.Message);
                Logger.Log("Stacktrace: " + e.StackTrace);
                ErrorHandler.HandleError(message, EndpointName);
                if (ErrorHandler.ShouldRethrowExceptions(EndpointName)) throw;
            }
            finally
            {
                AckMessage(channel, result.DeliveryTag, subscription.NoAck, message);
            }
        }
Example #9
0
 public void ReadFromQueue(string queueName, Func <BasicGetResult, bool> action)
 {
     TryCreateConnectionFactory(null);
     if (factory == null)
     {
         //Retry?
         return;
     }
     try
     {
         using (var connection = factory.CreateConnection())
             using (var channel = connection.CreateModel())
             {
                 channel.QueueDeclare(queueName, true, false, false, null);
                 RabbitMQ.Client.BasicGetResult data = channel.BasicGet(queueName, false);
                 if (data == null)
                 {
                     return;           // queue is empty hence no message
                 }
                 // execute an action with the message from the queue.
                 // If the action succeeds, acknowledge receipt
                 // Otherwise non-acknowledge and resubmit message to queue
                 if (action.Invoke(data))
                 {
                     Log.Information("RabbitMq: ReadFromQueue - Message Acknowledged from queue {0}", queueName);
                     channel.BasicAck(data.DeliveryTag, false);
                 }
                 else
                 {
                     Log.Information("RabbitMq: ReadFromQueue - Message not Acknowledged from queue {0} and requeued", queueName);
                     channel.BasicNack(data.DeliveryTag, false, true);
                 }
             }
     }
     catch (Exception ex)
     {
         Log.Error(ex, "RabbitMq: ReadFromQueue(queueName = {0}, action) has thrown an exception", queueName);
     }
 }
 /// <summary>
 /// Handle basic deliver.
 /// </summary>
 /// <param name="consumerTag">
 /// The consumer tag.
 /// </param>
 /// <param name="deliveryTag">
 /// The delivery tag.
 /// </param>
 /// <param name="redelivered">
 /// The redelivered.
 /// </param>
 /// <param name="exchange">
 /// The exchange.
 /// </param>
 /// <param name="routingKey">
 /// The routing key.
 /// </param>
 /// <param name="properties">
 /// The properties.
 /// </param>
 /// <param name="body">
 /// The body.
 /// </param>
 public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body)
 {
     // TODO: Validate that 1 is the right message count.
     var envelope = new BasicGetResult(deliveryTag, redelivered, exchange, routingKey, 1, properties, body);
     this.HandleBasicDeliver(consumerTag, envelope, properties, body);
 }
 /// <summary>
 /// Handle basic deliver.
 /// </summary>
 /// <param name="consumerTag">
 /// The consumer tag.
 /// </param>
 /// <param name="envelope">
 /// The envelope.
 /// </param>
 /// <param name="properties">
 /// The properties.
 /// </param>
 /// <param name="body">
 /// The body.
 /// </param>
 public void HandleBasicDeliver(string consumerTag, BasicGetResult envelope, IBasicProperties properties, byte[] body)
 {
     if (this.outer.cancelled)
     {
         if (this.outer.acknowledgeMode.TransactionAllowed())
         {
             return;
         }
     }
     if (this.logger.IsDebugEnabled)
     {
         this.logger.Debug("Storing delivery for " + this.outer.ToString());
     }
     try
     {
         // N.B. we can't use a bounded queue and offer() here with a timeout
         // in case the connection thread gets blocked
         this.outer.queue.Add(new Delivery(envelope, properties, body));
     }
     catch (ThreadInterruptedException e)
     {
         Thread.CurrentThread.Interrupt();
     }
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="Delivery"/> class.
 /// </summary>
 /// <param name="envelope">
 /// The envelope.
 /// </param>
 /// <param name="properties">
 /// The properties.
 /// </param>
 /// <param name="body">
 /// The body.
 /// </param>
 public Delivery(BasicGetResult envelope, IBasicProperties properties, byte[] body)
 {
     this.envelope = envelope;
     this.properties = properties;
     this.body = body;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="RabbitWorkMessage" /> class.
 /// </summary>
 /// <param name="queue">The queue.</param>
 /// <param name="evt">The evt.</param>
 public RabbitWorkMessage(RabbitWorkQueue queue, RabbitMQ.Client.BasicGetResult evt)
 {
     _queue = queue;
     _msg2  = evt;
 }
Example #14
0
        /// <summary>
        /// Create MessageProperties.
        /// </summary>
        /// <param name="source">
        /// The source.
        /// </param>
        /// <param name="envelope">
        /// The envelope.
        /// </param>
        /// <param name="charset">
        /// The charset.
        /// </param>
        /// <returns>
        /// The MessageProperties.
        /// </returns>
        /// <exception cref="AmqpUnsupportedEncodingException">
        /// </exception>
        public static MessageProperties CreateMessageProperties(IBasicProperties source, BasicGetResult envelope, string charset)
        {
            var target = new MessageProperties();
            var headers = source.Headers;
            if (!CollectionUtils.IsEmpty(headers))
            {
                foreach (DictionaryEntry entry in headers)
                {
                    target.Headers[entry.Key] = entry.Value;
                }
            }

            target.Timestamp = source.Timestamp.ToDateTime();
            target.MessageId = source.MessageId;
            target.UserId = source.UserId;
            target.AppId = source.AppId;
            target.ClusterId = source.ClusterId;
            target.Type = source.Type;
            target.DeliveryMode = (MessageDeliveryMode)source.DeliveryMode;
            target.Expiration = source.Expiration;
            target.Priority = source.Priority;
            target.ContentType = source.ContentType;
            target.ContentEncoding = source.ContentEncoding;
            var correlationId = source.CorrelationId;
            if (correlationId != null)
            {
                try
                {
                    // TODO: Get the encoding from the ContentEncoding string.
                    target.CorrelationId = Encoding.UTF8.GetBytes(source.CorrelationId);
                }
                catch (Exception ex)
                {
                    throw new AmqpUnsupportedEncodingException(ex);
                }
            }

            var replyTo = source.ReplyTo;
            if (replyTo != null)
            {
                target.ReplyTo = new Address(replyTo);
            }

            if (envelope != null)
            {
                target.ReceivedExchange = envelope.Exchange;
                target.ReceivedRoutingKey = envelope.RoutingKey;
                target.Redelivered = envelope.Redelivered;
                target.DeliveryTag = (long)envelope.DeliveryTag;
            }

            return target;
        }
        [Test] // AMQP-249
        public void DontHangConsumerThread()
        {
            var mockConnectionFactory = new Mock<ConnectionFactory>();
            var mockConnection = new Mock<IConnection>();
            var mockChannel = new Mock<IModel>();

            mockConnectionFactory.Setup(m => m.CreateConnection()).Returns(mockConnection.Object);
            mockConnection.Setup(m => m.IsOpen).Returns(true);
            mockConnection.Setup(m => m.CreateModel()).Returns(mockChannel.Object);
            mockChannel.Setup(m => m.QueueDeclare()).Returns(new QueueDeclareOk("foo", 0, 0));
            mockChannel.Setup(m => m.CreateBasicProperties()).Returns(() => new BasicProperties());

            var consumer = new AtomicReference<DefaultBasicConsumer>();
            mockChannel.Setup(m => m.BasicConsume(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<IDictionary>(), It.IsAny<IBasicConsumer>())).Callback
                <string, bool, string, bool, bool, IDictionary, IBasicConsumer>(
                    (a1, a2, a3, a4, a5, a6, a7) => consumer.LazySet((DefaultBasicConsumer)a7));

            var template = new RabbitTemplate(new SingleConnectionFactory(mockConnectionFactory.Object));
            template.ReplyTimeout = 1;
            var input = new Message(Encoding.UTF8.GetBytes("Hello, world!"), new MessageProperties());
            var doSendAndReceiveWithTemporaryMethod = typeof(RabbitTemplate).GetMethod("DoSendAndReceiveWithTemporary", BindingFlags.NonPublic | BindingFlags.Instance);
            doSendAndReceiveWithTemporaryMethod.Invoke(template, new object[] { "foo", "bar", input });
            var envelope = new BasicGetResult(1, false, "foo", "bar", 0, new BasicProperties(), null);

            // used to hang here because of the SynchronousQueue and DoSendAndReceive() already exited
            consumer.Value.HandleBasicDeliver("foo", envelope.DeliveryTag, envelope.Redelivered, envelope.Exchange, envelope.RoutingKey, new BasicProperties(), new byte[0]);
        }
        public void DequeueReturnsMessageTest()
        {
            var connFactory = Substitute.For<IConnectionFactory>();
            var conn = Substitute.For<IConnection>();
            var model = Substitute.For<IModel>();

            var queueName = Guid.NewGuid().ToString();

            connFactory.CreateConnection().Returns(conn);
            connFactory.CreateConnection(string.Empty).ReturnsForAnyArgs(conn);
            conn.CreateModel().Returns(model);
            conn.IsOpen.Returns(true);
            model.IsClosed.Returns(false);
            model.QueueDeclare(null, false, false, false, null).ReturnsForAnyArgs(new QueueDeclareOk(queueName, 1, 0));
            model.QueueDeclarePassive(null).ReturnsForAnyArgs(new QueueDeclareOk(string.Empty, 1, 0));
            model.MessageCount(null).ReturnsForAnyArgs(x => 1u);

            var payload = Guid.NewGuid().ToByteArray();
            var result = new BasicGetResult(0, false, null, null, 0, null, payload);
            model.BasicGet(queueName, false).Returns(result);

            var setup = new RabbitMQReaderSetup
            {
                ConnectionFactory = connFactory,
                Exchange = Constants.DefaultExchange,
                QueueName = queueName,
                IsDurable = false,
                DeleteQueueOnClose = true,
                QueueTimeToLive = TimeSpan.FromMinutes(20),
                Options = new RabbitMQReaderOptions(),
            };
            using (var rdr = new RabbitMQReader(setup, false))
            {
                var msg = rdr.Dequeue(TimeSpan.FromSeconds(30), CancellationToken.None);
                Assert.Equal(payload, msg.Body.CopyToByteArray());
            }
        }
 /// <summary>Handle basic deliver.</summary>
 /// <param name="consumerTag">The consumer tag.</param>
 /// <param name="deliveryTag">The delivery tag.</param>
 /// <param name="redelivered">The redelivered.</param>
 /// <param name="exchange">The exchange.</param>
 /// <param name="routingKey">The routing key.</param>
 /// <param name="properties">The properties.</param>
 /// <param name="body">The body.</param>
 public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body)
 {
     var envelope = new BasicGetResult(deliveryTag, redelivered, exchange, routingKey, 1, properties, body);
     this.HandleBasicDeliver(consumerTag, envelope, properties, body);
 }
        public void Setup()
        {
            TaskUtil.Await(async () =>
            {
                var connectionFactory = _host.Settings.GetConnectionFactory();
                using (var connection = connectionFactory.CreateConnection())
                using (var model = connection.CreateModel())
                {
                    byte[] bytes = Encoding.UTF8.GetBytes("[]");

                    model.BasicPublish("input_queue", "", model.CreateBasicProperties(), bytes);

                    await Task.Delay(3000).ConfigureAwait(false);

                    _basicGetResult = model.BasicGet("input_queue_error", true);

                    _body = Encoding.UTF8.GetString(_basicGetResult.Body);

                    model.Close(200, "Cleanup complete");
                    connection.Close(200, "Cleanup complete");
                }
            });
        }
Example #19
0
 protected void SetupModelBasicGet(QueueEndpoint endPoint, BasicGetResult result)
 {
     Model.Stub(x => x.BasicGet(endPoint.RoutingKey, false)).Return(result);
 }