Exemple #1
0
        private async Task RunMessageProcessorAsync()
        {
            do
            {
                if (CancellationToken.IsCancellationRequested)
                {
                    break;
                }

                if (_receiverLink == null || _receiverLink.IsClosed)
                {
                    await InitializeAsync().ConfigureAwait(false);
                }

                try
                {
                    using (var message = await _receiverLink.ReceiveAsync(TimeSpan.FromSeconds(10)).ConfigureAwait(false))
                    {
                        if (message != null)
                        {
                            try
                            {
                                await _messenger.ProcessMessageAsync(Address, (string)message.Body).ConfigureAwait(false);

                                _receiverLink.Accept(message);
                            }
                            catch (RescheduleException)
                            {
                                // no log, this is "wanted"

                                _receiverLink.Release(message);
                            }
                            catch (Exception exception)
                            {
                                Console.WriteLine($"Exception during processing AMQP message, rejecting: {exception}");

                                _receiverLink.Release(message);
                            }
                        }
                    }
                }
                catch (AmqpException e)
                {
                    if (!CancellationToken.IsCancellationRequested)
                    {
                        Console.WriteLine($"AMQP exception in receiver link for address {Address}: {e}");
                    }

                    await CloseAsync().ConfigureAwait(false);
                }
            } while (!CancellationToken.IsCancellationRequested);

            // normal end

            await CloseAsync().ConfigureAwait(false);
        }
Exemple #2
0
        public void Acknowledge(InboundMessageDispatch envelope, AckType ackType)
        {
            if (envelope.Message.Facade is AmqpNmsMessageFacade facade)
            {
                global::Amqp.Message message = facade.Message;
                switch (ackType)
                {
                case AckType.DELIVERED:
                    envelope.IsDelivered = true;
                    break;

                case AckType.ACCEPTED:
                    HandleAccepted(envelope, message);
                    break;

                case AckType.RELEASED:
                    receiverLink.Release(message);
                    RemoveMessage(envelope);
                    break;

                case AckType.MODIFIED_FAILED_UNDELIVERABLE:
                    receiverLink.Modify(message, true, true);
                    RemoveMessage(envelope);
                    break;

                default:
                    Tracer.ErrorFormat("Unsupported Ack Type for message: {0}", envelope);
                    throw new ArgumentException($"Unsupported Ack Type for message: {envelope}");
                }
            }
            else
            {
                Tracer.ErrorFormat($"Received Ack for unknown message: {envelope}");
            }
        }
        public void ContainerHostMessageSourceTest()
        {
            string          name     = "ContainerHostMessageSourceTest";
            int             count    = 100;
            Queue <Message> messages = new Queue <Message>();

            for (int i = 0; i < count; i++)
            {
                messages.Enqueue(new Message("test")
                {
                    Properties = new Properties()
                    {
                        MessageId = name + i
                    }
                });
            }

            var source = new TestMessageSource(messages);

            this.host.RegisterMessageSource(name, source);

            var connection = new Connection(Address);
            var session    = new Session(connection);
            var receiver   = new ReceiverLink(session, "receiver0", name);
            int released   = 0;
            int rejected   = 0;
            int ignored    = 0;

            for (int i = 1; i <= count; i++)
            {
                Message message = receiver.Receive();
                if (i % 5 == 0)
                {
                    receiver.Reject(message);
                    rejected++;
                }
                else if (i % 17 == 0)
                {
                    receiver.Release(message);
                    released++;
                }
                else if (i % 36 == 0)
                {
                    ignored++;
                }
                else
                {
                    receiver.Accept(message);
                }
            }

            receiver.Close();
            session.Close();
            connection.Close();

            Thread.Sleep(500);
            Assert.AreEqual(released + ignored, messages.Count, string.Join(",", messages.Select(m => m.Properties.MessageId)));
            Assert.AreEqual(rejected, source.DeadletterMessage.Count, string.Join(",", source.DeadletterMessage.Select(m => m.Properties.MessageId)));
        }
        public void ContainerHostSourceLinkEndpointTest()
        {
            string          name     = "ContainerHostSourceLinkEndpointTest";
            int             count    = 100;
            Queue <Message> messages = new Queue <Message>();

            for (int i = 0; i < count; i++)
            {
                messages.Enqueue(new Message("test")
                {
                    Properties = new Properties()
                    {
                        MessageId = name + i
                    }
                });
            }

            var source = new TestMessageSource(messages);

            this.linkProcessor = new TestLinkProcessor(link => new SourceLinkEndpoint(source, link));
            this.host.RegisterLinkProcessor(this.linkProcessor);

            var connection = new Connection(Address);
            var session    = new Session(connection);
            var receiver   = new ReceiverLink(session, "receiver0", name);
            int released   = 0;
            int rejected   = 0;

            for (int i = 1; i <= count; i++)
            {
                Message message = receiver.Receive();
                if (i % 5 == 0)
                {
                    receiver.Reject(message);
                    rejected++;
                }
                else if (i % 17 == 0)
                {
                    receiver.Release(message);
                    released++;
                }
                else
                {
                    receiver.Accept(message);
                }
            }

            receiver.Close();
            session.Close();
            connection.Close();

            Thread.Sleep(200);
            Assert.AreEqual(released, messages.Count);
            Assert.AreEqual(rejected, source.DeadletterMessage.Count);
        }
        public void TestMethod_ReleaseMessage()
        {
            string     testName   = "ReleaseMessage";
            const int  nMsgs      = 20;
            Connection connection = new Connection(address);
            Session    session    = new Session(connection);

            SenderLink sender = new SenderLink(session, "sender-" + testName, "q1");

            for (int i = 0; i < nMsgs; ++i)
            {
                Message message = new Message();
                message.Properties = new Properties()
                {
                    MessageId = "msg" + i
                };
                message.ApplicationProperties       = new ApplicationProperties();
                message.ApplicationProperties["sn"] = i;
                sender.Send(message, null, null);
            }

            ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "q1");

            for (int i = 0; i < nMsgs; ++i)
            {
                Message message = receiver.Receive();
                Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
                if (i % 2 == 0)
                {
                    receiver.Accept(message);
                }
                else
                {
                    receiver.Release(message);
                }
            }
            receiver.Close();

            ReceiverLink receiver2 = new ReceiverLink(session, "receiver2-" + testName, "q1");

            for (int i = 0; i < nMsgs / 2; ++i)
            {
                Message message = receiver2.Receive();
                Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
                receiver2.Accept(message);
            }

            receiver2.Close();
            sender.Close();
            session.Close();
            connection.Close();
        }
Exemple #6
0
        /// <summary>
        /// Receive messages from specified azure iothub on specified partition. The MessageManager parses the received message and displays it accordingly
        /// </summary>
        /// <param name="partition"></param>
        /// <param name="offset"></param>
        /// <param name="msgman"></param>
        /// <param name="hubData"></param>
        /// <returns></returns>
        public static async Task ReceiveMessages(string partition, DateTime offset, MessageManager msgman, IoTAccountData hubData)
        {
            string port = hubData.EventHubInfo.EventHubPort.Replace("sb://", "");

            port = port.Replace("/", "");
            Address    address    = new Address(port, 5671, hubData.SharedAccessPolicy, hubData.PrimaryKey, "/", "amqps");
            Connection connection = await Connection.Factory.CreateAsync(address);

            Session session           = new Session(connection);
            string  totalMilliseconds = ((long)(offset - new DateTime(StartOfEpoch, DateTimeKind.Utc)).TotalMilliseconds).ToString();
            Map     filters           = new Map();

            filters.Add(new Amqp.Types.Symbol("apache.org:selector-filter:string"),
                        new DescribedValue(
                            new Amqp.Types.Symbol("apache.org:selector-filter:string"),
                            "amqp.annotation.x-opt-enqueuedtimeutc > " + totalMilliseconds + ""));
            ReceiverLink receiver = new ReceiverLink(session,
                                                     "my-receiver",
                                                     new global::Amqp.Framing.Source()
            {
                Address =
                    hubData.EventHubInfo.EventHubEntity + "/ConsumerGroups/$Default/Partitions/" + partition,
                FilterSet = filters
            }, null);

            Amqp.Types.Symbol deviceIdKey = new Amqp.Types.Symbol("iothub-connection-device-id");
            string            deviceId    = hubData.DeviceName;

            while (true)
            {
                Amqp.Message m = await receiver.ReceiveAsync(10000);

                if (m != null)
                {
                    var id = m.MessageAnnotations.Map[deviceIdKey].ToString();
                    if (id == deviceId)
                    {
                        Data   data    = (Data)m.BodySection;
                        string msg     = System.Text.Encoding.UTF8.GetString(data.Binary, 0, data.Binary.Length);
                        bool   isValid = msgman.parseMessage(msg);
                        if (isValid)
                        {
                            receiver.Accept(m);
                        }
                        else
                        {
                            receiver.Release(m);
                        }
                    }
                }
            }
        }
Exemple #7
0
        public void Acknowledge(InboundMessageDispatch envelope, AckType ackType)
        {
            if (envelope.Message.Facade is AmqpNmsMessageFacade facade)
            {
                global::Amqp.Message message = facade.Message;
                switch (ackType)
                {
                case AckType.DELIVERED:
                    envelope.IsDelivered = true;
                    break;

                case AckType.ACCEPTED:
                    AmqpTransactionContext transactionalState = session.TransactionContext;
                    if (transactionalState != null)
                    {
                        receiverLink.Complete(message, transactionalState.GetTxnAcceptState());
                        transactionalState.RegisterTxConsumer(this);
                    }
                    else
                    {
                        receiverLink.Accept(message);
                    }
                    RemoveMessage(envelope);
                    break;

                case AckType.RELEASED:
                    receiverLink.Release(message);
                    RemoveMessage(envelope);
                    break;

                case AckType.MODIFIED_FAILED_UNDELIVERABLE:
                    receiverLink.Modify(message, true, true);
                    RemoveMessage(envelope);
                    break;

                default:
                    Tracer.Error($"Unsupported Ack Type for message: {envelope.Message}");
                    throw new ArgumentException($"Unsupported Ack Type for message: {envelope.Message}");
                }
            }
            else
            {
                Tracer.ErrorFormat($"Received Ack for unknown message: {envelope}");
            }
        }
Exemple #8
0
        public void TestMethod_MessageDeliveryRelease()
        {
            string     testName   = "MessageDeliveryRelease";
            Connection connection = new Connection(testTarget.Address);
            Session    session    = new Session(connection);
            SenderLink sender     = new SenderLink(session, "sender-" + testName, testTarget.Path);
            Message    message    = new Message("msg release");

            sender.Send(message, null, null);

            ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);

            message = receiver.Receive();
            MessageDelivery messageDelivery = message.GetDelivery();

            message.Dispose();
            receiver.Release(messageDelivery);
            connection.Close();
        }
        public void TransactedRetiring()
        {
            if (enabled)
            {
                string testName = "TransactedRetiring";
                path = "test." + testName;
                int nMsgs = 10;
                var ids   = new List <string>();

                Connection connection = new Connection(address);
                Session    session    = new Session(connection);
                SenderLink sender     = new SenderLink(session, "sender-" + testName, path);

                // send one extra for validation
                for (int i = 0; i < nMsgs + 1; i++)
                {
                    Message message = new Message("test");
                    message.Properties = new Properties()
                    {
                        MessageId = "msg" + i, GroupId = testName
                    };
                    ids.Add(message.Properties.MessageId);
                    sender.Send(message);
                }

                ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, path);
                Message[]    messages = new Message[nMsgs];
                for (int i = 0; i < nMsgs; i++)
                {
                    messages[i] = receiver.Receive();
                    Trace.WriteLine(TraceLevel.Information, "receive: {0}", messages[i].Properties.MessageId);
                }

                // commit half
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) {
                    for (int i = 0; i < nMsgs / 2; i++)
                    {
                        receiver.Accept(messages[i]);
                        ids.Remove(messages[i].Properties.MessageId);
                    }

                    ts.Complete();
                }

                // rollback
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) {
                    for (int i = nMsgs / 2; i < nMsgs; i++)
                    {
                        receiver.Accept(messages[i]);
                    }
                }

                // after rollback, messages should be still acquired
                {
                    Message message = receiver.Receive();
                    Assert.Contains(message.Properties.MessageId, ids);
                    receiver.Release(message);
                }

                // commit
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) {
                    for (int i = nMsgs / 2; i < nMsgs; i++)
                    {
                        receiver.Accept(messages[i]);
                        ids.Remove(messages[i].Properties.MessageId);
                    }

                    ts.Complete();
                }

                // only the last message is left
                {
                    Message message = receiver.Receive();
                    receiver.Accept(message);
                    ids.Remove(message.Properties.MessageId);
                }

                // at this point, the queue should have zero messages.
                // If there are messages, it is a bug in the broker.
                Assert.Empty(ids);

                // shouldn't be any messages left
                Message empty = receiver.Receive(TimeSpan.Zero);
                Assert.Null(empty);

                connection.Close();
            }
        }
        public void TransactedRetiringAndPosting()
        {
            if (enabled)
            {
                string testName = "TransactedRetiringAndPosting";
                path = "test." + testName;
                int nMsgs = 10;
                var ids   = new List <string>();

                Connection connection = new Connection(address);
                Session    session    = new Session(connection);

                SenderLink sender = new SenderLink(session, "sender-" + testName, path);

                for (int i = 0; i < nMsgs; i++)
                {
                    Message message = new Message("test")
                    {
                        Properties = new Properties()
                        {
                            MessageId = "msg" + i,
                            GroupId   = testName
                        }
                    };
                    ids.Add(message.Properties.MessageId);
                    sender.Send(message);
                }

                ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, path);

                receiver.SetCredit(2, false);
                Message message1 = receiver.Receive();
                Message message2 = receiver.Receive();

                // ack message1 and send a new message in a txn
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) {
                    receiver.Accept(message1);
                    ids.Remove(message1.Properties.MessageId);

                    Message message = new Message("test");
                    message.Properties = new Properties()
                    {
                        MessageId = "msg" + nMsgs, GroupId = testName
                    };
                    ids.Add(message.Properties.MessageId);
                    sender.Send(message);

                    ts.Complete();
                }

                // ack message2 and send a new message in a txn but abort the txn
                using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) {
                    receiver.Accept(message2);

                    Message message = new Message("test");
                    message.Properties = new Properties()
                    {
                        MessageId = "msg" + (nMsgs + 1), GroupId = testName
                    };
                    sender.Send(message1);
                }

                // release the message, since it shouldn't have been accepted above
                receiver.Release(message2);

                // receive all messages. should see the effect of the first txn
                receiver.SetCredit(nMsgs, false);
                for (int i = 1; i <= nMsgs; i++)
                {
                    Message message = receiver.Receive();
                    Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
                    receiver.Accept(message);

                    Assert.Contains(message.Properties.MessageId, ids);
                    ids.Remove(message.Properties.MessageId);
                }

                // at this point, the queue should have zero messages.
                // If there are messages, it is a bug in the broker.
                Assert.Empty(ids);

                // shouldn't be any messages left
                Message empty = receiver.Receive(TimeSpan.Zero);
                Assert.Null(empty);

                connection.Close();
            }
        }
Exemple #11
0
        public void TransactedRetiringAndPosting()
        {
            string testName = "TransactedRetiringAndPosting";
            int    nMsgs    = 10;

            Connection connection = new Connection(testTarget.Address);
            Session    session    = new Session(connection);
            SenderLink sender     = new SenderLink(session, "sender-" + testName, testTarget.Path);

            for (int i = 0; i < nMsgs; i++)
            {
                Message message = new Message("test");
                message.Properties = new Properties()
                {
                    MessageId = "msg" + i, GroupId = testName
                };
                sender.Send(message);
            }

            ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);

            receiver.SetCredit(2, false);
            Message message1 = receiver.Receive();
            Message message2 = receiver.Receive();

            // ack message1 and send a new message in a txn
            using (var ts = new TransactionScope())
            {
                receiver.Accept(message1);

                Message message = new Message("test");
                message.Properties = new Properties()
                {
                    MessageId = "msg" + nMsgs, GroupId = testName
                };
                sender.Send(message);

                ts.Complete();
            }

            // ack message2 and send a new message in a txn but abort the txn
            using (var ts = new TransactionScope())
            {
                receiver.Accept(message2);

                Message message = new Message("test");
                message.Properties = new Properties()
                {
                    MessageId = "msg" + (nMsgs + 1), GroupId = testName
                };
                sender.Send(message1);
            }

            receiver.Release(message2);

            // receive all messages. should see the effect of the first txn
            receiver.SetCredit(nMsgs, false);
            for (int i = 1; i <= nMsgs; i++)
            {
                Message message = receiver.Receive();
                Trace.WriteLine(TraceLevel.Information, "receive: {0}", message.Properties.MessageId);
                receiver.Accept(message);
                Assert.AreEqual("msg" + i, message.Properties.MessageId);
            }

            connection.Close();
        }
Exemple #12
0
        public void TransactedRetiring()
        {
            string testName = "TransactedRetiring";
            int    nMsgs    = 10;

            Connection connection = new Connection(testTarget.Address);
            Session    session    = new Session(connection);
            SenderLink sender     = new SenderLink(session, "sender-" + testName, testTarget.Path);

            // send one extra for validation
            for (int i = 0; i < nMsgs + 1; i++)
            {
                Message message = new Message("test");
                message.Properties = new Properties()
                {
                    MessageId = "msg" + i, GroupId = testName
                };
                sender.Send(message);
            }

            ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);

            Message[] messages = new Message[nMsgs];
            for (int i = 0; i < nMsgs; i++)
            {
                messages[i] = receiver.Receive();
                Trace.WriteLine(TraceLevel.Information, "receive: {0}", messages[i].Properties.MessageId);
            }

            // commit half
            using (var ts = new TransactionScope())
            {
                for (int i = 0; i < nMsgs / 2; i++)
                {
                    receiver.Accept(messages[i]);
                }

                ts.Complete();
            }

            // rollback
            using (var ts = new TransactionScope())
            {
                for (int i = nMsgs / 2; i < nMsgs; i++)
                {
                    receiver.Accept(messages[i]);
                }
            }

            // after rollback, messages should be still acquired
            {
                Message message = receiver.Receive();
                Assert.AreEqual("msg" + nMsgs, message.Properties.MessageId);
                receiver.Release(message);
            }

            // commit
            using (var ts = new TransactionScope())
            {
                for (int i = nMsgs / 2; i < nMsgs; i++)
                {
                    receiver.Accept(messages[i]);
                }

                ts.Complete();
            }

            // only the last message is left
            {
                Message message = receiver.Receive();
                Assert.AreEqual("msg" + nMsgs, message.Properties.MessageId);
                receiver.Accept(message);
            }

            // at this point, the queue should have zero messages.
            // If there are messages, it is a bug in the broker.

            connection.Close();
        }
Exemple #13
0
        public static void Main(string[] args)
        {
            Trace.TraceLevel    = TraceLevel.Frame;
            Trace.TraceListener = (f, a) =>
            {
                var t = DateTime.Now.ToString("[hh:ss.fff]") + " " + string.Format(f, a);
                Console.WriteLine(t);
            };

            connection = new Connection(amqpAddress, null, new Open()
            {
                ContainerId  = Guid.NewGuid().ToString(),
                ChannelMax   = 64,
                MaxFrameSize = 200,
            }, null);
            connection.Closed = OnClosed;

            session        = new Session(connection);
            session.Closed = OnClosed;

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

            senderLink = new SenderLink(session, linkName, new Attach()
            {
                Target = new Target()
                {
                    Address = "TestQueue1",
                },
                //RcvSettleMode = ReceiverSettleMode.Second,
                //SndSettleMode = SenderSettleMode.Settled,
            }, null);
            senderLink.Closed = OnClosed;

            for (int i = 0; i < 10; i++)
            {
                senderLink.Send(CreateMessage(), 5000);
            }

            senderLink.Close();

            linkName            = Guid.NewGuid().ToString();
            receiverLink        = new ReceiverLink(session, linkName, "TestQueue1");
            receiverLink.Closed = OnClosed;
            receiverLink.SetCredit(1);
            var message      = receiverLink.Receive(20000);
            int receiveCount = 0;

            while (message != null)
            {
                receiveCount++;
                //Console.WriteLine(message.Body.GetType());
                Console.WriteLine(message.BodySection.GetType());
                Console.WriteLine("Receive #{0}. Message = \"{1}\"", receiveCount.ToString(), Encoding.UTF8.GetString(message.GetBody <byte[]>()));
                if (receiveCount % 7 == 0)
                {
                    receiverLink.Release(message);
                }
                else if (receiveCount % 4 == 0)
                {
                    receiverLink.Reject(message);
                }
                else
                {
                    receiverLink.Accept(message);
                }
                Thread.Sleep(10000);
                message = receiverLink.Receive(20000);
            }
            receiverLink.Close();

            session.Close();
            connection.Close();
        }