All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hornetq.jms.server.recovery.RecoveryDiscovery Maven / Gradle / Ivy

/*
 * Copyright 2010 Red Hat, Inc.
 * Red Hat licenses this file to you under the Apache License, version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *    http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */

package org.hornetq.jms.server.recovery;

import java.util.concurrent.atomic.AtomicInteger;

import org.hornetq.api.core.HornetQException;
import org.hornetq.api.core.HornetQExceptionType;
import org.hornetq.api.core.Pair;
import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.api.core.client.ClusterTopologyListener;
import org.hornetq.api.core.client.ServerLocator;
import org.hornetq.api.core.client.SessionFailureListener;
import org.hornetq.api.core.client.TopologyMember;
import org.hornetq.core.client.impl.ClientSessionFactoryInternal;
import org.hornetq.jms.server.HornetQJMSServerLogger;

/**
 * 

This class will have a simple Connection Factory and will listen * for topology updates.

*

This Discovery is instantiated by {@link HornetQRecoveryRegistry} * * @author clebertsuconic * * */ public class RecoveryDiscovery implements SessionFailureListener { private ServerLocator locator; private ClientSessionFactoryInternal sessionFactory; private final XARecoveryConfig config; private final AtomicInteger usage = new AtomicInteger(0); private boolean started = false; public RecoveryDiscovery(XARecoveryConfig config) { this.config = config; } public synchronized void start(boolean retry) { if (!started) { HornetQJMSServerLogger.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); HornetQJMSServerLogger.LOGGER.debug("RecoveryDiscovery started fine on " + config); } catch (Exception startupError) { if (!retry) { HornetQJMSServerLogger.LOGGER.xaRecoveryStartError(config); } stop(); HornetQRecoveryRegistry.getInstance().failedDiscovery(this); } } } public synchronized void stop() { internalStop(); } /** we may have several connection factories referencing the same connection recovery entry. * Because of that we need to make a count of the number of the instances that are referencing it, * so we will remove it as soon as we are done */ public int incrementUsage() { return usage.decrementAndGet(); } public int decrementUsage() { return usage.incrementAndGet(); } @Override protected void finalize() { // I don't think it's a good thing to synchronize a method on a finalize, // hence the internalStop (no sync) call here internalStop(); } protected void internalStop() { if (started) { started = false; try { if (sessionFactory != null) { sessionFactory.close(); } } catch (Exception ignored) { HornetQJMSServerLogger.LOGGER.debug(ignored, ignored); } try { locator.close(); } catch (Exception ignored) { HornetQJMSServerLogger.LOGGER.debug(ignored, ignored); } sessionFactory = null; locator = null; } } static final class InternalListener implements ClusterTopologyListener { private final XARecoveryConfig config; public InternalListener(final XARecoveryConfig config) { this.config = config; } public void nodeUP(TopologyMember topologyMember, boolean last) { // There is a case where the backup announce itself, // we need to ignore a case where getLive is null if (topologyMember.getLive() != null) { Pair connector = new Pair(topologyMember.getLive(), topologyMember.getBackup()); HornetQRecoveryRegistry.getInstance().nodeUp(topologyMember.getNodeId(), connector, config.getUsername(), config.getPassword()); } } public void nodeDown(long eventUID, String nodeID) { // I'm not putting any node down, since it may have previous transactions hanging, however at some point we may //change it have some sort of timeout for removal } } @Override public void connectionFailed(HornetQException exception, boolean failedOver) { if (exception.getType() == HornetQExceptionType.DISCONNECTED) { HornetQJMSServerLogger.LOGGER.warn("being disconnected for server shutdown", exception); } else { HornetQJMSServerLogger.LOGGER.warn("Notified of connection failure in xa discovery, we will retry on the next recovery", exception); } internalStop(); HornetQRecoveryRegistry.getInstance().failedDiscovery(this); } @Override public void beforeReconnect(HornetQException exception) { } /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "RecoveryDiscovery [config=" + config + ", started=" + started + "]"; } @Override public int hashCode() { return config.hashCode(); } @Override public boolean equals(Object o) { if (o == null || (! (o instanceof RecoveryDiscovery))) { return false; } RecoveryDiscovery discovery = (RecoveryDiscovery)o; return config.equals(discovery.config); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy