/** 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); }
/** * 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); }
/** * 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); } }
/** * Handles any failure by trying to reconnect * * @param failure the reason for the failure */ public void handleFailure(Throwable failure) { if (failure instanceof HornetQException && ((HornetQException) failure).getType() == HornetQExceptionType.QUEUE_DOES_NOT_EXIST) { HornetQRALogger.LOGGER.awaitingTopicQueueCreation(getActivationSpec().getDestination()); } else if (failure instanceof HornetQException && ((HornetQException) failure).getType() == HornetQExceptionType.NOT_CONNECTED) { HornetQRALogger.LOGGER.awaitingJMSServerCreation(); } else { HornetQRALogger.LOGGER.failureInActivation(failure, spec); } int reconnectCount = 0; int setupAttempts = spec.getSetupAttempts(); long setupInterval = spec.getSetupInterval(); // Only enter the failure loop once if (inFailure.getAndSet(true)) return; try { Throwable lastException = failure; while (deliveryActive.get() && (setupAttempts == -1 || reconnectCount < setupAttempts)) { teardown(); try { Thread.sleep(setupInterval); } catch (InterruptedException e) { HornetQRALogger.LOGGER.debug("Interrupted trying to reconnect " + spec, e); break; } if (reconnectCount < 1) { HornetQRALogger.LOGGER.attemptingReconnect(spec); } try { setup(); HornetQRALogger.LOGGER.reconnected(); break; } catch (Throwable t) { if (failure instanceof HornetQException && ((HornetQException) failure).getType() == HornetQExceptionType.QUEUE_DOES_NOT_EXIST) { if (lastException == null || !(t instanceof HornetQNonExistentQueueException)) { lastException = t; HornetQRALogger.LOGGER.awaitingTopicQueueCreation( getActivationSpec().getDestination()); } } else if (failure instanceof HornetQException && ((HornetQException) failure).getType() == HornetQExceptionType.NOT_CONNECTED) { if (lastException == null || !(t instanceof HornetQNotConnectedException)) { lastException = t; HornetQRALogger.LOGGER.awaitingJMSServerCreation(); } } else { HornetQRALogger.LOGGER.errorReconnecting(t, spec); } } ++reconnectCount; } } finally { // Leaving failure recovery loop inFailure.set(false); } }
protected void setupDestination() throws Exception { String destinationName = spec.getDestination(); if (spec.isUseJNDI()) { Context ctx; if (spec.getParsedJndiParams() == null) { ctx = new InitialContext(); } else { ctx = new InitialContext(spec.getParsedJndiParams()); } HornetQRALogger.LOGGER.debug("Using context " + ctx.getEnvironment() + " for " + spec); if (HornetQActivation.trace) { HornetQRALogger.LOGGER.trace("setupDestination(" + ctx + ")"); } String destinationTypeString = spec.getDestinationType(); if (destinationTypeString != null && !destinationTypeString.trim().equals("")) { HornetQRALogger.LOGGER.debug("Destination type defined as " + destinationTypeString); Class<?> destinationType; if (Topic.class.getName().equals(destinationTypeString)) { destinationType = Topic.class; isTopic = true; } else { destinationType = Queue.class; } HornetQRALogger.LOGGER.debug( "Retrieving " + destinationType.getName() + " \"" + destinationName + "\" from JNDI"); try { destination = (HornetQDestination) HornetQRaUtils.lookup(ctx, destinationName, destinationType); } catch (Exception e) { if (destinationName == null) { throw HornetQRABundle.BUNDLE.noDestinationName(); } String calculatedDestinationName = destinationName.substring(destinationName.lastIndexOf('/') + 1); HornetQRALogger.LOGGER.debug( "Unable to retrieve " + destinationName + " from JNDI. Creating a new " + destinationType.getName() + " named " + calculatedDestinationName + " to be used by the MDB."); // If there is no binding on naming, we will just create a new instance if (isTopic) { destination = (HornetQDestination) HornetQJMSClient.createTopic(calculatedDestinationName); } else { destination = (HornetQDestination) HornetQJMSClient.createQueue(calculatedDestinationName); } } } else { HornetQRALogger.LOGGER.debug( "Destination type not defined in MDB activation configuration."); HornetQRALogger.LOGGER.debug( "Retrieving " + Destination.class.getName() + " \"" + destinationName + "\" from JNDI"); destination = (HornetQDestination) HornetQRaUtils.lookup(ctx, destinationName, Destination.class); if (destination instanceof Topic) { isTopic = true; } } } else { HornetQRALogger.LOGGER.instantiatingDestination( spec.getDestinationType(), spec.getDestination()); if (Topic.class.getName().equals(spec.getDestinationType())) { destination = (HornetQDestination) HornetQJMSClient.createTopic(spec.getDestination()); isTopic = true; } else { destination = (HornetQDestination) HornetQJMSClient.createQueue(spec.getDestination()); } } }