Package com.sun.enterprise.server

Source Code of com.sun.enterprise.server.AbstractManager

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. 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.
*/

/*
* @(#) AbstractManager.java
*
* Copyright 2000-2001 by iPlanet/Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of iPlanet/Sun Microsystems, Inc. ("Confidential Information").
* You shall not disclose such Confidential Information and shall
* use it only in accordance with the terms of the license
* agreement you entered into with iPlanet/Sun Microsystems.
*/
package com.sun.enterprise.server;

import com.sun.appserv.management.util.misc.RunnableBase;
import com.sun.appserv.server.ServerLifecycleException;
import com.sun.enterprise.admin.event.AdminEventListenerException;
import com.sun.enterprise.admin.event.AdminEventResult;
import com.sun.enterprise.admin.event.BaseDeployEvent;
import com.sun.enterprise.admin.server.core.AdminService;
import com.sun.enterprise.config.ConfigBean;
import com.sun.enterprise.config.ConfigContext;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.config.serverbeans.ApplicationHelper;
import com.sun.enterprise.config.serverbeans.ApplicationRef;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
import com.sun.enterprise.connectors.util.ResourcesUtil;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.backend.DeployableObjectType;
import com.sun.enterprise.instance.BaseManager;
import com.sun.enterprise.management.StateManageable;
import com.sun.enterprise.server.ondemand.OnDemandServer;
import com.sun.enterprise.ManagementObjectManager;
import com.sun.logging.LogDomains;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Set;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.ObjectName;

/**
* Base manager class for J2ee applications. A  manager manages all
* j2ee application and stand alone modules for a server instance.
* It also acts as a listener for the deployment events.
*
* <p> This manager object loads all the deployed applications
* or stand alone modules.
*
* <xmp>
*   Code Example:
*     AbstractManager mgr = new SubClassOfAbstractManager(loader, baseMgr);
*
*     // loads the deployed apps returned by the base mgr
*     mgr.load();
* </xmp>
*
* @author  Mahesh Kannan
* @author  Nazrul Islam
* @since   JDK1.4
*/
public abstract class AbstractManager implements MonitorListener {

    /** parent class loader for the j2ee applications */
    protected ClassLoader parentClassLoader;

    /** application registry */
    protected ApplicationRegistry registry;

    /** encapsulates all application related info */
    protected BaseManager configManager;

    /** application id vs application loaders */
    protected Hashtable id2loader;

    /** monitors the time stamp of the RELOAD_FILE */
    protected ReloadMonitor reloadMonitor = null;

    /** Indicates whether system apps of this manager are already loaded */
    protected boolean systemAppsLoaded = false;
 
    /** logger to log core messages */
    static Logger _logger = LogDomains.getLogger(LogDomains.CORE_LOGGER);

    /**
     * Inintializes the variables and constructs the application registry.
     *
     * @param    parentClassLoader    parent class loader for this manager
     * @param    configMgr            encapsulates all application related info
     */
    AbstractManager(ClassLoader parentClassLoader, BaseManager configMgr)
    {

        this.id2loader          = new Hashtable();
        this.parentClassLoader  = parentClassLoader;
        this.configManager      = configMgr;

        // initializes the application registry
        this.registry           = ApplicationRegistry.getInstance();

        // initializes the reload monitor if dynamic reload is enabled
        boolean monitor         = this.configManager.isDynamicReloadEnabled();
        if (monitor) {
            this.reloadMonitor  = ReloadMonitor.getInstance(
                            this.configManager.getReloadPollIntervalInMillis());
        }
    }

    /**
     * Loads the deployed and enabled applications and/or stand alone modules.
     * The list and the type (application vs stand alone module) is determined
     * from the associated config manager object.
     */
    void load() {
       
        // Set the thread context classloader
        final ClassLoader connCL = this.parentClassLoader;
        java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {
                public Object run() {
                    Thread.currentThread().setContextClassLoader(connCL);
                    return null;
                }
            }
        );
       
        //loadSystem();

        // deployed application list from config
        List appList = null;
        try {
            appList = this.configManager.listIds();
        } catch (ConfigException confEx) {
            _logger.log(Level.WARNING,
                        "core.error_while_getting_deployed_applist", confEx);
            return;
        }

        // set jsr77 to true
        boolean jsr77 = true;

        // loads all the deployed applications
        for (int i=0; i<appList.size(); i++) {

            // registration name of this app
            String id = (String) appList.get(i);

            try {
        if (this.configManager.isSystem(id)) {
      continue;
        }
            } catch (ConfigException confEx) {
                _logger.log(Level.WARNING,
                            "core.error_while_loading_app", confEx);
      }

            try {
                // loader for this app
                AbstractLoader loader = getLoader(id);

                // create jsr77 root mBean
                loader.createRootMBean();
           
                // if app is enabled
                ConfigContext ctx = configManager.getConfigContext();
                if (isEnabled(ctx, id)) {

                    // set jsr77 root mBean state to STARTING
                    try {
                        loader.setState(StateManageable.STARTING_STATE);
                    } catch (MBeanException mbe) {
                        _logger.log(Level.WARNING,
                            "core.error_while_setting_jsr77_state",mbe);
                    }

                    /**
                     *Add the loader to the map so it can be cleaned up later
                     *even if the load fails.
                     */
                    id2loader.put(id, loader);
                   
                    // if loader was able to load successfully
                    if (loader.load(jsr77) == true) {
                        // set jsr77 root mBean state to RUNNING
                        try {
                            loader.setState(StateManageable.RUNNING_STATE);
                        } catch (MBeanException mbe) {
                            _logger.log(Level.WARNING,
                            "core.error_while_setting_jsr77_state",mbe);
                        }

                    } else {
                        // set jsr77 root mBean state to FAILED
                        try {
                            loader.setState(StateManageable.FAILED_STATE);
                        } catch (MBeanException mbe) {
                            _logger.log(Level.WARNING,
                            "core.error_while_setting_jsr77_state",mbe);
                        }

                        _logger.log(Level.WARNING,
                                    "core.application_not_loaded", id);
                    }
                    // adds this app to be monitored if ON
                    addToReloadMonitor(id);
                } else if (! isEnabled(ctx, id)) {
                    // if app is not enabled
                    // set jsr77 root mBean state to STOPPED
                    try {
                        loader.setState(StateManageable.STOPPED_STATE);
                        loader.createLeafMBeans();
                    } catch (MBeanException mbe) {
                        _logger.log(Level.WARNING,
                            "core.error_while_setting_jsr77_state",mbe);
                    }

                }
            } catch (ConfigException confEx) {
                _logger.log(Level.WARNING,
                            "core.error_while_loading_app", confEx);
            } catch (Throwable t) { 
                _logger.log(Level.WARNING,
                    "core.unexpected_error_occured_while_loading_app", t);
            }
        }
    }
    /**
     * Loads the deployed and enabled system applications and/or stand alone modules.
     * The list and the type (application vs stand alone module) is determined
     * from the associated config manager object.
     */
    void loadSystem() {
       
        // set jsr77 to true
        boolean jsr77 = true;

        if(systemAppsLoaded)
            return;

        // deployed application list from config
        List appList = null;
        try {
            appList = this.configManager.listIds();
        } catch (ConfigException confEx) {
            _logger.log(Level.WARNING,
                        "core.error_while_getting_deployed_applist", confEx);
            return;
        }

        // loads all the deployed applications
        ArrayList<SystemAppStarter> systemAppStarters = new ArrayList<SystemAppStarter>();
       
        long systemAppLoadStartTime = System.currentTimeMillis();
        boolean isSystemAppLoadLoggingOn = _logger.isLoggable(Level.FINE);
        for (int i=0; i<appList.size(); i++) {

            // registration name of this app
            String id = (String) appList.get(i);

            /**
             * The system app controlled by on-demand framework should not be
             * loaded from this path. All appserver system apps are managed by
             * On-demand system app loader. Any system app inserted by addons
             * will be loaded in this path.
             */
            if (OnDemandServer.isOnDemandOff() ||
               !OnDemandServer.getSystemAppLoader().isOnDemandSystemApp(id)) {
                /*
                 *For each system app of this manager's type create a starter
                 *object and submit it for concurrent execution.  Keep
                 *track of all such objects to wait for their completion and
                 *to query their success.
                 */
                try {
                    if (configManager.isSystem(id)) {
                        SystemAppStarter starter = new SystemAppStarter(id, jsr77);
                        systemAppStarters.add(starter); //loadOneSystemApp(id, jsr77);
                       
                        // allow a system property to control whether system app startup is threaded
                        final boolean threaded = Boolean.parseBoolean( "" + System.getProperty("com.sun.enterprise.server.ThreadedSystemAppStartup") );
                        if ( threaded )
                        {
                            starter.submit();
                            _logger.fine( getClass().getName() + ":  system app \"" + id + "\" started as thread" );
                        }
                        else
                        {
                            starter.submit( RunnableBase.HowToRun.RUN_IN_CURRENT_THREAD );
                            _logger.fine( getClass().getName() + ":  system app \"" + id + "\" started synchronously" );
                        }

                        if (isSystemAppLoadLoggingOn) {
                            _logger.fine(getClass().getName() + " submitted system app load request for " + id);
                        }
                    }
                } catch (ConfigException ce) {
                    // Ignore this - it would come from the isSystem invocation.
                }
            }
        }
       
        /*
         * Wait for the system apps to complete their start-up.  Errors will be
         * thrown, and therefore logged, from the thread doing the work.  Wait for
         * all to complete before aborting the startup if any failed.
         */
        boolean systemAppsStartedOK = true;
        for (SystemAppStarter starter : systemAppStarters) {
            if (isSystemAppLoadLoggingOn) {
                _logger.fine("About to wait for completion of load request for " + starter.getID());
            }
            boolean ok = starter.waitDone() == null;
            systemAppsStartedOK &= ok;
            if (isSystemAppLoadLoggingOn) {
                _logger.fine("Completion received for " + starter.getID() + " reports " + (ok ? "success" : "failure"));
            }
        }
       
        if ( ! systemAppsStartedOK) {
            throw new RuntimeException(
                    _logger.getResourceBundle().getString("core.unexpected_error_occured_while_loading_app"));
        } else if (isSystemAppLoadLoggingOn) {
            _logger.fine(getClass().getName() + " has started its system apps successfully after " +
                    (System.currentTimeMillis() - systemAppLoadStartTime) + " ms");
        }
        systemAppsLoaded = true;
    }


    public void loadOneSystemApp(String id, boolean jsr77) {
     // Set the thread context classloader
        final ClassLoader connCL = this.parentClassLoader;
        final ClassLoader cl = (ClassLoader)
            java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction() {
                public Object run() {
                    ClassLoader cloader = Thread.currentThread().getContextClassLoader();
                    Thread.currentThread().setContextClassLoader(connCL);
                    return cloader;
                }
            }
        );

        try {
            // if app is enabled
            ConfigContext ctx = configManager.getConfigContext();
            if (ResourcesUtil.createInstance().belongToSystemRar(id) ||
                    (this.configManager.isSystem(id)
                     && isEnabled(ctx, id))) {

                // loader for this app
                AbstractLoader loader = getLoader(id);

                // create jsr77 root mBean
                loader.createRootMBean();
               
                /*
                 *Add the loader to the map so it can be cleaned up later
                 *even if the load fails.
                 */
                id2loader.put(id, loader);
               
                // if loader was able to load successfully
                if ( ! loader.load(jsr77) ) {
                    _logger.log(Level.WARNING,
                                "core.application_not_loaded", id);
                }
            }

        } catch (ConfigException confEx) {
            _logger.log(Level.SEVERE,
                        "core.error_while_loading_system_app", confEx);
        } catch (Throwable t) {
            _logger.log(Level.SEVERE,
               "core.unexpected_error_occured_while_loading_system_app", t);
        }

        if (cl != connCL) {
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction() {
                    public Object run() {
                        Thread.currentThread().setContextClassLoader(cl);
                        return null;
                    }
               }
            );
        }

    }


    /**
     * Shutsdown the reload monitor. The bean container shutdown
     * activity is handled from the ApplicationLifeCycle module.
     */
    void shutdown() {
       
        try {
            // shuts down the dynamic reload monitor
            if (this.reloadMonitor != null) {
                this.reloadMonitor.stop();
            }
        } catch (Throwable t) { 
            _logger.log(Level.WARNING,
                "core.unexpected_error_occured_while_app_shutdown", t);
        }
    }

    /**
     * Adds the given application or stand alone module to reload monitor.
     *
     * @param    id    registration name of the application
     *
     * @throws  ConfigException  if an error while parsing server configuration
     */
    protected void addToReloadMonitor(String id) throws ConfigException {

        // adds the reload file to monitor the time stamp
        if (this.reloadMonitor != null && !(this.configManager.isSystem(id))) {
            String mPath = this.configManager.getLocation(id)
                         + File.separator + ReloadMonitor.RELOAD_FILE;
            MonitorableEntry entry =
                new MonitorableEntry(id, new File(mPath), this);
            this.reloadMonitor.addMonitorableEntry(entry);
        }
    }

    /**
     * Removes the given application or stand alone module from reload monitor.
     *
     * @param    id    registration name of the application
     */
    protected void removeFromReloadMonitor(String id) {
    // 4925582  bnevins 10-1-03
    // If the user makes some tiny error and does a touch .reload -- they couldn't fix
    // it and try again.  Now -- we don't remove it from the monitor list.  So they can try again and
    // a regular first-time deployment will be attempted.  They can keep trying until a server restart.
    // After a restart, they'll have to deploy from scratch again.
   
        /*
     if (this.reloadMonitor != null) {
            //this.reloadMonitor.removeMonitoredEntry(id);
        }
     */
    }

    // ---- START OF MonitorListener METHOD -----------------------------------

    /**
     * No-op. Subclasses should implement this methods if they want to handle
     * the dynamic reload callbacks.
     *
     * @param    entry    monitored entry with a change in time stamp
     *
     * @return   no-op; returns false
     */
    public boolean reload(MonitorableEntry entry) {
        return false;
    }

    /**
     * No-op. Subclasses should implement this methods if they want to handle
     * the auto deploy callbacks.
     *
     * @param    entry    entry thats being monitored
     * @param    archive  newly detected archive under the auto deploy directory
     *
     * @return   no-op; returns false
     */
    public boolean deploy(MonitorableEntry entry, File archive) {
        return false;
    }

    // ---- END OF MonitorListener METHOD -------------------------------------

    /**
     * Returns the loader for this type of manager and the given id.
     *
     * @param    id    registration name of an application or stand alone module
     *
     * @return   the correct loader for this manager
     */
    protected abstract AbstractLoader getLoader(String id);

    /**
     * Returns the parent class loader (of ejb modules) used by this manager.
     *
     * @return    the parent class loader used by this manager
     */
    ClassLoader getParentClassLoader() {
        return this.parentClassLoader;
    }

    /**
     * This method is used to determine if an app or a module is already
     * registered.
     * @return true if the app is registered
     **/
    public boolean isRegistered(String id) {
        return this.configManager.isRegistered(id);
    }

    /**
     * @return Whether the JSR77 MBean for a specific app exists
     */
    protected boolean loadJSR77(String appName, String j2eeType) {
  ObjectName jsr77mBeanObjectName = null;
  try {
            String domainName = null;
            AdminService adminService = AdminService.getAdminService();
            if (adminService != null) {
                domainName = adminService.getAdminContext().getDomainName();
            } else {
                return false;
            }

            if (j2eeType == null) return false;

            //We do not load JSR77 MBeans for web modules
            //web modules are loaded by the Tomcat container
            if (j2eeType.equals(ManagementObjectManager.J2EE_TYPE_WEB_MODULE)) {
                return false;
            }

            String instanceName =
                ApplicationServer.getServerContext().getInstanceName();

            //form query
            StringBuffer sb = new StringBuffer("");
            sb.append(domainName + ":");
            sb.append("j2eeType=" + j2eeType + ",");
            sb.append("name=" + appName + ",");
            if (! j2eeType.equals(ManagementObjectManager.J2EE_TYPE_APPLICATION)) {
                sb.append("J2EEApplication=null" + ",");
            }
            sb.append("J2EEServer=" + instanceName + "," + "*");

            // perform query
            MBeanServer mbs = adminService.getAdminContext().getMBeanServer();

            ObjectName objNamePattern = new ObjectName(sb.toString());
            java.util.Set s = mbs.queryNames(objNamePattern, null);
            if (s != null && s.size()>0) {
                ObjectName [] objNameArr =
                    (ObjectName[]) s.toArray( new ObjectName[s.size()]);
                if (objNameArr.length>0) {
                    jsr77mBeanObjectName = objNameArr[0];
                }
            }
        } catch (Exception ex) {
            //Ignore on purpose.
        }

  return jsr77mBeanObjectName == null;
    }

    /**
     * Whether or not a component (either an application or a module) should be
     * enabled is defined by the "enable" attribute on both the
     * application/module element and the application-ref element.
     *
     * @param config The dynamic ConfigContext
     * @param moduleName The name of the component (application or module)
     * @return boolean
     */
    protected boolean isEnabled (ConfigContext config, String moduleName) {
        try {
            ConfigBean app = ApplicationHelper.findApplication(config, moduleName);

            Server server = ServerBeansFactory.getServerBean(config);
            ApplicationRef appRef = server.getApplicationRefByRef(moduleName);
            return ((app != null && app.isEnabled()) &&
                        (appRef != null && appRef.isEnabled()));
        } catch (ConfigException e) {
            AdminEventListenerException ex = new AdminEventListenerException();
            ex.initCause(e);
            _logger.log(Level.FINE, "Error in finding " + moduleName, e);

            //If there is anything wrong, do not enable the module
            return false;
        }
    }

    protected void registerException(BaseDeployEvent event, String msg) {
        AdminEventResult result = AdminEventResult.getAdminEventResult(event);
        result.setResultCode(AdminEventResult.SUCCESS);
        result.addException(event.getEffectiveDestination(),
                            new AdminEventListenerException(msg));
    }

    // creating JSR77 root mbean for the application so the root mbean
    // would also be available for disabled application
    protected void createRootMBeanForDisabledApplication(String appID) {
        try {
            AbstractLoader appLoader = (AbstractLoader)id2loader.get(appID);
            if (appLoader == null) {
                appLoader = getLoader(appID);
            }
            appLoader.createRootMBean();
            appLoader.setState(StateManageable.STOPPED_STATE);
        } catch (Exception e) {
            _logger.log(Level.WARNING, "core.error_createrb_disabled", e);
        }
    }
   
    /**
     *Represents the start-up of a system app, typically run concurrently with
     *other system-app start up work.
     */
    private class SystemAppStarter extends RunnableBase {
       
        private final String id;
        private final boolean jsr77;
       
        public SystemAppStarter(String id, boolean jsr77) {
            this.id = id;
            this.jsr77 = jsr77;
        }

        protected void doRun() throws Exception {
            loadOneSystemApp(id, jsr77);
        }
       
        public String getID() {
            return id;
        }
    }
}
TOP

Related Classes of com.sun.enterprise.server.AbstractManager

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.