Package org.jboss.gravia.container.tomcat.support

Source Code of org.jboss.gravia.container.tomcat.support.TomcatResourceInstaller

/*
* #%L
* Gravia :: Container :: Tomcat :: Support
* %%
* Copyright (C) 2010 - 2014 JBoss by Red Hat
* %%
* 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.
* #L%
*/

package org.jboss.gravia.container.tomcat.support;

import static org.jboss.gravia.container.tomcat.support.GraviaTomcatLogger.LOGGER;

import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;

import org.apache.catalina.User;
import org.apache.catalina.UserDatabase;
import org.apache.catalina.ant.DeployTask;
import org.apache.catalina.ant.UndeployTask;
import org.apache.catalina.users.MemoryUserDatabase;
import org.jboss.gravia.container.tomcat.extension.SharedModuleClassLoader;
import org.jboss.gravia.provision.ResourceHandle;
import org.jboss.gravia.provision.ResourceInstaller;
import org.jboss.gravia.provision.spi.AbstractResourceHandle;
import org.jboss.gravia.provision.spi.AbstractResourceInstaller;
import org.jboss.gravia.provision.spi.RuntimeEnvironment;
import org.jboss.gravia.resource.Capability;
import org.jboss.gravia.resource.ContentCapability;
import org.jboss.gravia.resource.ContentNamespace;
import org.jboss.gravia.resource.DefaultResourceBuilder;
import org.jboss.gravia.resource.Requirement;
import org.jboss.gravia.resource.Resource;
import org.jboss.gravia.resource.ResourceBuilder;
import org.jboss.gravia.resource.ResourceContent;
import org.jboss.gravia.resource.ResourceIdentity;
import org.jboss.gravia.resource.Version;
import org.jboss.gravia.runtime.Module;
import org.jboss.gravia.runtime.Runtime;
import org.jboss.gravia.runtime.RuntimeLocator;
import org.jboss.gravia.runtime.spi.NamedResourceAssociation;
import org.jboss.gravia.utils.IOUtils;
import org.jboss.gravia.utils.ResourceUtils;

/**
* Service providing the {@link ResourceInstaller}.
*
* @author Thomas.Diesler@jboss.com
* @since 13-Jan-2014
*/
public class TomcatResourceInstaller extends AbstractResourceInstaller {

    private final static File catalinaHome = new File(SecurityActions.getSystemProperty("catalina.home", null));
    private final static File catalinaLib = new File(catalinaHome.getPath() + File.separator + "lib");
    private final static File catalinaTemp = new File(catalinaHome.getPath() + File.separator + "temp");

    private final static String TOMCAT_USER = "tomcat";

    private final UserDatabase userDatabase;
    private final RuntimeEnvironment environment;

    public TomcatResourceInstaller(RuntimeEnvironment environment) {
        this.environment = environment;
        try {
            userDatabase = new MemoryUserDatabase();
            userDatabase.open();
        } catch (Exception ex) {
            throw new IllegalStateException("Cannot open user database", ex);
        }
        if (userDatabase.findUser(TOMCAT_USER) == null)
            throw new IllegalStateException("Cannot obtain user: " + TOMCAT_USER);
    }

    @Override
    public RuntimeEnvironment getEnvironment() {
        return environment;
    }

    @Override
    public ResourceHandle installResourceProtected(Context context, Resource resource) throws Exception {
        ResourceHandle handle;
        if (ResourceUtils.isShared(resource)) {
            handle = installSharedResourceInternal(context, resource);
        } else {
            handle = installUnsharedResourceInternal(context, resource);
        }
        return handle;
    }

    private ResourceHandle installSharedResourceInternal(Context context, Resource resource) throws Exception {
        LOGGER.info("Installing shared resource: {}", resource);

        ResourceIdentity resid = resource.getIdentity();
        String symbolicName = resid.getSymbolicName();
        Version version = resid.getVersion();

        // copy resource content
        final File targetFile = new File(catalinaLib, symbolicName + "-" + version + ".jar");
        if (targetFile.exists()) {
            LOGGER.warn("Module already exists: " + targetFile);
        } else {
            ResourceContent content = getFirstRelevantResourceContent(resource);
            IOUtils.copyStream(content.getContent(), new FileOutputStream(targetFile));
        }

        // Install the shared module
        final Module module = installSharedResource(resource, targetFile);

        // Start the module
        module.start();

        final Resource modres = module.adapt(Resource.class);
        return new AbstractResourceHandle(modres, module) {
            @Override
            public void uninstall() {
                LOGGER.info("Uninstall shared resource: {}", modres);
                SharedModuleClassLoader.removeSharedModule(modres);
                module.uninstall();
                targetFile.delete();
            }
        };
    }

    private ResourceHandle installUnsharedResourceInternal(Context context, Resource resource) throws Exception {
        LOGGER.info("Install unshared resource: {}", resource);

        File tempfile = null;
        ResourceIdentity identity = resource.getIdentity();
        String runtimeName = getRuntimeName(resource);

        ContentCapability ccap = (ContentCapability) resource.getCapabilities(ContentNamespace.CONTENT_NAMESPACE).get(0);
        URL contentURL = ccap.getContentURL();
        if (contentURL == null || !contentURL.toExternalForm().startsWith("file:")) {
            ResourceContent content = getFirstRelevantResourceContent(resource);
            tempfile = new File(catalinaTemp, runtimeName);
            IOUtils.copyStream(content.getContent(), new FileOutputStream(tempfile));
            contentURL = tempfile.toURI().toURL();
        }

        // Get contextPath, username, password
        final String contextPath = getContextPath(resource);
        final User user = userDatabase.findUser(TOMCAT_USER);
        final String password = user.getPassword();

        NamedResourceAssociation.putResource(contextPath, resource);
        try {
            DeployTask task = new DeployTask();
            task.setWar(contentURL.toExternalForm());
            task.setUsername(user.getName());
            task.setPassword(password);
            task.setPath(contextPath);
            task.execute();
        } finally {
            NamedResourceAssociation.removeResource(contextPath);
            if (tempfile != null) {
                tempfile.delete();
            }
        }

        // Get the resource as module (may be null)
        Runtime runtime = RuntimeLocator.getRequiredRuntime();
        Module module = runtime.getModule(identity);

        Resource modres = module != null ? module.adapt(Resource.class) : resource;
        return new AbstractResourceHandle(modres, module) {
            @Override
            public void uninstall() {
                UndeployTask task = new UndeployTask();
                task.setUsername(user.getName());
                task.setPassword(password);
                task.setPath(contextPath);
                task.execute();
            }
        };
    }

    private Module installSharedResource(Resource resource, File targetFile) throws Exception {

        // Get a resource copy with updated content capability
        ResourceBuilder builder = new DefaultResourceBuilder();
        for (Capability cap : resource.getCapabilities(null)) {
            String namespace = cap.getNamespace();
            if (!ContentNamespace.CONTENT_NAMESPACE.equals(namespace)) {
                builder.addCapability(namespace, cap.getAttributes(), cap.getDirectives());
            }
        }
        builder.addContentCapability(targetFile.toURI().toURL());
        for (Requirement req : resource.getRequirements(null)) {
            builder.addRequirement(req.getNamespace(), req.getAttributes(), req.getDirectives());
        }
        resource = builder.getResource();

        // Add the module to the {@link SharedModuleClassLoader}
        SharedModuleClassLoader.addSharedModule(resource);

        Runtime runtime = RuntimeLocator.getRequiredRuntime();
        ClassLoader classLoader = SharedModuleClassLoader.class.getClassLoader();
        return runtime.installModule(classLoader, resource, null);
    }

    private String getContextPath(Resource res) {
        String contextPath = (String) res.getIdentityCapability().getAttribute("contextPath");
        if (contextPath == null)
            contextPath = res.getIdentity().getSymbolicName();
        return "/" + contextPath;
    }
}
TOP

Related Classes of org.jboss.gravia.container.tomcat.support.TomcatResourceInstaller

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.