/** Teardown the activation */ protected synchronized void teardown() { HornetQRALogger.LOGGER.debug("Tearing down " + spec); if (resourceRecovery != null) { ra.getRecoveryManager().unRegister(resourceRecovery); } for (HornetQMessageHandler handler : handlers) { handler.interruptConsumer(); } Thread threadTearDown = new Thread("TearDown/HornetQActivation") { public void run() { for (HornetQMessageHandler handler : handlers) { handler.teardown(); } } }; // We will first start a new thread that will call tearDown on all the instances, trying to // graciously shutdown everything. // We will then use the call-timeout to determine a timeout. // if that failed we will then close the connection factory, and interrupt the thread threadTearDown.start(); try { threadTearDown.join(factory.getCallTimeout()); } catch (InterruptedException e) { // nothing to be done on this context.. we will just keep going as we need to send an // interrupt to threadTearDown and give up } if (threadTearDown.isAlive()) { if (factory != null) { // This will interrupt any threads waiting on reconnect factory.close(); factory = null; } threadTearDown.interrupt(); try { threadTearDown.join(5000); } catch (InterruptedException e) { // nothing to be done here.. we are going down anyways } if (threadTearDown.isAlive()) { HornetQRALogger.LOGGER.warn("Thread " + threadTearDown + " couldn't be finished"); } } if (spec.isHasBeenUpdated() && factory != null) { factory.close(); factory = null; } HornetQRALogger.LOGGER.debug("Tearing down complete " + this); }
protected void setupCF() throws Exception { if (spec.isHasBeenUpdated()) { factory = ra.createHornetQConnectionFactory(spec); } else { factory = ra.getDefaultHornetQConnectionFactory(); } }
/** * Constructor * * @param ra The resource adapter * @param endpointFactory The endpoint factory * @param spec The activation spec * @throws ResourceException Thrown if an error occurs */ public HornetQActivation( final HornetQResourceAdapter ra, final MessageEndpointFactory endpointFactory, final HornetQActivationSpec spec) throws ResourceException { spec.validate(); if (HornetQActivation.trace) { HornetQRALogger.LOGGER.trace( "constructor(" + ra + ", " + endpointFactory + ", " + spec + ")"); } if (ra.isUseMaskedPassword()) { String pass = spec.getOwnPassword(); if (pass != null) { SensitiveDataCodec<String> codec = ra.getCodecInstance(); try { spec.setPassword(codec.decode(pass)); } catch (Exception e) { throw new ResourceException(e); } } } this.ra = ra; this.endpointFactory = endpointFactory; this.spec = spec; try { isDeliveryTransacted = endpointFactory.isDeliveryTransacted(HornetQActivation.ONMESSAGE); } catch (Exception e) { throw new ResourceException(e); } }
/** * Setup the activation * * @throws Exception Thrown if an error occurs */ protected synchronized void setup() throws Exception { HornetQRALogger.LOGGER.debug("Setting up " + spec); setupCF(); setupDestination(); for (int i = 0; i < spec.getMaxSession(); i++) { ClientSession session = null; try { ClientSessionFactory cf = factory.getServerLocator().createSessionFactory(); session = setupSession(cf); HornetQMessageHandler handler = new HornetQMessageHandler(this, ra.getTM(), (ClientSessionInternal) session, cf, i); handler.setup(); session.start(); handlers.add(handler); } catch (Exception e) { if (session != null) { session.close(); } throw e; } } resourceRecovery = ra.getRecoveryManager().register(factory, spec.getUser(), spec.getPassword()); HornetQRALogger.LOGGER.debug("Setup complete " + this); }
/** @return */ protected HornetQResourceAdapter newResourceAdapter() { HornetQResourceAdapter qResourceAdapter = new HornetQResourceAdapter(); qResourceAdapter.setTransactionManagerLocatorClass(""); qResourceAdapter.setTransactionManagerLocatorMethod(""); qResourceAdapter.setConnectorClassName(UnitTestCase.INVM_CONNECTOR_FACTORY); return qResourceAdapter; }
@Test public void testInvalidAckMode() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); HornetQActivationSpec spec = new HornetQActivationSpec(); try { spec.setAcknowledgeMode("CLIENT_ACKNOWLEDGE"); fail("should throw exception"); } catch (java.lang.IllegalArgumentException e) { // pass } qResourceAdapter.stop(); }
/** * Start the activation * * @throws ResourceException Thrown if an error occurs */ public void start() throws ResourceException { if (HornetQActivation.trace) { HornetQRALogger.LOGGER.trace("start()"); } deliveryActive.set(true); ra.getWorkManager().scheduleWork(new SetupActivation()); }
/** * Get the work manager * * @return The value */ public WorkManager getWorkManager() { if (HornetQActivation.trace) { HornetQRALogger.LOGGER.trace("getWorkManager()"); } return ra.getWorkManager(); }
@Test public void testDurableSubscription() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); HornetQActivationSpec spec = new HornetQActivationSpec(); spec.setResourceAdapter(qResourceAdapter); spec.setUseJNDI(false); spec.setDestinationType("javax.jms.Topic"); spec.setDestination("mdbTopic"); spec.setSubscriptionDurability("Durable"); spec.setSubscriptionName("durable-mdb"); spec.setClientID("id-1"); qResourceAdapter.setConnectorClassName(INVM_CONNECTOR_FACTORY); 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("jms.topic.mdbTopic"); ClientMessage message = session.createMessage(true); message.getBodyBuffer().writeString("1"); clientProducer.send(message); latch.await(5, TimeUnit.SECONDS); assertNotNull(endpoint.lastMessage); assertEquals(endpoint.lastMessage.getCoreMessage().getBodyBuffer().readString(), "1"); qResourceAdapter.endpointDeactivation(endpointFactory, spec); message = session.createMessage(true); message.getBodyBuffer().writeString("2"); clientProducer.send(message); latch = new CountDownLatch(1); endpoint = new DummyMessageEndpoint(latch); endpointFactory = new DummyMessageEndpointFactory(endpoint, false); qResourceAdapter.endpointActivation(endpointFactory, spec); latch.await(5, TimeUnit.SECONDS); assertNotNull(endpoint.lastMessage); assertEquals(endpoint.lastMessage.getCoreMessage().getBodyBuffer().readString(), "2"); latch = new CountDownLatch(1); endpoint.reset(latch); message = session.createMessage(true); message.getBodyBuffer().writeString("3"); clientProducer.send(message); latch.await(5, TimeUnit.SECONDS); assertNotNull(endpoint.lastMessage); assertEquals(endpoint.lastMessage.getCoreMessage().getBodyBuffer().readString(), "3"); qResourceAdapter.endpointDeactivation(endpointFactory, spec); qResourceAdapter.stop(); }
@Test public void testXACommit() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); HornetQActivationSpec spec = new HornetQActivationSpec(); spec.setResourceAdapter(qResourceAdapter); spec.setUseJNDI(false); spec.setDestinationType("javax.jms.Queue"); spec.setDestination(MDBQUEUE); qResourceAdapter.setConnectorClassName(INVM_CONNECTOR_FACTORY); CountDownLatch latch = new CountDownLatch(1); XADummyEndpoint endpoint = new XADummyEndpoint(latch); DummyMessageEndpointFactory endpointFactory = new DummyMessageEndpointFactory(endpoint, true); 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"); endpoint.prepare(); endpoint.commit(); qResourceAdapter.endpointDeactivation(endpointFactory, spec); qResourceAdapter.stop(); }
@Test public void testSimpleMessageReceivedOnQueueManyMessages() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); HornetQActivationSpec spec = new HornetQActivationSpec(); spec.setResourceAdapter(qResourceAdapter); spec.setUseJNDI(false); spec.setDestinationType("javax.jms.Queue"); spec.setDestination(MDBQUEUE); qResourceAdapter.setConnectorClassName(INVM_CONNECTOR_FACTORY); CountDownLatch latch = new CountDownLatch(15); MultipleEndpoints endpoint = new MultipleEndpoints(latch, false); DummyMessageEndpointFactory endpointFactory = new DummyMessageEndpointFactory(endpoint, false); qResourceAdapter.endpointActivation(endpointFactory, spec); ClientSession session = locator.createSessionFactory().createSession(); ClientProducer clientProducer = session.createProducer(MDBQUEUEPREFIXED); for (int i = 0; i < 15; i++) { ClientMessage message = session.createMessage(true); message.getBodyBuffer().writeString("teststring" + i); clientProducer.send(message); } session.close(); latch.await(5, TimeUnit.SECONDS); qResourceAdapter.endpointDeactivation(endpointFactory, spec); qResourceAdapter.stop(); }
// https://issues.jboss.org/browse/JBPAPP-8017 @Test public void testNonDurableSubscriptionDeleteAfterCrash() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); qResourceAdapter.setTransactionManagerLocatorClass(""); qResourceAdapter.setTransactionManagerLocatorMethod(""); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); HornetQActivationSpec spec = new HornetQActivationSpec(); spec.setResourceAdapter(qResourceAdapter); spec.setUseJNDI(false); spec.setDestinationType("javax.jms.Topic"); spec.setDestination("mdbTopic"); qResourceAdapter.setConnectorClassName(INVM_CONNECTOR_FACTORY); 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("jms.topic.mdbTopic"); ClientMessage message = session.createMessage(true); message.getBodyBuffer().writeString("1"); clientProducer.send(message); latch.await(5, TimeUnit.SECONDS); assertNotNull(endpoint.lastMessage); assertEquals(endpoint.lastMessage.getCoreMessage().getBodyBuffer().readString(), "1"); HornetQActivation activation = lookupActivation(qResourceAdapter); SimpleString tempQueueName = activation.getTopicTemporaryQueue(); QueueQuery query = session.queueQuery(tempQueueName); assertTrue(query.isExists()); // this should be enough to simulate the crash qResourceAdapter.getDefaultHornetQConnectionFactory().close(); qResourceAdapter.stop(); query = session.queueQuery(tempQueueName); assertFalse(query.isExists()); }
/** * Setup a session * * @param cf * @return The connection * @throws Exception Thrown if an error occurs */ protected ClientSession setupSession(ClientSessionFactory cf) throws Exception { ClientSession result = null; try { result = ra.createSession( cf, spec.getAcknowledgeModeInt(), spec.getUser(), spec.getPassword(), ra.getPreAcknowledge(), ra.getDupsOKBatchSize(), ra.getTransactionBatchSize(), isDeliveryTransacted, spec.isUseLocalTx(), spec.getTransactionTimeout()); result.addMetaData("resource-adapter", "inbound"); result.addMetaData("jms-session", ""); String clientID = ra.getClientID() == null ? spec.getClientID() : ra.getClientID(); if (clientID != null) { result.addMetaData("jms-client-id", clientID); } HornetQRALogger.LOGGER.debug("Using queue connection " + result); return result; } catch (Throwable t) { try { if (result != null) { result.close(); } } catch (Exception e) { HornetQRALogger.LOGGER.trace("Ignored error closing connection", e); } if (t instanceof Exception) { throw (Exception) t; } throw new RuntimeException("Error configuring connection", t); } }
@Test public void testMaxSessions() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); HornetQActivationSpec spec = new HornetQActivationSpec(); spec.setMaxSession(1); spec.setResourceAdapter(qResourceAdapter); spec.setUseJNDI(false); spec.setDestinationType("javax.jms.Queue"); spec.setDestination(MDBQUEUE); qResourceAdapter.setConnectorClassName(INVM_CONNECTOR_FACTORY); CountDownLatch latch = new CountDownLatch(1); DummyMessageEndpoint endpoint = new DummyMessageEndpoint(latch); DummyMessageEndpointFactory endpointFactory = new DummyMessageEndpointFactory(endpoint, false); qResourceAdapter.endpointActivation(endpointFactory, spec); Binding binding = server.getPostOffice().getBinding(MDBQUEUEPREFIXEDSIMPLE); assertEquals(((LocalQueueBinding) binding).getQueue().getConsumerCount(), 1); qResourceAdapter.endpointDeactivation(endpointFactory, spec); qResourceAdapter.stop(); }
@Test public void testSharedSubscription() throws Exception { HornetQResourceAdapter qResourceAdapter = newResourceAdapter(); MyBootstrapContext ctx = new MyBootstrapContext(); qResourceAdapter.start(ctx); HornetQActivationSpec spec = new HornetQActivationSpec(); spec.setResourceAdapter(qResourceAdapter); spec.setUseJNDI(false); spec.setDestinationType("javax.jms.Topic"); spec.setDestination("mdbTopic"); spec.setSubscriptionDurability("Durable"); spec.setSubscriptionName("durable-mdb"); spec.setClientID("id-1"); spec.setSetupAttempts(1); spec.setShareSubscriptions(true); spec.setMaxSession(1); HornetQActivationSpec spec2 = new HornetQActivationSpec(); spec2.setResourceAdapter(qResourceAdapter); spec2.setUseJNDI(false); spec2.setDestinationType("javax.jms.Topic"); spec2.setDestination("mdbTopic"); spec2.setSubscriptionDurability("Durable"); spec2.setSubscriptionName("durable-mdb"); spec2.setClientID("id-1"); spec2.setSetupAttempts(1); spec2.setShareSubscriptions(true); spec2.setMaxSession(1); CountDownLatch latch = new CountDownLatch(5); DummyMessageEndpoint endpoint = new DummyMessageEndpoint(latch); DummyMessageEndpointFactory endpointFactory = new DummyMessageEndpointFactory(endpoint, false); qResourceAdapter.endpointActivation(endpointFactory, spec); CountDownLatch latch2 = new CountDownLatch(5); DummyMessageEndpoint endpoint2 = new DummyMessageEndpoint(latch2); DummyMessageEndpointFactory endpointFactory2 = new DummyMessageEndpointFactory(endpoint2, false); qResourceAdapter.endpointActivation(endpointFactory2, spec2); ClientSession session = locator.createSessionFactory().createSession(); ClientProducer clientProducer = session.createProducer("jms.topic.mdbTopic"); for (int i = 0; i < 10; i++) { ClientMessage message = session.createMessage(true); message.getBodyBuffer().writeString("" + i); clientProducer.send(message); } session.commit(); assertTrue(latch.await(5, TimeUnit.SECONDS)); assertTrue(latch2.await(5, TimeUnit.SECONDS)); assertNotNull(endpoint.lastMessage); assertNotNull(endpoint2.lastMessage); qResourceAdapter.endpointDeactivation(endpointFactory, spec); qResourceAdapter.endpointDeactivation(endpointFactory2, spec2); qResourceAdapter.stop(); }
@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(); }