Package org.jvnet.glassfish.comms.gms

Source Code of org.jvnet.glassfish.comms.gms.GMSEventListener$ClusterGMSModuleThread

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. 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.html
* or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [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.
*/

package org.jvnet.glassfish.comms.gms;

//import org.jvnet.glassfish.comms.clb.core.*;
import com.sun.enterprise.admin.server.core.AdminService;
import com.sun.enterprise.config.ConfigContext;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.config.serverbeans.Cluster;
import com.sun.enterprise.config.serverbeans.ClusterHelper;
import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.config.serverbeans.ConfigAPIHelper;
import com.sun.enterprise.ee.cms.core.CallBack;
import com.sun.enterprise.ee.cms.core.FailureNotificationActionFactory;
import com.sun.enterprise.ee.cms.core.FailureNotificationSignal;
import com.sun.enterprise.ee.cms.core.GMSConstants;
import com.sun.enterprise.ee.cms.core.GMSException;
import com.sun.enterprise.ee.cms.core.GMSFactory;
import com.sun.enterprise.ee.cms.core.GMSNotEnabledException;
import com.sun.enterprise.ee.cms.core.GroupManagementService;
import com.sun.enterprise.ee.cms.core.JoinNotificationActionFactory;
import com.sun.enterprise.ee.cms.core.JoinNotificationSignal;
import com.sun.enterprise.ee.cms.core.JoinedAndReadyNotificationActionFactory;
import com.sun.enterprise.ee.cms.core.JoinedAndReadyNotificationSignal;
import com.sun.enterprise.ee.cms.core.PlannedShutdownActionFactory;
import com.sun.enterprise.ee.cms.core.PlannedShutdownSignal;
import com.sun.enterprise.ee.cms.core.ServiceProviderConfigurationKeys;
import com.sun.enterprise.ee.cms.core.Signal;
import com.sun.enterprise.ee.cms.impl.client.FailureNotificationActionFactoryImpl;
import com.sun.enterprise.ee.cms.impl.client.JoinNotificationActionFactoryImpl;
import com.sun.enterprise.ee.cms.impl.client.JoinedAndReadyNotificationActionFactoryImpl;
import com.sun.enterprise.ee.cms.impl.client.PlannedShutdownActionFactoryImpl;
import com.sun.enterprise.ee.cms.spi.MemberStates;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jvnet.glassfish.comms.util.LogUtil;

/**
*
* @author kshitiz
*/
public abstract class GMSEventListener implements EventListener, CallBack{
    private static final Logger _logger = LogUtil.CLB_LOGGER.getLogger();
    private String clusterName;
    private GroupManagementService gms;
    private boolean startedGMSModule;
    private FailureNotificationActionFactory failureNotificationActionFactory;
    private PlannedShutdownActionFactory plannedShutdownActionFactory;
    private JoinedAndReadyNotificationActionFactory joinedAndReadyNotificationActionFactory;
    private JoinNotificationActionFactory joinNotificationActionFactory;
    private boolean spectatorMode;
   
    public GMSEventListener(String clusterName)
        throws GMSEventListenerException {
        this.clusterName = clusterName;
        gms = null;
        spectatorMode = false;
        registerCallBackHandler();
    }
   
    public GMSEventListener(String clusterName, boolean spectatorMode)
        throws GMSEventListenerException {
        this.clusterName = clusterName;
        gms = null;
        this.spectatorMode = spectatorMode;
        registerCallBackHandler();
    }
   
   
    public void processNotification(Signal signal) {
        if (signal instanceof JoinedAndReadyNotificationSignal){
            boolean isClusterStartup =
            (((JoinedAndReadyNotificationSignal)signal).getEventSubType().equals(
                    GMSConstants.startupType.GROUP_STARTUP));
            onRecovery(signal.getGroupName(), signal.getMemberToken(),
                    isClusterStartup);
        } else if (signal instanceof FailureNotificationSignal) {
            onFailure(signal.getGroupName(), signal.getMemberToken(),
                    false);
        } else if (signal instanceof PlannedShutdownSignal) {
            boolean isClusterShutdown =
            (((PlannedShutdownSignal)signal).getEventSubType().equals(
                    GMSConstants.shutdownType.GROUP_SHUTDOWN));
            onFailure(signal.getGroupName(), signal.getMemberToken(),
                    isClusterShutdown);
        } else if (signal instanceof JoinNotificationSignal){
             MemberStates memberState =
                ((JoinNotificationSignal) signal).getMemberState();
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE,
                    "clb.recieved_join_notification_for_instance",
                    new Object[]{signal.getMemberToken(), clusterName, memberState.name()});
            }
            //if member state is ALIVEANDREADY, then mark this instance as
            //recovered, this has to be case of network outage
            //if member state is READY then JOINANDREADY event will come,
            //and instance will be marked healthy then
            if (memberState == MemberStates.ALIVEANDREADY)
                onRecovery(signal.getGroupName(), signal.getMemberToken(),
                        false);           
            //Else if member state is not ALIVE or READY mark it as failed,
            //If member is not in above state, then it can be a case of
            //transient failure. Mark this instance as failed. It will marked
            //healthy again when JoinedAndReadyNotification is received 
            /* Still not sure whether this case need to be handled
            else if(memberState != MemberStates.ALIVE
            && memberState != MemberStates.READY)
            onFailure(signal.getGroupName(), signal.getMemberToken());
            */
        }
    }

    private void registerCallBackHandler()
        throws GMSEventListenerException {
        startedGMSModule = false;
        while(gms == null){
            try {
                gms = GMSFactory.getGMSModule(clusterName);
            } catch (GMSNotEnabledException ex) {
                // It means gms module is not started for this cluster
               
                //For core members, this should already be started as part of GMS lifecycle.
                //If it is not started then it can be either a configuration issue,
                //or gms startup/initialization issue. Cannot handle this case, hence
                //throw an exception in this case
                if (!spectatorMode) {
                    String message = _logger.getResourceBundle().
                            getString("clb.gms_module_not_started_for_self_lb_cluster") + clusterName;
                    throw new GMSEventListenerException(message);
                }
               
                //Already one attempt was made to start this GMS module
                //Will not retry, throwing an exception
                if(startedGMSModule){
                    String message = _logger.getResourceBundle().
                            getString("clb.unable_to_get_gms_module") + clusterName;
                    throw new GMSEventListenerException(message);
                }
               
                // Start a GMS module in this case
                if(_logger.isLoggable(Level.FINE))
                    _logger.log(Level.FINE,
                            "clb.starting_gms_module",
                            new Object[]{clusterName});
                startGMSModule();
                startedGMSModule = true;
                if(_logger.isLoggable(Level.FINE))
                    _logger.log(Level.FINE,
                            "clb.starting_gms_module",
                            new Object[]{clusterName, gms});
            } catch (GMSException ex) {
                throw new GMSEventListenerException(ex);
            }
        }

        failureNotificationActionFactory = new FailureNotificationActionFactoryImpl(this);
        gms.addActionFactory(failureNotificationActionFactory);

        plannedShutdownActionFactory = new PlannedShutdownActionFactoryImpl(this);
        gms.addActionFactory(plannedShutdownActionFactory);
       
        joinedAndReadyNotificationActionFactory = new JoinedAndReadyNotificationActionFactoryImpl(this);
        gms.addActionFactory(joinedAndReadyNotificationActionFactory);
       
        joinNotificationActionFactory = new JoinNotificationActionFactoryImpl(this);
        gms.addActionFactory(joinNotificationActionFactory);
    }

    private GroupManagementService startGMSModule() throws GMSEventListenerException {
        String instanceName = com.sun.enterprise.server.ondemand.OnDemandServer.getServerContext()
                                                                               .getInstanceName();
        Runnable gmsModule = GMSFactory.startGMSModule(instanceName,
                clusterName, //Adding itself as spectator
            GroupManagementService.MemberType.SPECTATOR, getGMSConfigProps());
       
        ClusterGMSModuleThread gmsModuleThread = new ClusterGMSModuleThread(gmsModule);
        gmsModuleThread.start();
       
        return gms;
    }
   
    private Properties getGMSConfigProps() throws GMSEventListenerException {
        Properties props = new Properties();
        Config config;
        Cluster cluster;
        ConfigContext configContext;

        try {
            configContext = AdminService.getAdminService().getAdminContext()
                                        .getAdminConfigContext();
            cluster = ClusterHelper.getClusterByName(configContext, clusterName);

            String configRef = cluster.getConfigRef();
            config = ConfigAPIHelper.getConfigByName(configContext, configRef);

            com.sun.enterprise.config.serverbeans.GroupManagementService gmsConfig =
                config.getGroupManagementService();
           
            if(!gmsConfig.isEnabled()){
                String message = _logger.getResourceBundle().
                            getString("clb.gms_not_enabled") + clusterName;
                    throw new GMSEventListenerException(message);
            }
                       
            props.put(ServiceProviderConfigurationKeys.FAILURE_DETECTION_RETRIES.toString(),
                gmsConfig.getFdProtocolMaxTries());
            props.put(ServiceProviderConfigurationKeys.FAILURE_DETECTION_TIMEOUT.toString(),
                gmsConfig.getFdProtocolTimeoutInMillis());
            props.put(ServiceProviderConfigurationKeys.DISCOVERY_TIMEOUT.toString(),
                gmsConfig.getPingProtocolTimeoutInMillis());
            props.put(ServiceProviderConfigurationKeys.FAILURE_VERIFICATION_TIMEOUT.toString(),
                gmsConfig.getVsProtocolTimeoutInMillis());
            String timeout = gmsConfig.getFailureDetectionTCPRetransmitTimeout();
            if (timeout != null)
                props.put(ServiceProviderConfigurationKeys.FAILURE_DETECTION_TCP_RETRANSMIT_TIMEOUT.toString(),
                          timeout);
            props.put(ServiceProviderConfigurationKeys.MULTICASTADDRESS.toString(),
                cluster.getHeartbeatAddress());
            props.put(ServiceProviderConfigurationKeys.MULTICASTPORT.toString(),
                cluster.getHeartbeatPort());
        } catch (ConfigException e) {
            _logger.log(Level.SEVERE,
                    "clb.exception_getting_properties_for_gms_module",
                    new Object[]{clusterName, e.getMessage()});
            if(_logger.isLoggable(Level.FINE))
                _logger.log(Level.FINE, "clb.caught_an_exception", e);
        }

        return props;
    }
   
    public GroupManagementService getGroupManagementService(){
        return gms;
    }
   
    public void cleanup() {
        gms.removeActionFactory(failureNotificationActionFactory);
        gms.removeActionFactory(plannedShutdownActionFactory);
        gms.removeActionFactory(joinedAndReadyNotificationActionFactory);
        gms.removeActionFactory(joinNotificationActionFactory);
        //To be confirmed how to shut down a GMS module
        if(startedGMSModule)
            gms.shutdown(GMSConstants.shutdownType.INSTANCE_SHUTDOWN);
    }
   
    public abstract void onRecovery(String clusterName, String instanceName,
            boolean isClusterStartup);

    public abstract void onFailure(String clusterName, String instanceName,
            boolean isClusterShutdown);

    public final void onDisable(String clusterName, String instanceName){
        //GMS will never propogate a disable event, so making this method
        //as unsupported
        throw new UnsupportedOperationException();
    }

    public final void onEnable(String clusterName, String instanceName){
        //GMS will never propogate a enable event, so making this method
        //as unsupported
        throw new UnsupportedOperationException();
    };
   
    public final void onAdd(String clusterName, String instanceName, boolean
            lbEnabled){
        //GMS will never propogate instance add event, so making this method
        //as unsupported
        throw new UnsupportedOperationException();
    }

    public final void onDelete(String clusterName, String instanceName){
        //GMS will never propogate instance delete event, so making this method
        //as unsupported
        throw new UnsupportedOperationException();
    };
    
    class ClusterGMSModuleThread extends Thread{
       
        ClusterGMSModuleThread(Runnable gmsModule){
            super(gmsModule);
        }
       
    }
}
TOP

Related Classes of org.jvnet.glassfish.comms.gms.GMSEventListener$ClusterGMSModuleThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.