/** * @param sessionFactory * @param seconds * @param waitForSync * @param backup */ public static void waitForRemoteBackup( ClientSessionFactoryInternal sessionFactory, int seconds, boolean waitForSync, final HornetQServer backup) { final HornetQServerImpl actualServer = (HornetQServerImpl) backup; final long toWait = seconds * 1000; final long time = System.currentTimeMillis(); while (true) { if ((sessionFactory == null || sessionFactory.getBackupConnector() != null) && (actualServer.isRemoteBackupUpToDate() || !waitForSync)) { break; } if (System.currentTimeMillis() > (time + toWait)) { fail( "backup never started (" + actualServer.isStarted() + "), or never finished synchronizing (" + actualServer.isRemoteBackupUpToDate() + "), or sessionFactory!=null ? " + (sessionFactory != null) + " || sessionFactory.getBackupConnector()==" + (sessionFactory != null ? sessionFactory.getBackupConnector() : "not-applicable")); } try { Thread.sleep(100); } catch (InterruptedException e) { fail(e.getMessage()); } } }
public synchronized void start() { if (!started) { HornetQJMSLogger.LOGGER.debug("Starting RecoveryDiscovery on " + config); started = true; locator = config.createServerLocator(); locator.disableFinalizeCheck(); locator.addClusterTopologyListener(new InternalListener(config)); try { sessionFactory = (ClientSessionFactoryInternal) locator.createSessionFactory(); // We are using the SessionFactoryInternal here directly as we don't have information to // connect with an user and password // on the session as all we want here is to get the topology // in case of failure we will retry sessionFactory.addFailureListener(this); HornetQJMSLogger.LOGGER.debug("RecoveryDiscovery started fine on " + config); } catch (Exception startupError) { HornetQJMSLogger.LOGGER.warn( "Couldn't start recovery discovery on " + config + ", we will retry this on the next recovery scan"); stop(); HornetQRecoveryRegistry.getInstance().failedDiscovery(this); } } }
@Test public void testExpireMessage() throws Exception { locator.setBlockOnNonDurableSend(true); locator.setBlockOnDurableSend(true); locator.setReconnectAttempts(-1); ClientSessionFactoryInternal sf = createSessionFactoryAndWaitForTopology(locator, 2); session = sf.createSession(true, true, 0); session.createQueue(PagingFailoverTest.ADDRESS, PagingFailoverTest.ADDRESS, true); ClientProducer prod = session.createProducer(PagingFailoverTest.ADDRESS); final int TOTAL_MESSAGES = 1000; for (int i = 0; i < TOTAL_MESSAGES; i++) { ClientMessage msg = session.createMessage(true); msg.putIntProperty(new SimpleString("key"), i); msg.setExpiration(System.currentTimeMillis() + 1000); prod.send(msg); } crash(session); session.close(); Queue queue = backupServer.getServer().locateQueue(ADDRESS); long timeout = System.currentTimeMillis() + 60000; while (timeout > System.currentTimeMillis() && queue.getPageSubscription().isPaging()) { Thread.sleep(100); // Simulating what would happen on expire queue.expireReferences(); } assertFalse(queue.getPageSubscription().isPaging()); }
protected void internalStop() { if (started) { started = false; try { if (sessionFactory != null) { sessionFactory.close(); } } catch (Exception ignored) { HornetQJMSLogger.LOGGER.debug(ignored, ignored); } try { locator.close(); } catch (Exception ignored) { HornetQJMSLogger.LOGGER.debug(ignored, ignored); } sessionFactory = null; locator = null; } }
private void decideOnAction() { // we may get called via multiple paths so need to guard synchronized (decisionGuard) { if (signal == BACKUP_ACTIVATION.FAIL_OVER) { return; } if (!isLiveDown()) { try { // no point in repeating all the reconnection logic sessionFactory.connect(RECONNECT_ATTEMPTS, false); return; } catch (HornetQException e) { if (e.getType() != HornetQExceptionType.NOT_CONNECTED) HornetQServerLogger.LOGGER.errorReConnecting(e); } } // live is assumed to be down, backup fails-over signal = BACKUP_ACTIVATION.FAIL_OVER; } latch.countDown(); }
@Override public void onConnection(ClientSessionFactoryInternal sf) { TopologyMember localMember = getLocalMember(); if (localMember != null) { sf.sendNodeAnnounce( localMember.getUniqueEventID(), manager.getNodeId(), manager.getNodeGroupName(), false, localMember.getLive(), localMember.getBackup()); } else { HornetQServerLogger.LOGGER.noLocalMemborOnClusterConnection(this); } // TODO: shouldn't we send the current time here? and change the current topology? // sf.sendNodeAnnounce(System.currentTimeMillis(), // manager.getNodeId(), // false, // localMember.getConnector().a, // localMember.getConnector().b); }
private void wrapUpSessionFactory() { sf.close(); Assert.assertEquals(0, sf.numSessions()); Assert.assertEquals(0, sf.numConnections()); }
public void setLiveID(String liveID) { targetServerID = liveID; nodeManager.setNodeID(liveID); // now we are replicating we can start waiting for disconnect notifications so we can fail over sessionFactory.addFailureListener(this); }
public void internalTestPage(final boolean transacted, final boolean failBeforeConsume) throws Exception { locator.setBlockOnNonDurableSend(true); locator.setBlockOnDurableSend(true); locator.setReconnectAttempts(-1); sf = createSessionFactoryAndWaitForTopology(locator, 2); session = sf.createSession(!transacted, !transacted, 0); session.createQueue(PagingFailoverTest.ADDRESS, PagingFailoverTest.ADDRESS, true); ClientProducer prod = session.createProducer(PagingFailoverTest.ADDRESS); final int TOTAL_MESSAGES = 2000; for (int i = 0; i < TOTAL_MESSAGES; i++) { if (transacted && i % 10 == 0) { session.commit(); } ClientMessage msg = session.createMessage(true); msg.putIntProperty(new SimpleString("key"), i); prod.send(msg); } session.commit(); if (failBeforeConsume) { crash(session); waitForBackup(null, 30); } session.close(); session = sf.createSession(!transacted, !transacted, 0); session.start(); ClientConsumer cons = session.createConsumer(PagingFailoverTest.ADDRESS); final int MIDDLE = TOTAL_MESSAGES / 2; for (int i = 0; i < MIDDLE; i++) { ClientMessage msg = cons.receive(20000); Assert.assertNotNull(msg); msg.acknowledge(); if (transacted && i % 10 == 0) { session.commit(); } Assert.assertEquals(i, msg.getObjectProperty(new SimpleString("key"))); } session.commit(); cons.close(); Thread.sleep(1000); if (!failBeforeConsume) { crash(session); // failSession(session, latch); } session.close(); session = sf.createSession(true, true, 0); cons = session.createConsumer(PagingFailoverTest.ADDRESS); session.start(); for (int i = MIDDLE; i < TOTAL_MESSAGES; i++) { ClientMessage msg = cons.receive(5000); Assert.assertNotNull(msg); msg.acknowledge(); int result = (Integer) msg.getObjectProperty(new SimpleString("key")); Assert.assertEquals(i, result); } }
@Test public void testServerShutdownAndReconnect() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); qResourceAdapter.setReconnectAttempts(-1); qResourceAdapter.setCallTimeout(500L); qResourceAdapter.setTransactionManagerLocatorClass(""); qResourceAdapter.setTransactionManagerLocatorMethod(""); qResourceAdapter.setRetryInterval(500L); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); // This is just to register a listener final CountDownLatch failedLatch = new CountDownLatch(1); ClientSessionFactoryInternal factoryListener = (ClientSessionFactoryInternal) qResourceAdapter .getDefaultHornetQConnectionFactory() .getServerLocator() .createSessionFactory(); factoryListener.addFailureListener( new SessionFailureListener() { @Override public void connectionFailed(HornetQException exception, boolean failedOver) {} @Override public void connectionFailed( HornetQException exception, boolean failedOver, String scaleDownTargetNodeID) { connectionFailed(exception, failedOver); } @Override public void beforeReconnect(HornetQException exception) { failedLatch.countDown(); } }); HornetQActivationSpec spec = new HornetQActivationSpec(); spec.setResourceAdapter(qResourceAdapter); spec.setUseJNDI(false); spec.setDestinationType("javax.jms.Queue"); spec.setDestination(MDBQUEUE); CountDownLatch latch = new CountDownLatch(1); DummyMessageEndpoint endpoint = new DummyMessageEndpoint(latch); DummyMessageEndpointFactory endpointFactory = new DummyMessageEndpointFactory(endpoint, false); qResourceAdapter.endpointActivation(endpointFactory, spec); ClientSession session = locator.createSessionFactory().createSession(); ClientProducer clientProducer = session.createProducer(MDBQUEUEPREFIXED); ClientMessage message = session.createMessage(true); message.getBodyBuffer().writeString("teststring"); clientProducer.send(message); session.close(); latch.await(5, TimeUnit.SECONDS); assertNotNull(endpoint.lastMessage); assertEquals(endpoint.lastMessage.getCoreMessage().getBodyBuffer().readString(), "teststring"); server.stop(); assertTrue(failedLatch.await(5, TimeUnit.SECONDS)); qResourceAdapter.endpointDeactivation(endpointFactory, spec); qResourceAdapter.stop(); }