Package org.servicemix.jbi.framework

Source Code of org.servicemix.jbi.framework.InstallationService

/**
* <a href="http://servicemix.org">ServiceMix: The open source ESB</a>
*
* Copyright 2005 RAJD Consultancy Ltd
*
* 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.servicemix.jbi.framework;
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.servicemix.jbi.container.ComponentEnvironment;
import org.servicemix.jbi.container.EnvironmentContext;
import org.servicemix.jbi.container.JBIContainer;
import org.servicemix.jbi.deployment.ClassPath;
import org.servicemix.jbi.deployment.Component;
import org.servicemix.jbi.deployment.Descriptor;
import org.servicemix.jbi.deployment.InstallationDescriptorExtension;
import org.servicemix.jbi.deployment.SharedLibrary;
import org.servicemix.jbi.deployment.SharedLibraryList;
import org.servicemix.jbi.management.BaseLifeCycle;
import org.servicemix.jbi.management.ManagementContext;
import org.servicemix.jbi.management.OperationInfoHelper;
import org.servicemix.jbi.management.ParameterHelper;
import org.servicemix.jbi.util.FileUtil;

import javax.jbi.JBIException;
import javax.jbi.management.DeploymentException;
import javax.jbi.management.InstallerMBean;
import javax.management.JMException;
import javax.management.MBeanOperationInfo;
import javax.management.ObjectName;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkException;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;

/**
* Installation Service - installs/uninstalls archives
*
* @version $Revision: 738 $
*/
public class InstallationService extends BaseLifeCycle implements FrameworkInstallationService {
    private static final Log log = LogFactory.getLog(InstallationService.class);
    private JBIContainer container;
    private EnvironmentContext environmentContext;
    private ManagementContext managementContext;
    private ClassLoaderService classLoaderService = new ClassLoaderService();
    private Map installers = new ConcurrentHashMap();

    /**
     * Get Description
     *
     * @return description of this item
     */
    public String getDescription() {
        return "installs/uninstalls Components";
    }

    /**
     * Load the installer for a new component from a component installation package.
     *
     * @param installJarURL - URL locating a jar file containing a JBI Installable Component.
     * @return - the JMX ObjectName of the InstallerMBean loaded from installJarURL.
     */
    public synchronized ObjectName loadNewInstaller(String installJarURL) {
        ObjectName result = null;
        try {
            File tmpDir = AutoDeploymentService.unpackLocation(environmentContext.getTmpDir(), installJarURL);
            if (tmpDir != null) {
                Descriptor root = AutoDeploymentService.buildDescriptor(tmpDir);
                if (root != null && root.getComponent() != null) {
                    String componentName = root.getComponent().getIdentification().getName();
                    if (!installers.containsKey(componentName)) {
                        InstallerMBeanImpl installer = doInstallArchive(tmpDir, root);
                        if (installer != null) {
                            result = installer.getObjectName();
                            installers.put(componentName, installer);
                        }
                    }
                    else {
                        log.error("An installer already exists for " + componentName);
                    }
                }
                else {
                    log.error("Could not find Component from: " + installJarURL);
                }
            }
            else {
                log.warn("location: " + installJarURL + " isn't valid");
            }
        }
        catch (DeploymentException e) {
            log.error("Deployment failed", e);
        }
        return result;
    }

    /**
     * Load the InstallerMBean for a previously installed component.
     *
     * @param aComponentName - the component name identifying the installer to load.
     * @return - the JMX ObjectName of the InstallerMBean loaded from an existing installation context.
     */
    public ObjectName loadInstaller(String aComponentName) {
        ObjectName result = null;
        InstallerMBeanImpl installer = (InstallerMBeanImpl) installers.get(aComponentName);
        if (installer != null) {
            result = installer.getObjectName();
        }
        return result;
    }

    /**
     * Unload a JBI Installable Component installer.
     *
     * @param componentName - the component name identifying the installer to unload.
     * @param isToBeDeleted - true if the component is to be deleted as well.
     * @return - true if the operation was successful, otherwise false.
     */
    public boolean unloadInstaller(String componentName, boolean isToBeDeleted) {
        boolean result = false;
        try {
            InstallerMBeanImpl installer = (InstallerMBeanImpl) installers.remove(componentName);
            result = installer != null;
            if (result && isToBeDeleted) {
                installer.uninstall();
                result = true;
            }
        }
        catch (JBIException e) {
            String errStr = "problem shutting down Component: " + componentName;
            log.error(errStr, e);
        }
        return result;
    }

    /**
     * Install a shared library jar.
     *
     * @param aSharedLibURI - URI locating a jar file containing a shared library.
     * @return - the name of the shared library loaded from aSharedLibURI.
     */
    public String installSharedLibrary(String aSharedLibURI) {
        String result = "";
        try {
            File tmpDir = AutoDeploymentService.unpackLocation(environmentContext.getTmpDir(), aSharedLibURI);
            if (tmpDir != null) {
                Descriptor root = AutoDeploymentService.buildDescriptor(tmpDir);
                SharedLibrary sl = root.getSharedLibrary();
                if (sl != null) {
                    result = doInstallSharedLibrary(tmpDir, sl);
                }
            }
            else {
                log.warn("location: " + aSharedLibURI + " isn't valid");
            }
        }
        catch (DeploymentException e) {
            log.error("Deployment failed", e);
        }
        return result;
    }

    /**
     * Uninstall a shared library.
     *
     * @param aSharedLibName - the name of the shared library to uninstall.
     * @return - true iff the uninstall was successful.
     */
    public boolean uninstallSharedLibrary(String aSharedLibName) {
        boolean result = false;
        classLoaderService.removeSharedLibrary(aSharedLibName);
        try {
            environmentContext.removeSharedLibraryDirectory(aSharedLibName);
            result = true;
        }
        catch (IOException e) {
            log.error("Failed to remove shared library directory");
        }
        return result;
    }

    /**
     * Initialize the Service
     *
     * @param container
     * @throws JBIException
     * @throws DeploymentException
     */
    public void init(JBIContainer container) throws JBIException {
        this.container = container;
        this.environmentContext = container.getEnvironmentContext();
        this.managementContext = container.getManagementContext();
        buildState();
        container.getManagementContext().registerSystemService(this, FrameworkInstallationService.class);
    }

    /**
     * Install an archive
     *
     * @param location
     * @throws DeploymentException
     */
    public void install(String location) throws DeploymentException {
        install(location, false);
    }

    /**
     * Install an archive
     *
     * @param location
     * @param autoStart
     * @throws DeploymentException
     */
    public void install(String location, boolean autoStart) throws DeploymentException {
        File tmpDir = AutoDeploymentService.unpackLocation(environmentContext.getTmpDir(), location);
        if (tmpDir != null) {
            Descriptor root = AutoDeploymentService.buildDescriptor(tmpDir);
            if (root != null) {
                install(tmpDir, root, autoStart);
            }
            else {
                log.error("Could not find Descriptor from: " + location);
            }
        }
        else {
            log.warn("location: " + location + " isn't valid");
        }
    }

    /**
     * Install an archive
     *
     * @param tmpDir
     * @param root
     * @param autoStart
     * @throws DeploymentException
     */
    protected void install(File tmpDir,Descriptor root,boolean autoStart) throws DeploymentException{
        if(root.getComponent() != null){
            String componentName = root.getComponent().getIdentification().getName();
            if(!installers.containsKey(componentName)){
                InstallerMBeanImpl installer = doInstallArchive(tmpDir,root);
                if(installer != null){
                    try{
                        installer.install();
                    }catch(JBIException e){
                        throw new DeploymentException(e);
                    }
                    if(autoStart){
                        try{
                            ComponentNameSpace cns = new ComponentNameSpace(container.getName(),componentName,
                                    componentName);
                            LocalComponentConnector lcc = container.getRegistry().getLocalComponentConnector(cns);
                            if(container.getRegistry().isLocalComponentRegistered(componentName)){
                                ComponentMBean mbean = lcc.getComponentMBean();
                                if(mbean != null){

                                    mbean.start();

                                }else{
                                    log.warn("No ComponentMBean found for Component " + componentName);
                                }
                            }else{
                                log.warn("No ComponentConnector found for Component " + componentName);
                            }
                        }catch(JBIException e){
                            String errStr = "Failed to start Component: " + componentName;
                            log.error(errStr,e);
                            throw new DeploymentException(e);
                        }

                    }
                    installers.put(componentName,installer);
                }
            }else{
                log.warn("Component " + componentName + " is already installed");
            }
        }
    }

    /**
     * Get an array of MBeanOperationInfo
     *
     * @return array of OperationInfos
     * @throws JMException
     */
    public MBeanOperationInfo[] getOperationInfos() throws JMException {
        OperationInfoHelper helper = new OperationInfoHelper();
        ParameterHelper ph = helper.addOperation(getObjectToManage(), "loadNewInstaller", 1, "load a new Installer ");
        ph.setDescription(0, "installJarURL", "URL locating the install Jar");
        ph = helper.addOperation(getObjectToManage(), "loadInstaller", 1,
                "load installer for a previously installed component");
        ph.setDescription(0, "componentName", "Name of the Component");
        ph = helper.addOperation(getObjectToManage(), "unloadInstaller", 2, "unload an installer");
        ph.setDescription(0, "componentName", "Name of the Component");
        ph.setDescription(1, "isToBeDeleted", "true if component is to be deleted");
        ph = helper.addOperation(getObjectToManage(), "installSharedLibrary", 1, "Install a shared library jar");
        ph.setDescription(0, "sharedLibURI", "URI for the jar to be installed");
        ph = helper.addOperation(getObjectToManage(), "uninstallSharedLibrary", 1, "Uninstall a shared library jar");
        ph.setDescription(0, "sharedLibName", "name of the shared library");
        ph = helper.addOperation(getObjectToManage(), "install", 1, "install and deplot an archive");
        ph.setDescription(0, "location", "location of archive");
        ph = helper.addOperation(getObjectToManage(), "install", 2, "install and deplot an archive");
        ph.setDescription(0, "location", "location of archive");
        ph.setDescription(1, "autostart", "automatically start the Component");
        return OperationInfoHelper.join(super.getOperationInfos(), helper.getOperationInfos());
    }

    protected InstallerMBeanImpl doInstallArchive(File tmpDirectory, Descriptor descriptor) throws DeploymentException {
        InstallerMBeanImpl installer = null;
        Component component = descriptor.getComponent();
        if (component != null) {
            installer = doInstallComponent(tmpDirectory, component);
        }
        return installer;
    }

    protected String doInstallSharedLibrary(File tmpDirectory, SharedLibrary descriptor) throws DeploymentException {
        String result = null;
        if (descriptor != null) {
            try {
                result = descriptor.getIdentification().getName();
                File installationDir = environmentContext.createSharedLibraryDirectory(result);
                if (installationDir.exists()) {
                    FileUtil.deleteFile(installationDir);
                }
                if (!tmpDirectory.renameTo(installationDir)) {
                    throw new DeploymentException("Unable to rename " + tmpDirectory + " to " + installationDir);
                }
                log.info("moved " + tmpDirectory + " to " + installationDir);
                classLoaderService.addSharedLibrary(installationDir, descriptor);
            }
            catch (IOException e) {
                log.error("Deployment of Shared Library failed", e);
                // remove any files created for installation
                environmentContext.removeComponentRootDirectory(descriptor.getIdentification().getName());
                throw new DeploymentException(e);
            }
        }
        return result;
    }

    protected InstallerMBeanImpl doInstallComponent(File tmpDirectory, Component descriptor) throws DeploymentException {
        // move archive to Component directory
        InstallerMBeanImpl result = null;
        String name = descriptor.getIdentification().getName();
        File installationDir;
        try {
            installationDir = environmentContext.getInstallationDirectory(name);
        }
        catch (IOException e) {
            throw new DeploymentException(e);
        }
        FileUtil.deleteFile(installationDir);
        tmpDirectory.renameTo(installationDir);
        log.info("moved " + tmpDirectory + " to " + installationDir);
        // create the Installation context
        result = initializeInstaller(installationDir, descriptor);
        return result;
    }

    private InstallerMBeanImpl initializeInstaller(File installationDir, Component descriptor)
            throws DeploymentException {
        InstallerMBeanImpl result = null;
        try {
            String name = descriptor.getIdentification().getName();
            InstallationContextImpl installationContext = new InstallationContextImpl();
            installationContext.setInstall(true);
            installationContext.setComponentName(name);
            installationContext.setComponentDescription(descriptor.getIdentification().getDescription());
            installationContext.setInstallRoot(installationDir);
            installationContext.setComponentClassName(descriptor.getComponentClassName());
            ClassPath cp = descriptor.getComponentClassPath();
            if (cp != null) {
                installationContext.setClassPathElements(cp.getPathElements());
            }
            // now build the ComponentContext
            installationContext.setContext(buildComponentContext(name));
            InstallationDescriptorExtension desc = descriptor.getDescriptorExtension();
            if (desc != null) {
                installationContext.setDescriptorExtension(desc.getDescriptorExtension());
            }
            installationContext.setBinding(descriptor.isBindingComponent());
            installationContext.setEngine(descriptor.isServiceEngine());
            // now we must initialize the boot strap class
            String bootstrapClassName = descriptor.getBootstrapClassName();
            ClassPath bootStrapClassPath = descriptor.getBootstrapClassPath();
            InstallationClassLoader bootstrapLoader = null;
            if (bootstrapClassName != null && bootstrapClassName.length() > 0) {
                boolean parentFirst = descriptor.isBootstrapClassLoaderDelegationParentFirst();
                bootstrapLoader = classLoaderService.buildClassLoader(installationDir, bootStrapClassPath
                        .getPathElements(), parentFirst);
            }
            SharedLibraryList[] lists = descriptor.getSharedLibraries();
            String componentClassName = descriptor.getComponentClassName();
            ClassPath componentClassPath = descriptor.getComponentClassPath();
            boolean parentFirst = descriptor.isComponentClassLoaderDelegationParentFirst();
            ClassLoader componentClassLoader = classLoaderService.buildClassLoader(installationDir, componentClassPath
                    .getPathElements(), parentFirst, lists);
            result = new InstallerMBeanImpl(container, installationContext, componentClassLoader, componentClassName,
                    bootstrapLoader, bootstrapClassName);
            // create an MBean for the installer
            ObjectName objectName = managementContext.createCustomComponentMBeanName(InstallerMBean.class.getName(),
                    name);
            result.setObjectName(objectName);
            managementContext.registerMBean(objectName, result, InstallerMBean.class,
                    "standard installation controls for a Component");
        }
        catch (Throwable e) {
            log.error("Deployment of Component failed", e);
            // remove any files created for installation
            environmentContext.removeComponentRootDirectory(descriptor.getIdentification().getName());
            throw new DeploymentException(e);
        }
        return result;
    }

    protected void buildState() {
        buildSharedLibs();
        buildComponents();
    }

    /**
     * returns true if a shared library is already installed
     *
     * @param name
     * @return true/false
     */
    protected boolean containsSharedLibrary(String name) {
        return classLoaderService.containsSharedLibrary(name);
    }

    protected void buildSharedLibs() {
        // walk through shared libaries and add then to the ClassLoaderService
        File top = environmentContext.getSharedLibDir();
        if (top.exists() && top.isDirectory()) {
            // directory structure is sharedlibraries/<lib name>stuff ...
            File[] files = top.listFiles();
            if (files != null) {
                for (int i = 0;i < files.length;i++) {
                    if (files[i].isDirectory()) {
                        Descriptor root = AutoDeploymentService.buildDescriptor(files[i]);
                        if (root != null) {
                            SharedLibrary sl = root.getSharedLibrary();
                            if (sl != null) {
                                try {
                                    classLoaderService.addSharedLibrary(files[i], sl);
                                }
                                catch (MalformedURLException e) {
                                    log.error("Failed to initialize sharted library", e);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    protected void buildComponents() {
        // walk through components and add then to the ClassLoaderService
        File top = environmentContext.getComponentsDir();
        if (top.exists() && top.isDirectory()) {
            // directory structure is components/<component name>/installation ...
            File[] files = top.listFiles();
            if (files != null) {
                for (int i = 0;i < files.length;i++) {
                    if (files[i].isDirectory()) {
                        final File directory = files[i];
                        try {
                            container.getWorkManager().doWork(new Work() {
                                public void release() {
                                }

                                public void run() {
                                    try {
                                        buildComponent(directory);
                                    }
                                    catch (DeploymentException e) {
                                        log.error("Could not build Component: " + directory.getName(), e);
                                        log.warn("Deleting Component directory: " + directory);
                                        FileUtil.deleteFile(directory);
                                    }
                                }
                            });
                        }
                        catch (WorkException e) {
                            log.error("Could not build Component: " + directory.getName(), e);
                            log.warn("Deleting Component directory: " + directory);
                            FileUtil.deleteFile(directory);
                        }
                    }
                }
            }
        }
    }

    protected void buildComponent(File componentDirectory) throws DeploymentException{
        try{
            File installationDirectory = environmentContext.getInstallationDirectory(componentDirectory.getName());
            Descriptor root = AutoDeploymentService.buildDescriptor(installationDirectory);
            if(root != null){
                Component desc = root.getComponent();
                if(desc != null){
                    String componentName = desc.getIdentification().getName();
                    if(!installers.containsKey(componentName)){
                        InstallerMBean installer = initializeInstaller(installationDirectory,desc);
                        if(installer != null){
                            if(installer != null){
                                try{
                                    installer.install();
                                }catch(JBIException e){
                                    throw new DeploymentException(e);
                                }
                                // now get and set running state
                                ComponentNameSpace cns = new ComponentNameSpace(container.getName(),componentName,
                                        componentName);
                                try{
                                    LocalComponentConnector lcc = container.getRegistry().getLocalComponentConnector(
                                            cns);
                                    if(lcc != null){

                                        lcc.setRunningState();

                                    }else{
                                        log.error("Failed to get LocalComponentConnector for Component: "
                                                + componentName);
                                    }
                                }catch(JBIException e){
                                    log.warn("Failed to set running state for Component: " + componentName);
                                }
                            }
                            installers.put(componentName,installer);
                            log.info("Created installer for existing component:  " + componentName);
                        }
                    }else{
                        log.warn("Component " + componentName + " is already installed");
                    }
                }
            }
        }catch(IOException e){
            throw new DeploymentException(e);
        }
    }

    protected ComponentContextImpl buildComponentContext(String name) throws IOException {
        ComponentNameSpace cns = new ComponentNameSpace(container.getName(), name, name);
        ComponentContextImpl context = new ComponentContextImpl(container, cns);
        ComponentEnvironment env  = new ComponentEnvironment();
    File componentRoot = environmentContext.getComponentRootDirectory(name);
    FileUtil.buildDirectory(componentRoot);
    File privateWorkspace = environmentContext.createWorkspaceDirectory(name);
    env.setWorkspaceRoot(privateWorkspace);
    env.setComponentRoot(componentRoot);
    context.setEnvironment(env);
        return context;
    }

    public void shutDown() throws JBIException {
        super.shutDown();
        container.getManagementContext().unregisterMBean(this);
    }
}
TOP

Related Classes of org.servicemix.jbi.framework.InstallationService

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.