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

mq5.0-source.main.mq-broker.cluster.src.main.java.com.sun.messaging.jmq.jmsserver.cluster.manager.ha.HAClusterManagerImpl Maven / Gradle / Ivy

There is a newer version: 5.1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2000-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

/*
 * @(#)HAClusterManagerImpl.java	1.77 06/28/07
 */ 

package com.sun.messaging.jmq.jmsserver.cluster.manager.ha;

import java.util.*;
import java.net.MalformedURLException;
import com.sun.messaging.jmq.io.MQAddress;
import com.sun.messaging.jmq.io.Status;
import com.sun.messaging.jmq.util.log.*;
import com.sun.messaging.jmq.util.UID;
import com.sun.messaging.jmq.jmsserver.cluster.api.*;
import com.sun.messaging.jmq.jmsserver.cluster.api.ha.*;
import com.sun.messaging.jmq.jmsserver.util.BrokerException;
import com.sun.messaging.jmq.jmsserver.core.BrokerMQAddress;
import com.sun.messaging.jmq.jmsserver.config.*;
import com.sun.messaging.jmq.jmsserver.persist.api.StoreManager;
import com.sun.messaging.jmq.jmsserver.persist.api.TakeoverStoreInfo;
import com.sun.messaging.jmq.jmsserver.persist.api.HABrokerInfo;
import com.sun.messaging.jmq.jmsserver.cluster.api.*;
import com.sun.messaging.jmq.jmsserver.cluster.manager.*;
import com.sun.messaging.jmq.jmsserver.resources.*;
import com.sun.messaging.jmq.jmsserver.Globals;
import org.jvnet.hk2.annotations.Service;
import javax.inject.Singleton;

// XXX FOR TEST CLASS
import java.io.*;


/**
 * This class extends ClusterManagerImpl and is used to obtain and
 * distribute cluster information in an HA cluster.
 */

@Service(name = "com.sun.messaging.jmq.jmsserver.cluster.manager.ha.HAClusterManagerImpl")
@Singleton
public class HAClusterManagerImpl extends ClusterManagerImpl 
implements ClusterManager
{

// testing only property
    private static boolean IGNORE_HADB_ERRORS = true;

    /**
     * The brokerid associated with the local broker.
     * The local broker is running in the current vm.
     */
    protected String localBrokerId = null;

    /**
     * The version of the cluster protocol.
     */
    protected int VERSION = ClusterBroadcast.VERSION_500;

    protected UID localSessionUID = null;

   /**
    * Creates an instance of HAClusterManagerImpl.
    * @throws BrokerException if the cluster information could not be loaded
    *      because of a configuration issue.
    */
   public HAClusterManagerImpl() 
       throws BrokerException
   {
       super();
   }

   /**
    * Returns if the cluster is "highly available".
    *
    * @return true if the cluster is HA
    * @throws RuntimeException if called before the cluster has
    *         been initialized by calling ClusterManager.setMQAddress
    * @see ClusterManager#setMQAddress
    */
   public boolean isHA() {
       if (!initialized)
           throw new RuntimeException("Cluster not initialized");

       return true;
   }

   /**
    * Reload the cluster properties from config 
    *
    */
   public void reloadConfig() throws BrokerException {
       if (!initialized)
           throw new RuntimeException("Cluster not initialized");

       String[] props = { CLUSTERURL_PROPERTY };
       config.reloadProps(Globals.getConfigName(), props, false);
   }


   /**
    * Retrieves the Map used to store all objects. In the HA broker,
    * the map automatically checks the database if a broker can not
    * be found in memory.
    * @return the map used to store the brokers.
    * @throws BrokerException if something goes wrong loading brokers
    *             from the database
    */
   protected Map initAllBrokers(MQAddress myaddr) 
        throws BrokerException
   {
       return newHABrokerInfoMap();
   }


   /**
    * Method which initializes the broker cluster. (Called by
    * ClusterManager.setMQAddress()).
    *
    * @param address the address for the portmapper
    *
    * @see ClusterManager#setMQAddress
    * @throws BrokerException if something goes wrong during intialzation 
    */
   public String initialize(MQAddress address) 
        throws BrokerException
   {
        logger.log(Logger.DEBUG, "initializingCluster at " + address);

        localBrokerId = Globals.getBrokerID();

        if (localBrokerId == null) {
            throw new BrokerException(
                Globals.getBrokerResources().getKString(
                BrokerResources.E_BAD_BROKER_ID, "null"));
        }

        // make sure master broker is not set
        String mbroker = config.getProperty(CONFIG_SERVER);

        if (mbroker != null) {
            logger.log(Logger.WARNING, 
                   Globals.getBrokerResources().getKString(
                   BrokerResources.W_HA_MASTER_BROKER_NOT_ALLOWED, 
                   CONFIG_SERVER+"="+mbroker));
        }

        super.initialize(address);

        return localBrokerId;
   }

   protected void checkStore() throws BrokerException {
       if (!StoreManager.isConfiguredJDBCStore()) {
           throw new BrokerException(
                 Globals.getBrokerResources().getKString(
                 BrokerResources.E_HA_CLUSTER_INVALID_STORE_CONFIG));
       }
   }

   /**
    * @return true if allow configured master broker
    */
   protected boolean allowMasterBroker() {
       return false; 
   }


   /**
    * Method used to retrieve the list of brokers. In HA, this
    * method displays warnings if the old cluster properties
    * have been set and then loads the brokers from the database.
    *
    * @return a set of MQAddress objects which contains all known
    *         brokers except the local broker
    * @throws MalformedURLException if the address of a broker
    *         stored in the database is invalid.
    */
   protected LinkedHashSet parseBrokerList()
       throws MalformedURLException
   {
       // ignore properties, we get the list from the 
       // database
   
        String propfileSetting = config.getProperty(AUTOCONNECT_PROPERTY);
        String cmdlineSetting = config.getProperty(Globals.IMQ 
                                + ".cluster.brokerlist.manual");

        if (propfileSetting != null) {
             logger.log(Logger.INFO,
                 BrokerResources.I_HA_IGNORE_PROP,
                 AUTOCONNECT_PROPERTY);
        }
        if (cmdlineSetting != null) {
             logger.log(Logger.INFO,
                 BrokerResources.I_HA_IGNORE_PROP,
                 Globals.IMQ + ".cluster.brokerlist.manual");
        }
        LinkedHashSet brokers = new LinkedHashSet();
        synchronized(allBrokers) {
            Iterator itr = allBrokers.values().iterator();
            while (itr.hasNext()) {
                Object obj = itr.next();
                HAClusteredBroker hab = (HAClusteredBroker)obj;
                if (!hab.isLocalBroker())
                    brokers.add(hab.getBrokerURL());
            }
        }
        return brokers;
   }

   /**
    * Method used in ClusterManagerImpl (both in initialization and
    * in normal operation) to add a broker.
    * 

*NOTE: broker created is an HAClusteredBroker.

* @param URL the MQAddress of the new broker * @param isLocal indicates if this is the current broker in this * vm. * @throws NoSuchElementException if the broker listed is * not available in the shared store (since this * indicates a misconfiguration). * @throws RuntimeException if the cluster has not be initialized * (which occurs the first time the MQAddress is set) * @see ClusterManagerImpl#setMQAddress * @return the uid associated with the new broker */ protected String addBroker(MQAddress URL, boolean isLocal, boolean isConfig, UID brokerUID) throws NoSuchElementException, BrokerException { // NOTE we are always a config broker in the HA case, ignore this argument if (!initialized) throw new RuntimeException("Cluster not initialized"); String brokerid = null; ClusteredBroker cb = null; if (isLocal) { // get the broker id brokerid = localBrokerId; // see if the broker exists, if not create one cb = getBroker(brokerid); // NOTE: in HA, the Monitor class will have to validate the // URL and update if necessary if (cb == null) { cb = newHAClusteredBroker(brokerid, URL, VERSION, BrokerState.INITIALIZING, brokerUID); ((HAClusteredBrokerImpl)cb).setIsLocal(true); cb.setInstanceName(Globals.getConfigName()); } else { ((HAClusteredBrokerImpl)cb).setIsLocal(true); cb.setInstanceName(Globals.getConfigName()); } synchronized(allBrokers) { allBrokers.put(brokerid, cb); } } else { // lookup id brokerid = lookupBrokerID(URL); if (brokerid != null) { cb = getBroker(brokerid); } } if (brokerUID != null) { cb.setBrokerSessionUID(brokerUID); } // OK, if we are here we need to create a new one if (brokerid == null ) { throw new NoSuchElementException( Globals.getBrokerResources().getKString( BrokerResources.E_BROKERINFO_NOT_FOUND_IN_STORE, brokerid)); } if (isLocal) { // OK, we know the local broker is up // for all others, activate must be called cb.setStatus(BrokerStatus.ACTIVATE_BROKER, null); } else { updateBroker(cb); } brokerChanged(ClusterReason.ADDED, cb.getBrokerName(), null, cb, cb.getBrokerSessionUID(), null); return brokerid; } protected HAClusteredBroker newHAClusteredBroker(String brokerid, MQAddress url, int version, BrokerState state, UID session) throws BrokerException { return new HAClusteredBrokerImpl(brokerid, url, version, state, session, this); } protected ClusteredBroker updateBrokerOnActivation( ClusteredBroker broker, Object userData) { return updateBroker(broker); } private ClusteredBroker updateBroker(ClusteredBroker broker) { // force an update synchronized(allBrokers) { return (HAClusteredBroker)((AutoClusterBrokerMap)allBrokers).get(broker.getBrokerName(), true); } } /** * Method used in a dynamic cluster, it updates the * system when a broker is removed. * * @param brokerid the id associated with the broker * @param userData optional user data * @throws NoSuchElementException if the broker can not * be found in the cluster. * @throws RuntimeException if the cluster has not be initialized * (which occurs the first time the MQAddress is set) * @see ClusterManagerImpl#setMQAddress */ public void deactivateBroker(String brokerid, Object userData) throws NoSuchElementException { if (!initialized) throw new RuntimeException("Cluster not initialized"); ClusteredBroker cb = getBroker(brokerid); if (cb == null) throw new NoSuchElementException( "Unknown brokerid " + brokerid); cb.setInstanceName(null); // OK, set the broker link down synchronized (this) { cb.setStatus(BrokerStatus.setBrokerLinkIsDown( cb.getStatus()), userData); } } /** * finds the brokerid associated with the given session. * * @param uid is the session uid to search for * @return the uid associated with the session or null we cant find it. */ public String lookupStoreSessionOwner(UID uid) { try { // for HA, check the database if necessary return Globals.getStore().getStoreSessionOwner(uid.longValue()); } catch (Exception ex) { logger.logStack(logger.WARNING, ex.getMessage(), ex); } return null; } /** * Retrieve the broker that creates the specified store session ID. * @param uid store session ID * @return the broker ID */ public String getStoreSessionCreator(UID uid) { try { return Globals.getStore().getStoreSessionCreator(uid.longValue()); } catch (Exception ex) { logger.logStack(logger.INFO, ex.getMessage(), ex); } return null; } /** * Finds the brokerid associated with the given host/port. * * @param address the MQAddress of the new broker * @return the id associated with the broker or null if the broker does not exist * @throws RuntimeException if the cluster has not be initialized * (which occurs the first time the MQAddress is set) * @see ClusterManagerImpl#setMQAddress */ public String lookupBrokerID(MQAddress address) { // for HA, check the database if necessary try { synchronized(allBrokers) { ((AutoClusterBrokerMap)allBrokers).updateMap(); } } catch (BrokerException e) { logger.logStack(logger.WARNING, e.getMessage(), e); } return super.lookupBrokerID(address); } /** * Returns the current number of brokers in the * configuration propperties. In a non-ha cluster, this includes all * brokers listed by -cluster or the cluster property. * @return count of configured brokers in the cluster. * @throws RuntimeException if the cluster has not be initialized * (which occurs the first time the MQAddress is set) * @see ClusterManagerImpl#setMQAddress */ public int getConfigBrokerCount() { return super.getKnownBrokerCount(); } /** * Returns an iterator of HAClusteredBroker objects for * all other brokers in the cluster. (this is a copy of * the current list) * * @param refresh if true refresh current list then return it * @return iterator of HAClusteredBroker * @throws RuntimeException if called before the cluster has * been initialized by calling ClusterManager.setMQAddress * @see ClusterManager#setMQAddress */ public Iterator getKnownBrokers(boolean refresh) { if (!initialized) throw new RuntimeException("Cluster not initialized"); HashSet brokers = null; if (refresh) { try { synchronized(allBrokers) { ((AutoClusterBrokerMap)allBrokers).updateMap(true); } } catch (BrokerException ex) { logger.logStack(logger.WARNING, ex.getMessage(), ex); } } synchronized (allBrokers) { brokers = new HashSet(allBrokers.values()); } return brokers.iterator(); } /** * Returns an iterator of ClusteredBroker objects for * all brokers in the cluster. This is a copy of * the current list and is accurate at the time getBrokers was * called. * * @return iterator of ClusteredBrokers * @throws RuntimeException if the cluster has not be initialized * (which occurs the first time the MQAddress is set) * @see ClusterManagerImpl#setMQAddress */ public Iterator getConfigBrokers() { return getKnownBrokers(true); } protected void addSupportedStoreSessionUID(UID uid) { super.addSupportedStoreSessionUID(uid); } /** * Called when the master broker is set or changed * * @param mbroker the brokerid associated with the * master broker * @throws UnsupportedOperationException if called since * a master broker is not allowed with an HA * cluster. */ protected void masterBrokerChanged(String mbroker) { // no master broker allowed !!! throw new UnsupportedOperationException( "Can not use/set/ change masterbroker"); } /** * Validates an updated property. * @see ConfigListener * @param name the name of the property to be changed * @param value the new value of the property * @throws PropertyUpdateException if the value is * invalid (e.g. format is wrong, property * can not be changed) */ public void validate(String name, String value) throws PropertyUpdateException { // no master broker allowed !!! if (name.equals(CONFIG_SERVER)) { throw new PropertyUpdateException( Globals.getBrokerResources().getKString( BrokerResources.X_HA_MASTER_BROKER_UNSUPPORTED)); } super.validate(name, value); } //------------------------------------------------------------ // apis added for javadoc documentation ONLY //------------------------------------------------------------ /** * Retrieves the HAClusteredBroker which represents * this broker. * * @return the local broker * @throws RuntimeException if the cluster has not be initialized * (which occurs the first time the MQAddress is set) * @see ClusterManagerImpl#setMQAddress * @see HAClusterManagerImpl#getBroker(String) */ public ClusteredBroker getLocalBroker() { return super.getLocalBroker(); } protected String getLocalBrokerName() { return localBroker; } /** * Gets the session UID associated with the local broker * * @return the broker session uid (if known) */ public UID getStoreSessionUID() { if (localSessionUID == null) { localSessionUID = ((HAClusteredBroker)getLocalBroker()).getStoreSessionUID(); } return localSessionUID; } /** * Returns a specific HAClusteredBroker object by name. * * @param brokerid the id associated with the broker * @return the broker associated with brokerid or null * if the broker is not found * @throws RuntimeException if the cluster has not be initialized * (which occurs the first time the MQAddress is set) * @see ClusterManagerImpl#setMQAddress */ public ClusteredBroker getBroker(String brokerid) { ClusteredBroker cb = super.getBroker(brokerid); if (cb != null) return cb; // for HA, check the database if necessary try { synchronized(allBrokers) { ((AutoClusterBrokerMap)allBrokers).updateMap(true); } } catch (BrokerException ex) { logger.logStack(logger.WARNING, ex.getMessage(), ex); } return super.getBroker(brokerid); } protected Map newHABrokerInfoMap() throws BrokerException { return new JDBCHABrokerInfoMap(this); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy