public async Task TestIncomingExpiredMessageGetsFilteredAsync()
        {
            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                IConnection connection = await EstablishConnectionAsync(testPeer);

                await connection.StartAsync();

                testPeer.ExpectBegin();

                ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge);

                IQueue queue = await session.GetQueueAsync("myQueue");

                // Expected the consumer to attach and send credit, then send it an
                // already-expired message followed by a live message.
                testPeer.ExpectReceiverAttach();

                string       expiredMsgContent = "already-expired";
                Amqp.Message message           = CreateExpiredMessage(expiredMsgContent);
                testPeer.ExpectLinkFlowRespondWithTransfer(message: message);

                string liveMsgContent = "valid";
                testPeer.SendTransferToLastOpenedLinkOnLastOpenedSession(message: new Amqp.Message()
                {
                    BodySection = new AmqpValue()
                    {
                        Value = liveMsgContent
                    }
                }, nextIncomingId: 2);

                IMessageConsumer consumer = await session.CreateConsumerAsync(queue);

                // Add message listener, expect the first message to be filtered due to expiry,
                // and the second message to be given to the test app and accepted.
                Action <DeliveryState> modifiedMatcher = state =>
                {
                    var modified = state as Modified;
                    Assert.IsNotNull(modified);
                    Assert.IsTrue(modified.DeliveryFailed);
                    Assert.IsTrue(modified.UndeliverableHere);
                };
                testPeer.ExpectDisposition(settled: true, stateMatcher: modifiedMatcher, firstDeliveryId: 1, lastDeliveryId: 1);
                testPeer.ExpectDisposition(settled: true, stateMatcher: Assert.IsInstanceOf <Accepted>, firstDeliveryId: 2, lastDeliveryId: 2);


                ManualResetEvent success         = new ManualResetEvent(false);
                ManualResetEvent listenerFailure = new ManualResetEvent(false);

                consumer.Listener += m =>
                {
                    if (liveMsgContent.Equals(((ITextMessage)m).Text))
                    {
                        success.Set();
                    }
                    else
                    {
                        listenerFailure.Set();
                    }
                };

                Assert.True(success.WaitOne(TimeSpan.FromSeconds(5)), "didn't get expected message");
                Assert.False(listenerFailure.WaitOne(TimeSpan.FromMilliseconds(100)), "Received message when message should not have been received");

                testPeer.WaitForAllMatchersToComplete(3000);

                testPeer.ExpectClose();
                await connection.CloseAsync();

                testPeer.WaitForAllMatchersToComplete(3000);
            }
        }
        public void TestFailoverHandlesDropThenRejectionCloseAfterConnect()
        {
            using (TestAmqpPeer originalPeer = new TestAmqpPeer())
                using (TestAmqpPeer rejectingPeer = new TestAmqpPeer())
                    using (TestAmqpPeer finalPeer = new TestAmqpPeer())
                    {
                        ManualResetEvent originalConnected = new ManualResetEvent(false);
                        ManualResetEvent finalConnected    = new ManualResetEvent(false);

                        // Create a peer to connect to, one to fail to reconnect to, and a final one to reconnect to
                        var originalUri  = CreatePeerUri(originalPeer);
                        var rejectingUri = CreatePeerUri(rejectingPeer);
                        var finalUri     = CreatePeerUri(finalPeer);

                        // Connect to the first
                        originalPeer.ExpectSaslAnonymous();
                        originalPeer.ExpectOpen();
                        originalPeer.ExpectBegin();

                        long     ird   = 0;
                        long     rd    = 2000;
                        DateTime start = DateTime.UtcNow;

                        NmsConnection connection = EstablishAnonymousConnection("failover.initialReconnectDelay=" + ird + "&failover.reconnectDelay=" + rd + "&failover.maxReconnectAttempts=10", originalPeer,
                                                                                rejectingPeer, finalPeer);

                        Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>();

                        connectionListener
                        .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString())))
                        .Callback(() => { originalConnected.Set(); });

                        connectionListener
                        .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString())))
                        .Callback(() => { finalConnected.Set(); });

                        connection.AddConnectionListener(connectionListener.Object);

                        connection.Start();

                        Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer");
                        Assert.False(finalConnected.WaitOne(TimeSpan.FromMilliseconds(100)), "Should not yet have connected to final peer");

                        // Set expectations on rejecting and final peer
                        rejectingPeer.RejectConnect(AmqpError.NOT_FOUND, "Resource could not be located");

                        finalPeer.ExpectSaslAnonymous();
                        finalPeer.ExpectOpen();
                        finalPeer.ExpectBegin();

                        // Close the original peer and wait for things to shake out.
                        originalPeer.Close(sendClose: false);

                        rejectingPeer.WaitForAllMatchersToComplete(2000);

                        Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer");
                        DateTime end = DateTime.UtcNow;

                        long margin = 2000;

                        // TODO: It is failing because, we are not handling rejected connection properly, when socket connection is established
                        // but broker replies with amqp:connection-establishment-failed. Initially connection is treated as successful, which resets
                        // the attempts counter. As a result next connect attempt is being made without any delay.
                        // Assert.That((end - start).TotalMilliseconds, Is.GreaterThanOrEqualTo(ird + rd).And.LessThanOrEqualTo(ird + rd + margin), "Elapsed time outwith expected range for reconnect");

                        finalPeer.ExpectClose();
                        connection.Close();

                        finalPeer.WaitForAllMatchersToComplete(1000);
                    }
        }
Example #3
0
        public async Task TestAcknowledgeIndividualMessagesAsync()
        {
            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                int msgCount = 6;

                IConnection connection = await EstablishConnectionAsync(testPeer);

                await connection.StartAsync();

                testPeer.ExpectBegin();
                ISession session = await connection.CreateSessionAsync(AcknowledgementMode.IndividualAcknowledge);

                IQueue queue = await session.GetQueueAsync("myQueue");

                testPeer.ExpectReceiverAttach();
                testPeer.ExpectLinkFlowRespondWithTransfer(
                    message: CreateMessageWithNullContent(),
                    count: msgCount,
                    drain: false,
                    nextIncomingId: 1,
                    addMessageNumberProperty: true,
                    sendDrainFlowResponse: false,
                    sendSettled: false,
                    creditMatcher: credit => Assert.Greater(credit, msgCount));

                IMessageConsumer consumer = await session.CreateConsumerAsync(queue);

                CountdownEvent      latch    = new CountdownEvent(msgCount);
                List <ITextMessage> messages = new List <ITextMessage>();
                consumer.Listener += message =>
                {
                    messages.Add((ITextMessage)message);
                    latch.Signal();
                };

                Assert.True(latch.Wait(TimeSpan.FromMilliseconds(1000)), $"Should receive: {msgCount}, but received: {messages.Count}");

                Action <DeliveryState> dispositionMatcher = state => { Assert.AreEqual(state.Descriptor.Code, MessageSupport.ACCEPTED_INSTANCE.Descriptor.Code); };

                // Acknowledge the messages in a random order and verify the individual dispositions have expected delivery state.
                Random random = new Random();
                for (int i = 0; i < msgCount; i++)
                {
                    var message = messages[random.Next(msgCount - i)];
                    messages.Remove(message);

                    uint deliveryNumber = (uint)message.Properties.GetInt(TestAmqpPeer.MESSAGE_NUMBER) + 1;

                    testPeer.ExpectDisposition(settled: true, stateMatcher: dispositionMatcher, firstDeliveryId: deliveryNumber, lastDeliveryId: deliveryNumber);

                    await message.AcknowledgeAsync();

                    testPeer.WaitForAllMatchersToComplete(3000);
                }

                testPeer.ExpectClose();
                await connection.CloseAsync();

                testPeer.WaitForAllMatchersToComplete(3000);
            }
        }
Example #4
0
        private async Task DoSendingMessageNonPersistentTestImpl(bool anonymousProducer, bool setPriority, bool setOnProducer)
        {
            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                //Add capability to indicate support for ANONYMOUS-RELAY
                Symbol[]    serverCapabilities = { SymbolUtil.OPEN_CAPABILITY_ANONYMOUS_RELAY };
                IConnection connection         = await EstablishConnectionAsync(testPeer, serverCapabilities : serverCapabilities);

                testPeer.ExpectBegin();

                string          queueName     = "myQueue";
                Action <object> targetMatcher = t =>
                {
                    var target = t as Target;
                    Assert.IsNotNull(target);
                    if (anonymousProducer)
                    {
                        Assert.IsNull(target.Address);
                    }
                    else
                    {
                        Assert.AreEqual(queueName, target.Address);
                    }
                };


                testPeer.ExpectSenderAttach(targetMatcher: targetMatcher, sourceMatcher: Assert.NotNull, senderSettled: false);

                ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge);

                IQueue queue = await session.GetQueueAsync(queueName);

                IMessageProducer producer = null;
                if (anonymousProducer)
                {
                    producer = await session.CreateProducerAsync();
                }
                else
                {
                    producer = await session.CreateProducerAsync(queue);
                }

                byte   priority = 5;
                String text     = "myMessage";
                testPeer.ExpectTransfer(messageMatcher: message =>
                {
                    if (setPriority)
                    {
                        Assert.IsFalse(message.Header.Durable);
                        Assert.AreEqual(5, message.Header.Priority);
                    }

                    Assert.AreEqual(text, (message.BodySection as AmqpValue).Value);
                }, stateMatcher: Assert.IsNull,
                                        settled: false,
                                        sendResponseDisposition: true,
                                        responseState: new Accepted(),
                                        responseSettled: true);

                ITextMessage textMessage = await session.CreateTextMessageAsync(text);

                if (setOnProducer)
                {
                    producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
                    if (setPriority)
                    {
                        producer.Priority = (MsgPriority)5;
                    }

                    if (anonymousProducer)
                    {
                        await producer.SendAsync(queue, textMessage);
                    }
                    else
                    {
                        await producer.SendAsync(textMessage);
                    }
                }
                else
                {
                    if (anonymousProducer)
                    {
                        await producer.SendAsync(destination : queue,
                                                 message : textMessage,
                                                 deliveryMode : MsgDeliveryMode.NonPersistent,
                                                 priority : setPriority?(MsgPriority)priority : NMSConstants.defaultPriority,
                                                 timeToLive : NMSConstants.defaultTimeToLive);
                    }
                    else
                    {
                        await producer.SendAsync(message : textMessage,
                                                 deliveryMode : MsgDeliveryMode.NonPersistent,
                                                 priority : setPriority?(MsgPriority)priority : NMSConstants.defaultPriority,
                                                 timeToLive : NMSConstants.defaultTimeToLive);
                    }
                }

                Assert.AreEqual(MsgDeliveryMode.NonPersistent, textMessage.NMSDeliveryMode, "Should have NonPersistent delivery mode set");

                testPeer.WaitForAllMatchersToComplete(1000);

                testPeer.ExpectClose();
                await connection.CloseAsync();

                testPeer.WaitForAllMatchersToComplete(1000);
            }
        }
        private async Task DoSendingMessageNonPersistentTestImpl(bool setPriority)
        {
            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                //Add capability to indicate support for ANONYMOUS-RELAY
                Symbol[] serverCapabilities = { SymbolUtil.OPEN_CAPABILITY_ANONYMOUS_RELAY };
                var      context            = await EstablishNMSContextAsync(testPeer, serverCapabilities : serverCapabilities);

                testPeer.ExpectBegin();

                string          queueName     = "myQueue";
                Action <object> targetMatcher = t =>
                {
                    var target = t as Target;
                    Assert.IsNotNull(target);
                };


                testPeer.ExpectSenderAttach(targetMatcher: targetMatcher, sourceMatcher: Assert.NotNull, senderSettled: false);

                IQueue queue = await context.GetQueueAsync(queueName);

                INMSProducer producer = await context.CreateProducerAsync();

                byte   priority = 5;
                String text     = "myMessage";
                testPeer.ExpectTransfer(messageMatcher: message =>
                {
                    if (setPriority)
                    {
                        Assert.IsFalse(message.Header.Durable);
                        Assert.AreEqual(priority, message.Header.Priority);
                    }

                    Assert.AreEqual(text, (message.BodySection as AmqpValue).Value);
                }, stateMatcher: Assert.IsNull,
                                        settled: false,
                                        sendResponseDisposition: true,
                                        responseState: new Accepted(),
                                        responseSettled: true);

                ITextMessage textMessage = await context.CreateTextMessageAsync(text);

                producer.DeliveryMode = MsgDeliveryMode.NonPersistent;
                if (setPriority)
                {
                    producer.Priority = (MsgPriority)priority;
                }

                await producer.SendAsync(queue, textMessage);

                Assert.AreEqual(MsgDeliveryMode.NonPersistent, textMessage.NMSDeliveryMode, "Should have NonPersistent delivery mode set");

                testPeer.WaitForAllMatchersToComplete(1000);

                testPeer.ExpectEnd();
                testPeer.ExpectClose();
                await context.CloseAsync();

                testPeer.WaitForAllMatchersToComplete(1000);
            }
        }
        public async Task TestRemotelyEndConnectionWithSessionWithConsumer()
        {
            string errorMessage = "buba";

            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                IConnection connection = await EstablishConnectionAsync(testPeer);

                testPeer.ExpectBegin();
                ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge);

                // Create a consumer, then remotely end the connection afterwards.
                testPeer.ExpectReceiverAttach();

                testPeer.ExpectLinkFlow();
                testPeer.RemotelyCloseConnection(expectCloseResponse: true, errorCondition: AmqpError.RESOURCE_LIMIT_EXCEEDED, errorMessage: errorMessage);

                IQueue queue = await session.GetQueueAsync("myQueue");

                IMessageConsumer consumer = await session.CreateConsumerAsync(queue);

                Assert.That(() => ((NmsConnection)connection).IsConnected, Is.False.After(10_000, 100), "Connection never closes.");

                try
                {
                    await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge);

                    Assert.Fail("Expected ISE to be thrown due to being closed");
                }
                catch (NMSConnectionException e)
                {
                    Assert.True(e.ToString().Contains(AmqpError.RESOURCE_LIMIT_EXCEEDED));
                    Assert.True(e.ToString().Contains(errorMessage));
                }

                // Verify the session is now marked closed
                try
                {
                    var _ = session.AcknowledgementMode;
                    Assert.Fail("Expected ISE to be thrown due to being closed");
                }
                catch (IllegalStateException e)
                {
                    Assert.True(e.ToString().Contains(AmqpError.RESOURCE_LIMIT_EXCEEDED));
                    Assert.True(e.ToString().Contains(errorMessage));
                }

                // Verify the consumer is now marked closed
                try
                {
                    consumer.Listener += message => { };
                }
                catch (IllegalStateException e)
                {
                    Assert.True(e.ToString().Contains(AmqpError.RESOURCE_LIMIT_EXCEEDED));
                    Assert.True(e.ToString().Contains(errorMessage));
                }

                // Try closing them explicitly, should effectively no-op in client.
                // The test peer will throw during close if it sends anything.
                await consumer.CloseAsync();

                await session.CloseAsync();

                await connection.CloseAsync();
            }
        }
Example #7
0
        public void TestRecoverOrderingWithAsyncConsumer()
        {
            ManualResetEvent latch      = new ManualResetEvent(false);
            Exception        asyncError = null;

            int    recoverCount      = 5;
            int    messageCount      = 8;
            int    testPayloadLength = 255;
            string payload           = Encoding.UTF8.GetString(new byte[testPayloadLength]);

            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                IConnection connection = EstablishConnection(testPeer);
                connection.Start();

                testPeer.ExpectBegin();

                ISession session     = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
                IQueue   destination = session.GetQueue("myQueue");
                connection.Start();

                testPeer.ExpectReceiverAttach();
                testPeer.ExpectLinkFlowRespondWithTransfer(
                    message: new Amqp.Message()
                {
                    BodySection = new AmqpValue()
                    {
                        Value = payload
                    }
                },
                    count: messageCount,
                    drain: false,
                    nextIncomingId: 1,
                    addMessageNumberProperty: true,
                    sendDrainFlowResponse: false,
                    sendSettled: false,
                    creditMatcher: credit => Assert.Greater(credit, messageCount)
                    );

                IMessageConsumer consumer = session.CreateConsumer(destination);

                bool complete      = false;
                int  messageSeen   = 0;
                int  expectedIndex = 0;
                consumer.Listener += message =>
                {
                    if (complete)
                    {
                        return;
                    }

                    try
                    {
                        int actualIndex = message.Properties.GetInt(TestAmqpPeer.MESSAGE_NUMBER);
                        Assert.AreEqual(expectedIndex, actualIndex, "Received Message Out Of Order");

                        // don't ack the message until we receive it X times
                        if (messageSeen < recoverCount)
                        {
                            session.Recover();
                            messageSeen++;
                        }
                        else
                        {
                            messageSeen = 0;
                            expectedIndex++;

                            // Have the peer expect the accept the disposition (1-based, hence pre-incremented).
                            testPeer.ExpectDisposition(settled: true,
                                                       stateMatcher: state => Assert.AreEqual(state.Descriptor.Code, MessageSupport.ACCEPTED_INSTANCE.Descriptor.Code
                                                                                              ));

                            message.Acknowledge();

                            if (expectedIndex == messageCount)
                            {
                                complete = true;
                                latch.Set();
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        complete   = true;
                        asyncError = e;
                        latch.Set();
                    }
                };

                Assert.True(latch.WaitOne(TimeSpan.FromSeconds(15)), "Messages not received within given timeout.");
                Assert.IsNull(asyncError, "Unexpected exception");

                testPeer.WaitForAllMatchersToComplete(2000);

                testPeer.ExpectClose();
                connection.Close();

                testPeer.WaitForAllMatchersToComplete(2000);
            }
        }
Example #8
0
        public void TestConsumerCanReceivesMessagesWhenConnectionLostDuringAutoAck()
        {
            using (TestAmqpPeer originalPeer = new TestAmqpPeer())
                using (TestAmqpPeer finalPeer = new TestAmqpPeer())
                {
                    ManualResetEvent consumerReady     = new ManualResetEvent(false);
                    ManualResetEvent originalConnected = new ManualResetEvent(false);
                    ManualResetEvent finalConnected    = new ManualResetEvent(false);

                    // Connect to the first peer
                    originalPeer.ExpectSaslAnonymous();
                    originalPeer.ExpectOpen();
                    originalPeer.ExpectBegin();
                    originalPeer.ExpectBegin();

                    NmsConnection connection = EstablishAnonymousConnection(originalPeer, finalPeer);

                    Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>();

                    connectionListener
                    .Setup(listener => listener.OnConnectionEstablished(It.IsAny <Uri>()))
                    .Callback(() => { originalConnected.Set(); });

                    connectionListener
                    .Setup(listener => listener.OnConnectionRestored(It.IsAny <Uri>()))
                    .Callback(() => { finalConnected.Set(); });

                    connection.AddConnectionListener(connectionListener.Object);

                    connection.Start();

                    Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer");

                    originalPeer.ExpectReceiverAttach();
                    originalPeer.ExpectLinkFlowRespondWithTransfer(message: CreateMessageWithContent(), 1);
                    originalPeer.RunAfterLastHandler(() => consumerReady.WaitOne(TimeSpan.FromSeconds(2)));
                    originalPeer.DropAfterLastMatcher();

                    // Post Failover Expectations of FinalPeer
                    finalPeer.ExpectSaslAnonymous();
                    finalPeer.ExpectOpen();
                    finalPeer.ExpectBegin();
                    finalPeer.ExpectBegin();
                    finalPeer.ExpectReceiverAttach();
                    finalPeer.ExpectLinkFlowRespondWithTransfer(message: CreateMessageWithContent(), 1);
                    finalPeer.ExpectDispositionThatIsAcceptedAndSettled();

                    ISession         session          = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
                    IQueue           queue            = session.GetQueue("myQueue");
                    IMessageConsumer messageConsumer  = session.CreateConsumer(queue);
                    CountdownEvent   msgReceivedLatch = new CountdownEvent(2);
                    messageConsumer.Listener += message =>
                    {
                        if (msgReceivedLatch.CurrentCount == 2)
                        {
                            consumerReady.Set();
                            finalConnected.WaitOne(2000);
                        }

                        msgReceivedLatch.Signal();
                    };

                    finalPeer.WaitForAllMatchersToComplete(5000);

                    Assert.IsTrue(msgReceivedLatch.Wait(TimeSpan.FromSeconds(10)), $"Expected 2 messages, but got {2 - msgReceivedLatch.CurrentCount}");
                }
        }
Example #9
0
        public void TestTempDestinationRecreatedAfterConnectionFailsOver()
        {
            using (TestAmqpPeer originalPeer = new TestAmqpPeer())
                using (TestAmqpPeer finalPeer = new TestAmqpPeer())
                {
                    ManualResetEvent originalConnected = new ManualResetEvent(false);
                    ManualResetEvent finalConnected    = new ManualResetEvent(false);

                    // Create a peer to connect to, then one to reconnect to
                    var originalUri = CreatePeerUri(originalPeer);
                    var finalUri    = CreatePeerUri(finalPeer);

                    originalPeer.ExpectSaslAnonymous();
                    originalPeer.ExpectOpen();
                    originalPeer.ExpectBegin();
                    originalPeer.ExpectBegin();
                    string dynamicAddress1 = "myTempTopicAddress";
                    originalPeer.ExpectTempTopicCreationAttach(dynamicAddress1);
                    originalPeer.DropAfterLastMatcher();

                    NmsConnection connection = EstablishAnonymousConnection(originalPeer, finalPeer);

                    Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>();

                    connectionListener
                    .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString())))
                    .Callback(() => { originalConnected.Set(); });

                    connectionListener
                    .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString())))
                    .Callback(() => { finalConnected.Set(); });

                    connection.AddConnectionListener(connectionListener.Object);

                    connection.Start();

                    Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer");

                    // Post Failover Expectations of FinalPeer
                    finalPeer.ExpectSaslAnonymous();
                    finalPeer.ExpectOpen();
                    finalPeer.ExpectBegin();
                    String dynamicAddress2 = "myTempTopicAddress2";
                    finalPeer.ExpectTempTopicCreationAttach(dynamicAddress2);

                    // Session is recreated after previous temporary destinations are recreated on failover.
                    finalPeer.ExpectBegin();

                    ISession        session        = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
                    ITemporaryTopic temporaryTopic = session.CreateTemporaryTopic();

                    Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer");

                    // Delete the temporary Topic and close the session.
                    finalPeer.ExpectDetach(expectClosed: true, sendResponse: true, replyClosed: true);
                    finalPeer.ExpectEnd();

                    temporaryTopic.Delete();

                    session.Close();

                    // Shut it down
                    finalPeer.ExpectClose();
                    connection.Close();

                    originalPeer.WaitForAllMatchersToComplete(2000);
                    finalPeer.WaitForAllMatchersToComplete(1000);
                }
        }
Example #10
0
        public void TestCreateConsumerAfterConnectionDrops()
        {
            using (TestAmqpPeer originalPeer = new TestAmqpPeer())
                using (TestAmqpPeer finalPeer = new TestAmqpPeer())
                {
                    ManualResetEvent originalConnected = new ManualResetEvent(false);
                    ManualResetEvent finalConnected    = new ManualResetEvent(false);

                    // Create a peer to connect to, then one to reconnect to
                    var originalUri = CreatePeerUri(originalPeer);
                    var finalUri    = CreatePeerUri(finalPeer);

                    // Connect to the first peer
                    originalPeer.ExpectSaslAnonymous();
                    originalPeer.ExpectOpen();
                    originalPeer.ExpectBegin();
                    originalPeer.ExpectBegin();
                    originalPeer.DropAfterLastMatcher();

                    NmsConnection connection = EstablishAnonymousConnection(originalPeer, finalPeer);

                    Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>();

                    connectionListener
                    .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString())))
                    .Callback(() => { originalConnected.Set(); });

                    connectionListener
                    .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString())))
                    .Callback(() => { finalConnected.Set(); });

                    connection.AddConnectionListener(connectionListener.Object);

                    connection.Start();

                    Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer");

                    // Post Failover Expectations of FinalPeer
                    finalPeer.ExpectSaslAnonymous();
                    finalPeer.ExpectOpen();
                    finalPeer.ExpectBegin();
                    finalPeer.ExpectBegin();
                    finalPeer.ExpectReceiverAttach();
                    finalPeer.ExpectLinkFlow(drain: false, sendDrainFlowResponse: false, creditMatcher: credit => Assert.AreEqual(credit, 200));
                    finalPeer.ExpectDetach(expectClosed: true, sendResponse: true, replyClosed: true);
                    finalPeer.ExpectClose();

                    ISession         session  = connection.CreateSession();
                    IQueue           queue    = session.GetQueue("myQueue");
                    IMessageConsumer consumer = session.CreateConsumer(queue);

                    Assert.IsNull(consumer.Receive(TimeSpan.FromMilliseconds(500)));

                    Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer");

                    consumer.Close();

                    // Shut it down
                    connection.Close();

                    finalPeer.WaitForAllMatchersToComplete(1000);
                }
        }
Example #11
0
        public void TestFailoverHandlesDropThenRejectionCloseAfterConnect()
        {
            using (TestAmqpPeer originalPeer = new TestAmqpPeer())
                using (TestAmqpPeer rejectingPeer = new TestAmqpPeer())
                    using (TestAmqpPeer finalPeer = new TestAmqpPeer())
                    {
                        ManualResetEvent originalConnected = new ManualResetEvent(false);
                        ManualResetEvent finalConnected    = new ManualResetEvent(false);

                        // Create a peer to connect to, one to fail to reconnect to, and a final one to reconnect to
                        var originalUri  = CreatePeerUri(originalPeer);
                        var rejectingUri = CreatePeerUri(rejectingPeer);
                        var finalUri     = CreatePeerUri(finalPeer);

                        Logger.Info($"Original peer is at: {originalUri}");
                        Logger.Info($"Rejecting peer is at: {rejectingUri}");
                        Logger.Info($"Final peer is at: {finalUri}");

                        // Connect to the first
                        originalPeer.ExpectSaslAnonymous();
                        originalPeer.ExpectOpen();
                        originalPeer.ExpectBegin();

                        long ird = 0;
                        long rd  = 2000;

                        NmsConnection connection = EstablishAnonymousConnection("failover.initialReconnectDelay=" + ird + "&failover.reconnectDelay=" + rd + "&failover.maxReconnectAttempts=10", originalPeer,
                                                                                rejectingPeer, finalPeer);

                        Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>();

                        connectionListener
                        .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString())))
                        .Callback(() => { originalConnected.Set(); });

                        connectionListener
                        .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString())))
                        .Callback(() => { finalConnected.Set(); });

                        connection.AddConnectionListener(connectionListener.Object);

                        connection.Start();

                        Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer");
                        Assert.False(finalConnected.WaitOne(TimeSpan.FromMilliseconds(100)), "Should not yet have connected to final peer");

                        // Set expectations on rejecting and final peer
                        rejectingPeer.RejectConnect(AmqpError.NOT_FOUND, "Resource could not be located");

                        finalPeer.ExpectSaslAnonymous();
                        finalPeer.ExpectOpen();
                        finalPeer.ExpectBegin();

                        // Close the original peer and wait for things to shake out.
                        originalPeer.Close(sendClose: true);

                        rejectingPeer.WaitForAllMatchersToComplete(2000);

                        Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(10)), "Should connect to final peer");

                        finalPeer.ExpectClose();
                        connection.Close();

                        finalPeer.WaitForAllMatchersToComplete(1000);
                    }
        }