Пример #1
0
        public void TestFailoverHandlesDropAfterSessionCloseRequested()
        {
            using (TestAmqpPeer originalPeer = new TestAmqpPeer())
            {
                ManualResetEvent originalConnected = new ManualResetEvent(false);

                // Create a peer to connect to
                var originalUri = CreatePeerUri(originalPeer);

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

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

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

                NmsConnection connection = EstablishAnonymousConnection(originalPeer);
                connection.AddConnectionListener(connectionListener.Object);

                connection.Start();

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

                originalPeer.ExpectBegin();
                originalPeer.ExpectEnd(sendResponse: false);
                originalPeer.DropAfterLastMatcher();

                ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

                ManualResetEvent sessionCloseCompleted = new ManualResetEvent(false);
                Exception        sessionClosedThrew    = null;

                Task.Run(() =>
                {
                    try
                    {
                        session.Close();
                    }
                    catch (Exception e)
                    {
                        sessionClosedThrew = e;
                    }
                    finally
                    {
                        sessionCloseCompleted.Set();
                    }
                });

                originalPeer.WaitForAllMatchersToComplete(2000);

                Assert.IsTrue(sessionCloseCompleted.WaitOne(TimeSpan.FromSeconds(3)), "Session close should have completed by now");
                Assert.IsNull(sessionClosedThrew, "Session close should have completed normally");

                connection.Close();
            }
        }
Пример #2
0
        public void TestCreateProducerAfterConnectionDrops()
        {
            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.ExpectSenderAttach();
                    finalPeer.ExpectDetach(expectClosed: true, sendResponse: true, replyClosed: true);
                    finalPeer.ExpectClose();

                    ISession         session  = connection.CreateSession();
                    IQueue           queue    = session.GetQueue("myQueue");
                    IMessageProducer producer = session.CreateProducer(queue);

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

                    producer.Close();

                    connection.Close();

                    finalPeer.WaitForAllMatchersToComplete(1000);
                }
        }
Пример #3
0
        public void TestFailoverHandlesDropWithModifiedInitialReconnectDelay()
        {
            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("failover.initialReconnectDelay=1&failover.reconnectDelay=600&failover.maxReconnectAttempts=10", 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();

                    connection.CreateSession(AcknowledgementMode.AutoAcknowledge);

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

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

                    finalPeer.WaitForAllMatchersToComplete(1000);
                }
        }
        private async Task DoTestConsumerReceiveThrowsIfConnectionLost(bool useTimeout)
        {
            ManualResetEvent consumerReady = new ManualResetEvent(false);

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

                testPeer.ExpectBegin();

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

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

                await connection.StartAsync();

                testPeer.ExpectReceiverAttach();
                testPeer.ExpectLinkFlow();
                testPeer.RunAfterLastHandler(() => { consumerReady.WaitOne(2000); });
                testPeer.DropAfterLastMatcher(delay: 10);

                IMessageConsumer consumer = await session.CreateConsumerAsync(queue);

                consumerReady.Set();

                try
                {
                    if (useTimeout)
                    {
                        await consumer.ReceiveAsync(TimeSpan.FromMilliseconds(10_0000));
                    }
                    else
                    {
                        await consumer.ReceiveAsync();
                    }


                    Assert.Fail("An exception should have been thrown");
                }
                catch (NMSException)
                {
                    // Expected
                }

                testPeer.WaitForAllMatchersToComplete(1000);
            }
        }
Пример #5
0
        public void TestFailoverEnforcesSendTimeout()
        {
            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                ManualResetEvent connected    = new ManualResetEvent(false);
                ManualResetEvent disconnected = new ManualResetEvent(false);

                // Connect to the test peer
                testPeer.ExpectSaslAnonymous();
                testPeer.ExpectOpen();
                testPeer.ExpectBegin();
                testPeer.ExpectBegin();
                testPeer.ExpectSenderAttach();
                testPeer.DropAfterLastMatcher();

                NmsConnection connection = EstablishAnonymousConnection("nms.sendTimeout=1000&failover.reconnectDelay=2000&failover.maxReconnectAttempts=60", testPeer);

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

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

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

                connection.AddConnectionListener(connectionListener.Object);

                connection.Start();

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

                ISession         session  = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
                IQueue           queue    = session.GetQueue("myQueue");
                IMessageProducer producer = session.CreateProducer(queue);

                Assert.True(disconnected.WaitOne(TimeSpan.FromSeconds(5)), "Should lose connection to peer");

                Assert.Catch <NMSException>(() => producer.Send(producer.CreateTextMessage("test")));

                connection.Close();

                testPeer.WaitForAllMatchersToComplete(1000);
            }
        }
Пример #6
0
        public void TestFailoverDoesNotFailPendingSend()
        {
            using (TestAmqpPeer originalPeer = new TestAmqpPeer())
                using (TestAmqpPeer finalPeer = new TestAmqpPeer())
                {
                    originalPeer.ExpectSaslAnonymous();
                    originalPeer.ExpectOpen();
                    originalPeer.ExpectBegin();
                    originalPeer.ExpectBegin();

                    // Ensure our send blocks in the provider waiting for credit so that on failover
                    // the message will actually get sent from the Failover bits once we grant some
                    // credit for the recovered sender.
                    originalPeer.ExpectSenderAttachWithoutGrantingCredit();
                    originalPeer.DropAfterLastMatcher(delay: 10); // Wait for sender to get into wait state

                    // Post Failover Expectations of sender
                    finalPeer.ExpectSaslAnonymous();
                    finalPeer.ExpectOpen();
                    finalPeer.ExpectBegin();
                    finalPeer.ExpectBegin();
                    finalPeer.ExpectSenderAttach();
                    finalPeer.ExpectTransfer(messageMatcher: Assert.IsNotNull);
                    finalPeer.ExpectClose();

                    NmsConnection connection = EstablishAnonymousConnection("failover.initialReconnectDelay=25", originalPeer, finalPeer);
                    ISession      session    = connection.CreateSession();
                    IQueue        queue      = session.GetQueue("myQueue");

                    IMessageProducer producer = session.CreateProducer(queue);

                    // Create and transfer a new message
                    string       text    = "myMessage";
                    ITextMessage message = session.CreateTextMessage(text);

                    Assert.DoesNotThrow(() =>
                    {
                        producer.Send(message);
                    });

                    connection.Close();

                    finalPeer.WaitForAllMatchersToComplete(1000);
                }
        }
        private void DoTestConsumerReceiveThrowsIfConnectionLost(bool useTimeout)
        {
            ManualResetEvent consumerReady = new ManualResetEvent(false);

            using (TestAmqpPeer testPeer = new TestAmqpPeer())
            {
                var context = EstablishNMSContext(testPeer);

                testPeer.ExpectBegin();

                IQueue queue = context.GetQueue("queue");
                context.Start();

                testPeer.ExpectReceiverAttach();
                testPeer.ExpectLinkFlow();
                testPeer.RunAfterLastHandler(() => { consumerReady.WaitOne(2000); });
                testPeer.DropAfterLastMatcher(delay: 10);

                var consumer = context.CreateConsumer(queue);
                consumerReady.Set();

                try
                {
                    if (useTimeout)
                    {
                        consumer.Receive(TimeSpan.FromMilliseconds(10_0000));
                    }
                    else
                    {
                        consumer.Receive();
                    }


                    Assert.Fail("An exception should have been thrown");
                }
                catch (NMSException)
                {
                    // Expected
                }

                testPeer.WaitForAllMatchersToComplete(1000);
            }
        }
Пример #8
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);
                }
        }
        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}");
                }
        }