static void Main(string[] args) { // Setup and start the connection using a pooled connection. using (var connection = new NmsConnection(new Uri(URI)) .SessionFactory(new PooledSessionFactory(new PooledSessionFactorySettings() { MinimumSessionsPerConnection = SESSIONS_PER_CONNECTION })) .Start()) { // Create a pooled consumer. connection.CreatePooledConsumer(QUEUE, POOLED_CONSUMER_COUNT, (msg) => { // This action will be invoked for each received message. We'll sleep for 3 seconds each message so that we can // see clearly that messages are truly being processed in parallel. Thread.Sleep(3000); Console.WriteLine("[{0:HH:mm:ss.fffff}] Received => {1}", DateTime.Now, ((ITextMessage)msg).Text); processedCount++; if (processedCount == PARALLEL_PRODUCE_COUNT) Console.WriteLine("Test run completed! {0}/{1} produced messages consumed.", processedCount, PARALLEL_PRODUCE_COUNT); }); // Create a producer. We'll use this producer to send 100 test messages to the queue as fast as we can, and then we can watch // the consumer consume them. using (var producer = connection.CreateProducer(QUEUE)) { Parallel.For(0, PARALLEL_PRODUCE_COUNT, (i) => { var msg = producer.MessageFactory.CreateTextMessage("Test #" + i); producer.SendRequest(msg, Apache.NMS.MsgDeliveryMode.NonPersistent, Apache.NMS.MsgPriority.High, new TimeSpan(0, 1, 0)); Console.WriteLine("[{0:HH:mm:ss.fffff}] Sent => {1}", DateTime.Now, msg.Text); }); } // So that we don't dispose the connection before the test is run :-) Console.ReadLine(); } }
public void TestConnectionThrowsNMSExceptionProviderStartFails() { provider.Configuration.FailOnStart = true; Assert.Throws <NMSException>(() => connection = new NmsConnection(connectionInfo, provider)); }
public void TestSetClientIdFromNull() { connection = new NmsConnection(connectionInfo, provider); Assert.False(connection.IsConnected); Assert.Throws <InvalidClientIDException>(() => connection.ClientId = null); }
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}"); } }
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 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); } }
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; 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: true); 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); } }