@Test public void testManualFailover() throws Exception { ActiveMQConnectionFactory jbcfLive = ActiveMQJMSClient.createConnectionFactoryWithoutHA( JMSFactoryType.CF, new TransportConfiguration(INVM_CONNECTOR_FACTORY)); jbcfLive.setBlockOnNonDurableSend(true); jbcfLive.setBlockOnDurableSend(true); ActiveMQConnectionFactory jbcfBackup = ActiveMQJMSClient.createConnectionFactoryWithoutHA( JMSFactoryType.CF, new TransportConfiguration(INVM_CONNECTOR_FACTORY, backupParams)); jbcfBackup.setBlockOnNonDurableSend(true); jbcfBackup.setBlockOnDurableSend(true); jbcfBackup.setInitialConnectAttempts(-1); jbcfBackup.setReconnectAttempts(-1); Connection connLive = jbcfLive.createConnection(); MyExceptionListener listener = new MyExceptionListener(); connLive.setExceptionListener(listener); Session sessLive = connLive.createSession(false, Session.AUTO_ACKNOWLEDGE); ClientSession coreSessionLive = ((ActiveMQSession) sessLive).getCoreSession(); RemotingConnection coreConnLive = ((ClientSessionInternal) coreSessionLive).getConnection(); SimpleString jmsQueueName = new SimpleString(ActiveMQDestination.JMS_QUEUE_ADDRESS_PREFIX + "myqueue"); coreSessionLive.createQueue(jmsQueueName, jmsQueueName, null, true); Queue queue = sessLive.createQueue("myqueue"); final int numMessages = 1000; MessageProducer producerLive = sessLive.createProducer(queue); for (int i = 0; i < numMessages; i++) { TextMessage tm = sessLive.createTextMessage("message" + i); producerLive.send(tm); } // Note we block on P send to make sure all messages get to server before failover JMSUtil.crash(liveService, coreSessionLive); connLive.close(); // Now recreate on backup Connection connBackup = jbcfBackup.createConnection(); Session sessBackup = connBackup.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer consumerBackup = sessBackup.createConsumer(queue); connBackup.start(); for (int i = 0; i < numMessages; i++) { TextMessage tm = (TextMessage) consumerBackup.receive(1000); Assert.assertNotNull(tm); Assert.assertEquals("message" + i, tm.getText()); } TextMessage tm = (TextMessage) consumerBackup.receiveNoWait(); Assert.assertNull(tm); connBackup.close(); }
@Test public void testSendReceiveLargeMessages() throws Exception { SimpleString QUEUE = new SimpleString("jms.queue.somequeue"); ActiveMQConnectionFactory jbcf = ActiveMQJMSClient.createConnectionFactoryWithHA(JMSFactoryType.CF, livetc, backuptc); jbcf.setReconnectAttempts(-1); jbcf.setBlockOnDurableSend(true); jbcf.setBlockOnNonDurableSend(true); jbcf.setMinLargeMessageSize(1024); // jbcf.setConsumerWindowSize(0); // jbcf.setMinLargeMessageSize(1024); final CountDownLatch flagAlign = new CountDownLatch(1); final CountDownLatch waitToKill = new CountDownLatch(1); final AtomicBoolean killed = new AtomicBoolean(false); jbcf.getServerLocator() .addIncomingInterceptor( new Interceptor() { int count = 0; @Override public boolean intercept(Packet packet, RemotingConnection connection) throws ActiveMQException { if (packet instanceof SessionReceiveContinuationMessage) { if (count++ == 300 && !killed.get()) { System.out.println("sending countDown on latch waitToKill"); killed.set(true); waitToKill.countDown(); } } return true; } }); Connection conn = JMSUtil.createConnectionAndWaitForTopology(jbcf, 2, 5); Session sess = conn.createSession(true, Session.SESSION_TRANSACTED); final ClientSession coreSession = ((ActiveMQSession) sess).getCoreSession(); // The thread that will fail the server Thread spoilerThread = new Thread() { public void run() { flagAlign.countDown(); // a large timeout just to help in case of debugging try { waitToKill.await(120, TimeUnit.SECONDS); } catch (Exception e) { e.printStackTrace(); } try { System.out.println("Killing server..."); JMSUtil.crash(liveService, coreSession); } catch (Exception e) { e.printStackTrace(); } } }; coreSession.createQueue(QUEUE, QUEUE, true); Queue queue = sess.createQueue("somequeue"); MessageProducer producer = sess.createProducer(queue); producer.setDeliveryMode(DeliveryMode.PERSISTENT); for (int i = 0; i < 100; i++) { TextMessage message = sess.createTextMessage(new String(new byte[10 * 1024])); producer.send(message); if (i % 10 == 0) { sess.commit(); } } sess.commit(); conn.start(); spoilerThread.start(); assertTrue(flagAlign.await(10, TimeUnit.SECONDS)); MessageConsumer consumer = sess.createConsumer(queue); // We won't receive the whole thing here.. we just want to validate if message will arrive or // not... // this test is not meant to validate transactionality during Failover as that would require XA // and recovery for (int i = 0; i < 90; i++) { TextMessage message = null; int retryNrs = 0; do { retryNrs++; try { message = (TextMessage) consumer.receive(5000); assertNotNull(message); break; } catch (JMSException e) { new Exception("Exception on receive message", e).printStackTrace(); } } while (retryNrs < 10); assertNotNull(message); try { sess.commit(); } catch (Exception e) { new Exception("Exception during commit", e); sess.rollback(); } } conn.close(); spoilerThread.join(); }
@Test public void testAutomaticFailover() throws Exception { ActiveMQConnectionFactory jbcf = ActiveMQJMSClient.createConnectionFactoryWithHA(JMSFactoryType.CF, livetc); jbcf.setReconnectAttempts(-1); jbcf.setBlockOnDurableSend(true); jbcf.setBlockOnNonDurableSend(true); // Note we set consumer window size to a value so we can verify that consumer credit re-sending // works properly on failover // The value is small enough that credits will have to be resent several time final int numMessages = 10; final int bodySize = 1000; jbcf.setConsumerWindowSize(numMessages * bodySize / 10); Connection conn = JMSUtil.createConnectionAndWaitForTopology(jbcf, 2, 5); MyExceptionListener listener = new MyExceptionListener(); conn.setExceptionListener(listener); Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); ClientSession coreSession = ((ActiveMQSession) sess).getCoreSession(); SimpleString jmsQueueName = new SimpleString(ActiveMQDestination.JMS_QUEUE_ADDRESS_PREFIX + "myqueue"); coreSession.createQueue(jmsQueueName, jmsQueueName, null, true); Queue queue = sess.createQueue("myqueue"); MessageProducer producer = sess.createProducer(queue); producer.setDeliveryMode(DeliveryMode.PERSISTENT); MessageConsumer consumer = sess.createConsumer(queue); byte[] body = RandomUtil.randomBytes(bodySize); for (int i = 0; i < numMessages; i++) { BytesMessage bm = sess.createBytesMessage(); bm.writeBytes(body); producer.send(bm); } conn.start(); JMSFailoverTest.log.info("sent messages and started connection"); Thread.sleep(2000); JMSUtil.crash(liveService, ((ActiveMQSession) sess).getCoreSession()); for (int i = 0; i < numMessages; i++) { JMSFailoverTest.log.info("got message " + i); BytesMessage bm = (BytesMessage) consumer.receive(1000); Assert.assertNotNull(bm); Assert.assertEquals(body.length, bm.getBodyLength()); } TextMessage tm = (TextMessage) consumer.receiveNoWait(); Assert.assertNull(tm); conn.close(); }