FileDocCategorySizeDatePackage
JmsProviderLifecycle.javaAPI DocGlassfish v2 API22120Fri May 04 22:35:04 BST 2007com.sun.enterprise.jms

JmsProviderLifecycle

public final class JmsProviderLifecycle extends com.sun.appserv.server.ServerLifecycleImpl
This class provides service for starting (currently only ping) the configured JMS provider at J2EE server intialization and stopping the configured JMS provider at J2EE server termination

Fields Summary
private ConfigContext
ctx
private static JmsService
jmsService_
private JmsHost
jmsHost_
private static com.sun.messaging.jmq.jmsspi.JMSAdmin
jmsAdmin_
private boolean
onShutdown
private static boolean
startedByMe_
private boolean
autoShutdown_
private static final Logger
_logger
private static boolean
debug
private static final int
NOTCHECKED
private static final int
SUCCESSFUL
private static final int
FAILED
private static final int
REMOTESTARTUP
private static int
startupStatus
private static String
instanceName
private static String
iMQBin
private static String
exception
private static String
url
private static final String
AS_INTEGRATION_VIA_MQ_SPI
private static boolean
useMQRAForBrokerLifecycle
Constructors Summary
Methods Summary
private java.lang.StringattachToJmsProvider()

        jmsAdmin_.connectToProvider();
        String name = jmsAdmin_.getProviderInstanceName();
        jmsAdmin_.disconnectFromProvider();
        return name;
    
public static voidcheckProviderStartup()
Check Jms Provider and make sure that it is started. When resource adapter starts up, it will also doublecheck using this static method.

        if (shouldUseMQRAForLifecycleControl()) {
            return;
        } 

	switch (startupStatus) {
	    case NOTCHECKED    : break;
	    case SUCCESSFUL    : return;
	    case FAILED        : 
	         throw new ServerLifecycleException
		 ("MQ startup failed :" + exception);
	    case REMOTESTARTUP : return;
	}

	String iMQInstance =  System.getProperty(Constants.INSTALL_ROOT) +
	                      java.io.File.separator + "imq" +
	                      java.io.File.separator + "var" +
	                      java.io.File.separator + "instances"; 

        String initTimeoutStr = null;
        long initTimeout = 30 * 1000;

        initTimeoutStr = jmsService_.getInitTimeoutInSeconds();

        if (initTimeoutStr != null)
            initTimeout = Integer.parseInt(initTimeoutStr) * 1000;

        Exception excp = null;
        try {
             waitForJmsProvider(initTimeout);
	     startupStatus = SUCCESSFUL;
        }
        catch (javax.jms.JMSSecurityException e) {
	    excp = e;

	    // Provider is up and we have a wrong username and password 
	    // configured. We should shut this down. Recreate the admin
	    // with defult user and password.
            startedByMe_ = true;
	    try {
                jmsAdmin_ =
                    IASJmsUtil.getJMSAdminFactory().getJMSAdmin(url,
		    IASJmsUtil.DEFAULT_USER,
		    IASJmsUtil.DEFAULT_PASSWORD);
	    } catch (Exception ex) {
	    }
	}
        catch (Exception e1) {
	    excp = e1;
        }

	if (excp != null) {
             startupStatus = FAILED;
             _logger.log(Level.INFO, "jms.broker_ping_failed",
                         Long.toString(initTimeout));
             _logger.log(Level.INFO,
                    "jms.broker_instance_dir", iMQInstance);
             _logger.log(Level.INFO,
                    "jms.broker_log_location",instanceName);
	     exception = excp.getMessage();
             throw new ServerLifecycleException(excp.getMessage(), excp);
	}

        startedByMe_ = true;

        Object[] params = {instanceName, iMQBin};
            _logger.log(Level.INFO, "jms.broker_started", params);

    
public static com.sun.messaging.jmq.jmsspi.JMSAdmingetJMSAdmin()

        return jmsAdmin_;
    
public booleanisNOJMS()

        return false;
    
public voidonInitialization(com.sun.enterprise.server.ServerContext sc)
THIS METHOD MUST BE CALLED BEFORE any of the IASJmsUtil, IASJmsConfig method get called. Server is initializing subsystems and setting up the runtime environment. Prepare for the beginning of active use of the public methods of this subsystem. This method is called before any of the public methods of this subsystem are utilized.

param
sc ServerContext the server runtime context.
exception
IllegalStateException if this subsystem has already been started
exception
ServerLifecycleException if this subsystem detects a fatal error that prevents this subsystem from being used

    
    //determine if MQ SPI needs to be used.
     
        try {
            String s = System.getProperty(AS_INTEGRATION_VIA_MQ_SPI);
            if (s != null) {
                useMQRAForBrokerLifecycle = !((new Boolean(s)).booleanValue());
            }
            String status = (useMQRAForBrokerLifecycle ? "Using MQ RA for Broker lifecycle control" : 
                "Using MQ SPI for Broker Lifecycle control");
            _logger.log(Level.INFO, status);
        } catch (Exception ex) {
            _logger.log(Level.WARNING, "Exception while reading " 
                    + AS_INTEGRATION_VIA_MQ_SPI +  "property" + ex.getMessage());
            _logger.log(Level.INFO, "Using MQ RA for Broker Lifecycle control");
            _logger.log(Level.FINE, ex.getMessage());
        }
    
        if (!shouldUseMQRAForLifecycleControl()) {

            if (jmsService_ != null) {
                // Dont allow duplicate initializations.
                return;
            }

            try {
                jmsAdmin_ = null;
                ctx = sc.getConfigContext();

                //ROB: config changes
                //JavaConfig jc = ServerBeansFactory.getServerBean(
                //    ctx).getJavaConfig();
                JavaConfig jc = ServerBeansFactory.getJavaConfigBean(ctx);

                String java_home = jc.getJavaHome();

                //ROB: config changes
                //jmsService_ = ServerBeansFactory.getServerBean(ctx).getJmsService();
                jmsService_ = ServerBeansFactory.getJmsServiceBean(ctx);
                String defaultJmsHost = jmsService_.getDefaultJmsHost();

                if (defaultJmsHost==null || defaultJmsHost.equals("")) {
                    jmsHost_ = ServerBeansFactory.getJmsHostBean(ctx);
                } else {
                    jmsHost_ = jmsService_.getJmsHostByName(defaultJmsHost);
                }

    //ROB: config changes
    /*
                if (jmsService_ != null && jmsService_.isEnabled()) {
                    String portStr = jmsService_.getPort();
                    String username = jmsService_.getAdminUserName();
                    String password = jmsService_.getAdminPassword();
    */
                String type = jmsService_.getType();
                if (!(type.equals("LOCAL"))) {
                    startupStatus = REMOTESTARTUP;
                    _logger.log(Level.INFO, "jms.broker_notlocal", type);
                    return;
                }

                if (jmsHost_ != null && jmsHost_.isEnabled()) {
                    String portStr = jmsHost_.getPort();
                    String username = jmsHost_.getAdminUserName();
                    String password = jmsHost_.getAdminPassword();

                    Vector v = new Vector();
                    if (java_home != null) {
                        v.add("-javahome");
                        v.add(java_home);
                    }

                    String mqInstanceDir = 
                           sc.getInstanceEnvironment().getInstancesRoot() +
                           java.io.File.separator + IASJmsUtil.MQ_DIR_NAME;

                    // If the directory doesnt exist, create it.
                    // It is necessary for windows.
                    java.io.File instanceDir = new java.io.File(mqInstanceDir);
                    if (!(instanceDir.exists() && instanceDir.isDirectory())) {
                        instanceDir.mkdirs();
                    }

                    v.add("-varhome");
                    v.add(mqInstanceDir);


                    String tmpstr = jmsService_.getStartArgs();
                    if (tmpstr != null) {
                        StringTokenizer st = new StringTokenizer(tmpstr, " ");
                        while (st.hasMoreTokens()) {
                            String t = st.nextToken();
                            v.add(t);
                        }
                    }

                    String[] startArgs = (String []) v.toArray(new String[0]);

                    // Extract the information from the optional properties.
                    // Valid property names : "auto-shutdown"
                    ElementProperty[] jmsProperties =
                        jmsService_.getElementProperty();

                    if (jmsProperties != null) {
                        for (int ii=0; ii < jmsProperties.length; ii++) {
                            ElementProperty p = jmsProperties[ii];
                            String name = p.getName();

                            if (name.equals("auto-shutdown"))
                                autoShutdown_ =
                                    Boolean.valueOf(p.getValue()).booleanValue();
                        }
                    }

                    // If the property was not specified, then look for the 
                    // imqRoot as defined by the com.sun.aas.imqRoot property   
                    iMQBin = java.lang.System.getProperty(SystemPropertyConstants.IMQ_BIN_PROPERTY);

                    // Finally if all else fails (though this should never happen)
                    // look for IMQ relative to the installation directory
                    if (iMQBin == null) {
                        String IMQ_INSTALL_SUBDIR = java.io.File.separator + 
                            ".." + java.io.File.separator + ".." +
                            java.io.File.separator + "imq" +
                            java.io.File.separator + "bin";
                        iMQBin = sc.getInstallRoot() + IMQ_INSTALL_SUBDIR;
                    }

                    //
                    // Calculate the imq broker executable path.
                    //
                    String asInstance = sc.getInstanceName();
                    String domainName = ServerManager.instance().getDomainName();
                    instanceName = IASJmsUtil.getBrokerInstanceName(
                        domainName, asInstance, jmsService_);

                    String localhost = "127.0.0.1";
                    url = localhost + ((portStr == null) ?
                        "" : ":" + portStr);
                    if (username == null) {
                        jmsAdmin_ =
                            IASJmsUtil.getJMSAdminFactory().getJMSAdmin(url);
                    }
                    else {
                        jmsAdmin_ =
                            IASJmsUtil.getJMSAdminFactory().getJMSAdmin(url,
                                username, password);
                    }

                    // First ping the provider to see if it is already
                    // running.
                    boolean running;
                    try {
                        jmsAdmin_.pingProvider();
                        running = true;
                    }
                    catch (Exception e) {
                        running = false;
                    }

                    if (running) {
                        _logger.fine(
                            "Broker is already running. Trying to attach.");
                        String s = null;
                        try {
                            s = attachToJmsProvider();
                        }
                        catch (Exception e) {
                            _logger.log(Level.INFO, "jms.broker_attach_failed");
                            _logger.log(Level.INFO,
                                "jms.broker_log_location", instanceName);
                            throw new ServerLifecycleException(e.getMessage(), e);
                        }
                        if (s.equals(instanceName)) {
                            // An iMQ broker instance with the same name
                            // is already running.  Since the instance
                            // names match, it is probably a broker
                            // process left behind by the application
                            // server. Treat it as if it was started by
                            // this application server process...
                            startedByMe_ = true;
                            _logger.log(Level.INFO, "jms.broker_found",
                                instanceName);
                        }
                        else {
                            startedByMe_ = false;
                            Object[] params = {s, portStr};
                            _logger.log(Level.SEVERE, "jms.broker_already_up",
                                params);
                            throw new ServerLifecycleException(
                                "JmsProviderLifecycle error.");
                        }
                    }
                    else {
                        _logger.fine("Starting JMS broker : imq-home=" + iMQBin +
                            ", stargArgs=" + tmpstr +
                            ", instanceName=" + instanceName);

                        try {
                            jmsAdmin_.startProvider(iMQBin,
                                startArgs, instanceName);
                        }
                        catch (Exception e) {
                            _logger.log(Level.INFO, "jms.broker_exec_failed");
                            _logger.log(Level.INFO,
                                "jms.broker_log_location", instanceName);
                            throw new ServerLifecycleException(e.getMessage(), e);
                        }


                    }
                }
            }
            catch (Exception e) {
                jmsService_ = null;
                _logger.log(Level.SEVERE, "jms.broker_startup_failed");

                // The exception will be logged at the outer level...

                throw new ServerLifecycleException(e.getMessage(), e);
            }
        }
    
public voidonShutdown()
Server is shutting down applications

exception
ServerLifecycleException if this subsystem detects a fatal error that prevents this subsystem from being used

        checkProviderStartup();
        onShutdown = true;
    
public voidonStartup(com.sun.enterprise.server.ServerContext sc)
Server is starting up applications

param
sc ServerContext the server runtime context.
exception
ServerLifecycleException if this subsystem detects a fatal error that prevents this subsystem from being used

        //Start ActiveJMSRA
        try {
            String module = ConnectorConstants.DEFAULT_JMS_ADAPTER;
            String loc = Switch.getSwitch().getResourceInstaller().
                         getSystemModuleLocation(module);
            ConnectorRuntime.getRuntime().createActiveResourceAdapter(
                         loc, module);
        } catch (ConnectorRuntimeException e) {
            e.printStackTrace();
            _logger.log(Level.INFO, "Failed to start JMS RA");
            throw new ServerLifecycleException("Failed to start JMS RA", e);
        }
       
    
public voidonTermination()
Server is terminating the subsystems and the runtime environment. Gracefully terminate the active use of the public methods of this subsystem. This method should be the last one called on a given instance of this subsystem.

exception
ServerLifecycleException if this subsystem detects a fatal error that prevents this subsystem from being used

        onShutdown = true;
        //need not do anything if lifecycke managed by the RA.
        if (!shouldUseMQRAForLifecycleControl()) {

            try {
                if (startupStatus == REMOTESTARTUP ||
                    autoShutdown_ == false ||
                    jmsService_ == null ||
                    jmsService_.isEnabled() == false)
                    return;

                if (jmsAdmin_ == null || startedByMe_ == false)
                    return;

                _logger.log(Level.INFO, "jms.broker_shutting_down");
                jmsAdmin_.connectToProvider();
            }
            catch (Exception e) {
                throw new ServerLifecycleException(e.getMessage(), e);
            }

            try {
                jmsAdmin_.shutdownProvider();
                _logger.log(Level.INFO, "jms.broker_shutdown_complete");
            }
            catch (Exception e) {} // Ignore this exception.
        }
    
public static booleanshouldUseMQRAForLifecycleControl()

        return JmsProviderLifecycle.useMQRAForBrokerLifecycle;
    
private static voidwaitForJmsProvider(long initTimeout)


        boolean ready = false;

        // It is debatable where to put startTime. If we set the
        // time right after startProvider as startTime, we may land into
        // some issues. In a single CPU system, the startTime
        // may not reflect the correct meaning. If we consider startTime
        // as cpuTime, here it is assumed that there is no time spend
        // for JMS startup until now. Actually CPU should have spend time. 
        long startTime = java.lang.System.currentTimeMillis();

        while (true) {
            try {
                jmsAdmin_.pingProvider();
                ready = true;
                break;
            }
            catch (Exception e) {}

            if (java.lang.System.currentTimeMillis() - startTime >=
                initTimeout) {
                break;
            }

            try {
                Thread.sleep(2000);
            }
            catch (Exception e) {}
        }

        // If provider is not ready, call pingProvider again
        // to generate the exception...
        if (!ready)
            jmsAdmin_.pingProvider();