Package org.apache.geronimo.kernel

Source Code of org.apache.geronimo.kernel.Kernel$KernelReference

/**
*
* Copyright 2003-2004 The Apache Software Foundation
*
*  Licensed 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.apache.geronimo.kernel;

import java.io.Serializable;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;
import javax.management.Attribute;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.JMRuntimeException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcasterSupport;
import javax.management.ObjectName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.jmx.DependencyService;
import org.apache.geronimo.gbean.jmx.GBeanMBean;
import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.geronimo.kernel.config.InvalidConfigException;
import org.apache.geronimo.kernel.jmx.JMXUtil;


/**
* The core of a Geronimo instance.
* A Kernel is responsible for managing the Configurations that comprise a
* Geronimo system and exposing them using JMX. Each Kernel is associated
* with an MBeanServer that is used to register the Configurations themselves
* and the MBeans they define.
*
* Dependencies between MBeans are handled by a dedicated DependencyService
* that is responsible for tracking those dependencies and ensuring that the
* dependent objects follow the appropriate lifecycle and receive appropriate
* notifications.
*
* The Kernel also provides a ConfigurationStore which is used to stage
* installed Configurations (providing a local filesystem based classpath) and
* used hold the persistent state of each Configuration. This allows
* Configurations to restart in he event of system failure.
*
* @version $Revision: 1.24 $ $Date: 2004/04/23 03:02:00 $
*/
public class Kernel extends NotificationBroadcasterSupport implements Serializable, KernelMBean {

    /**
     * The JMX name used by a Kernel to register itself when it boots.
     */
    public static final ObjectName KERNEL = JMXUtil.getObjectName("geronimo.boot:role=Kernel");

    /**
     * The JMX name of the DependencyService.
     */
    public static final ObjectName DEPENDENCY_SERVICE = JMXUtil.getObjectName("geronimo.boot:role=DependencyService2");


    private static final Map kernels = new Hashtable();
    private static final ReferenceQueue queue = new ReferenceQueue();
    private final String kernelName;
    private final String domainName;

    private transient Log log;
    private transient boolean running;
    private transient MBeanServer mbServer;

    private transient ConfigurationManager configurationManager;
    private transient GBeanMBean configurationManagerGBean;

    private static final String[] NO_TYPES = new String[0];
    private static final Object[] NO_ARGS = new Object[0];
    private static final ObjectName CONFIGURATION_MANAGER_NAME = JMXUtil.getObjectName("geronimo.boot:role=ConfigurationManager");
    private static final ObjectName CONFIGURATION_STORE_PATTERN = JMXUtil.getObjectName("*:role=ConfigurationStore,*");

    /**
     * No-arg constructor allowing this class to be used as a GBean reference.
     */
    public Kernel() {
        kernelName = null;
        domainName = null;
    }

    /**
     * Construct a Kernel which does not have a config store.
     * @param domainName the domain name to be used for the JMX MBeanServer
     */
    public Kernel(String domainName) {
        this(null, domainName);
    }

    /**
     * Construct a Kernel which does not have a config store.
     * @param kernelName the name of the kernel that uniquely indentifies the kernel in a VM
     * @param domainName the domain name to be used for the JMX MBeanServer
     */
    public Kernel(String kernelName, String domainName) {
        this.kernelName = kernelName;
        this.domainName = domainName;
    }

    public MBeanServer getMBeanServer() {
        return mbServer;
    }

    public String getKernelName() {
        return kernelName;
    }

    /**
     * Get a particular kernel indexed by a name
     * @param name the name of the kernel to be obtained
     * @return the kernel that was registered with that name
     */
    public static Kernel getKernel(String name) {
        synchronized (kernels) {
            processQueue();
            KernelReference ref = (KernelReference) kernels.get(name);
            if (ref != null) {
                return (Kernel) ref.get();
            }
        }
        return null;
    }

    /**
     * Obtain the single kernel that's registered.
     *
     * <p>This method assumes that there is only one kernel registered and will throw an
     * <code>IllegalStateException</code> if more than one has been registered.
     * @return the single kernel that's registered
     * @throws IllegalStateException if more than one
     */
    public static Kernel getSingleKernel() {
        synchronized (kernels) {
            processQueue();

            int size = kernels.size();
            if (size > 1) throw new IllegalStateException("More than one kernel has been registered.");
            if (size < 1) return null;

            Kernel result = (Kernel) ((KernelReference) kernels.values().iterator().next()).get();
            if (result == null) {
                kernels.clear();
            }
            return result;
        }
    }

    public ConfigurationManager getConfigurationManager() {
        return configurationManager;
    }

    public Object getAttribute(ObjectName objectName, String attributeName) throws Exception {
        try {
            return mbServer.getAttribute(objectName, attributeName);
        } catch (JMException e) {
            Throwable cause = e;
            while ((cause instanceof JMException || cause instanceof JMRuntimeException) && cause.getCause() != null) {
                cause = cause.getCause();
            }
            if (cause instanceof Error) {
                throw (Error) cause;
            } else if (cause instanceof Exception) {
                throw (Exception) cause;
            } else {
                throw new AssertionError(cause);
            }
        }
    }

    public void setAttribute(ObjectName objectName, String attributeName, Object attributeValue) throws Exception {
        try {
            mbServer.setAttribute(objectName, new Attribute(attributeName, attributeValue));
        } catch (JMException e) {
            Throwable cause = e;
            while ((cause instanceof JMException || cause instanceof JMRuntimeException) && cause.getCause() != null) {
                cause = cause.getCause();
            }
            if (cause instanceof Error) {
                throw (Error) cause;
            } else if (cause instanceof Exception) {
                throw (Exception) cause;
            } else {
                throw new AssertionError(cause);
            }
        }
    }

    public Object invoke(ObjectName objectName, String methodName) throws Exception {
        return invoke(objectName, methodName, NO_ARGS, NO_TYPES);
    }

    public Object invoke(ObjectName objectName, String methodName, Object[] args, String[] types) throws Exception {
        try {
            return mbServer.invoke(objectName, methodName, args, types);
        } catch (JMException e) {
            Throwable cause = e;
            while ((cause instanceof JMException || cause instanceof JMRuntimeException) && cause.getCause() != null) {
                cause = cause.getCause();
            }
            if (cause instanceof Error) {
                throw (Error) cause;
            } else if (cause instanceof Exception) {
                throw (Exception) cause;
            } else {
                throw new AssertionError(cause);
            }
        }
    }


    public boolean isLoaded(ObjectName name) {
        return mbServer != null && mbServer.isRegistered(name);
    }

    public void loadGBean(ObjectName name, GBeanMBean gbean) throws InstanceAlreadyExistsException, InvalidConfigException {
        try {
            mbServer.registerMBean(gbean, name);
        } catch (MBeanRegistrationException e) {
            throw new InvalidConfigException("Invalid GBean configuration for " + name, e);
        } catch (NotCompliantMBeanException e) {
            throw new InvalidConfigException("Invalid GBean configuration for " + name, e);
        }
    }

    public void startGBean(ObjectName name) throws InstanceNotFoundException, InvalidConfigException {
        try {
            invoke(name, "start");
        } catch (Exception e) {
            throw new InvalidConfigException("Invalid GBean configuration for " + name, e);
        }
    }

    public void startRecursiveGBean(ObjectName name) throws InstanceNotFoundException, InvalidConfigException {
        try {
            invoke(name, "startRecursive");
        } catch (Exception e) {
            throw new InvalidConfigException("Invalid GBean configuration for " + name, e);
        }
    }

    public void stopGBean(ObjectName name) throws InstanceNotFoundException, InvalidConfigException {
        try {
            invoke(name, "stop");
        } catch (Exception e) {
            throw new InvalidConfigException("Invalid GBean configuration for " + name, e);
        }
    }

    public void unloadGBean(ObjectName name) throws InstanceNotFoundException {
        try {
            mbServer.unregisterMBean(name);
        } catch (MBeanRegistrationException e) {
            throw (IllegalStateException) new IllegalStateException("Error unloading GBean " + name).initCause(e);
        }
    }

    /**
     * Boot this Kernel, triggering the instantiation of the MBeanServer and
     * the registration of the DependencyService and ConfigurationStore
     * @throws java.lang.Exception if the boot fails
     */
    public void boot() throws Exception {
        if (running) {
            return;
        }
        log = LogFactory.getLog(Kernel.class.getName());
        log.info("Starting boot");

        if (kernelName != null) {
            synchronized (kernels) {
                kernels.put(kernelName, new KernelReference(kernelName, this));
            }
        }

        mbServer = MBeanServerFactory.createMBeanServer(domainName);
        mbServer.registerMBean(this, KERNEL);
        mbServer.registerMBean(new DependencyService(), DEPENDENCY_SERVICE);

        configurationManagerGBean = new GBeanMBean(ConfigurationManager.GBEAN_INFO);
        configurationManagerGBean.setReferencePatterns("Kernel", Collections.singleton(KERNEL));
        configurationManagerGBean.setReferencePatterns("Stores", Collections.singleton(CONFIGURATION_STORE_PATTERN));
        mbServer.registerMBean(configurationManagerGBean, CONFIGURATION_MANAGER_NAME);
        configurationManagerGBean.start();
        configurationManager = (ConfigurationManager) configurationManagerGBean.getTarget();

        running = true;
        log.info("Booted");
    }

    /**
     * Shut down this kernel instance, unregistering the MBeans and releasing
     * the MBeanServer.
     */
    public void shutdown() {
        if (!running) {
            return;
        }
        running = false;
        log.info("Starting kernel shutdown");

        configurationManager = null;
        configurationManagerGBean = null;
        try {
            if (configurationManagerGBean != null) {
                configurationManagerGBean.stop();
            }
        } catch (Exception e) {
            // ignore
        }
        try {
            if (configurationManagerGBean != null) {
                mbServer.unregisterMBean(CONFIGURATION_MANAGER_NAME);
            }
        } catch (Exception e) {
            // ignore
        }
        configurationManagerGBean = null;

        try {
            mbServer.unregisterMBean(KERNEL);
        } catch (Exception e) {
            // ignore
        }
        try {
            mbServer.unregisterMBean(DEPENDENCY_SERVICE);
        } catch (Exception e) {
            // ignore
        }

        MBeanServerFactory.releaseMBeanServer(mbServer);
        mbServer = null;
        synchronized (this) {
            notify();
        }

        if (kernelName != null) {
            synchronized (kernels) {
                kernels.remove(kernelName);
            }
        }

        log.info("Kernel shutdown complete");
    }

    public boolean isRunning() {
        return running;
    }

    private static void processQueue() {
        KernelReference kernelRef;
        while ((kernelRef = (KernelReference) queue.poll()) != null) {
            synchronized (kernels) {
                kernels.remove(kernelRef.key);
            }
        }
    }

    private static class KernelReference extends WeakReference {
        private final Object key;

        public KernelReference(Object key, Object kernel) {
            super(kernel, queue);
            this.key = key;
        }
    }
}
TOP

Related Classes of org.apache.geronimo.kernel.Kernel$KernelReference

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.