Package org.wso2.carbon.server

Source Code of org.wso2.carbon.server.TomcatGenericWebappsDeployer

/*
* Copyright 2005-2007 WSO2, Inc. (http://wso2.com)
*
* 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.wso2.carbon.server;

import org.apache.catalina.Context;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.session.StandardManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.CarbonException;
import org.wso2.carbon.utils.multitenancy.CarbonContextHolder;

import java.io.File;
import java.lang.management.ManagementPermission;
import java.util.List;
import java.util.Map;

/**
* This deployer is responsible for deploying/undeploying/updating those webapps.
*
* @see org.wso2.carbon.server.TomcatServer
*/
@SuppressWarnings("unused")
public class TomcatGenericWebappsDeployer {

    private static Log log = LogFactory.getLog(TomcatGenericWebappsDeployer.class);

    private String webContextPrefix;
    private int tenantId;
    private String tenantDomain;

    private WebApplicationsHolder webappsHolder;

    /**
     * Constructor
     *
     * @param webContextPrefix The Web context prefix
     * @param tenantId The tenant ID of the tenant to whom this deployer belongs to
     * @param tenantDomain  The tenant domain of the tenant to whom this deployer belongs to
     * @param webappsHolder    WebApplicationsHolder
     */
    public TomcatGenericWebappsDeployer(String webContextPrefix,
                                        int tenantId,
                                        String tenantDomain,
                                        WebApplicationsHolder webappsHolder) {
        SecurityManager secMan = System.getSecurityManager();
        if (secMan != null) {
            secMan.checkPermission(new ManagementPermission("control"));
        }
        this.tenantId = tenantId;
        this.tenantDomain = tenantDomain;
        this.webContextPrefix = webContextPrefix;
        this.webappsHolder = webappsHolder;
    }

    /**
     * Deploy webapps
     *
     * @param webappFile The webapp file to be deployed
     * @param webContextParams  context-params for this webapp
     * @param applicationEventListeners Application event listeners
     * @throws CarbonException If a deployment error occurs
     */
    public void deploy(File webappFile,
                       List<WebContextParameter> webContextParams,
                       List<Object> applicationEventListeners) throws CarbonException {
        CarbonContextHolder currentCarbonContextHolder =
                CarbonContextHolder.getCurrentCarbonContextHolder();
        currentCarbonContextHolder.startTenantFlow();
        try {
            currentCarbonContextHolder.setTenantId(tenantId);
            currentCarbonContextHolder.setTenantDomain(tenantDomain);
            long lastModifiedTime = webappFile.lastModified();
            WebApplication deployedWebapp =
                    webappsHolder.getStartedWebapps().get(webappFile.getName());
            WebApplication undeployedWebapp =
                    webappsHolder.getStoppedWebapps().get(webappFile.getName());
            WebApplication faultyWebapp =
                    webappsHolder.getFaultyWebapps().get(webappFile.getName());
            if (deployedWebapp == null && faultyWebapp == null && undeployedWebapp == null) {
                handleHotDeployment(webappFile, webContextParams, applicationEventListeners);
            } else if (deployedWebapp != null &&
                    deployedWebapp.getLastModifiedTime() != lastModifiedTime) {
                handleHotUpdate(deployedWebapp, webContextParams, applicationEventListeners);
            } else if (faultyWebapp != null &&
                    faultyWebapp.getLastModifiedTime() != lastModifiedTime) {
                handleHotDeployment(webappFile, webContextParams, applicationEventListeners);
            }
        } finally {
            currentCarbonContextHolder.endTenantFlow();
        }
    }

    /**
     * Hot deploy a webapp. i.e., deploy a webapp that has newly become available.
     *
     * @param webapp The webapp WAR or directory that needs to be deployed
     * @param webContextParams ServletContext params for this webapp
     * @param applicationEventListeners Application event listeners
     * @throws CarbonException If an error occurs during deployment
     */
    private void handleHotDeployment(File webapp, List<WebContextParameter> webContextParams,
                                     List<Object> applicationEventListeners)
            throws CarbonException {
        String filename = webapp.getName();
        if (webapp.isDirectory()) {
            handleExplodedWebappDeployment(webapp, webContextParams, applicationEventListeners);
        } else if (filename.endsWith(".war")) {
            handleWarWebappDeployment(webapp, webContextParams, applicationEventListeners);
        }
    }

    /**
     * Handle the deployment of a an archive webapp. i.e., a WAR
     *
     * @param webappWAR The WAR webapp file
     * @param webContextParams ServletContext params for this webapp
     * @param applicationEventListeners Application event listeners
     * @throws CarbonException If a deployment error occurs
     */
    private void handleWarWebappDeployment(File webappWAR,
                                           List<WebContextParameter> webContextParams,
                                           List<Object> applicationEventListeners)
            throws CarbonException {
        String filename = webappWAR.getName();
        String warContext = "";
        if (filename.equals("ROOT.war")) {  // FIXME: This is not working for some reason!
            if (webContextPrefix != null && !webContextPrefix.endsWith("/")) {
                warContext = "/";
            }
        } else {
            warContext = filename.substring(0, filename.indexOf(".war"));
        }
        if (!warContext.equals("/") && webContextPrefix.length() == 0) {
            webContextPrefix = "/";
        }
        handleWebappDeployment(webappWAR, webContextPrefix + warContext,
                               webContextParams, applicationEventListeners);
    }

    /**
     * Handle the deployment of a an exploded webapp. i.e., a webapp deployed as a directory
     * & not an archive
     *
     * @param webappDir The exploded webapp directory
     * @param webContextParams ServletContext params for this webapp
     * @param applicationEventListeners Application event listeners
     * @throws CarbonException If a deployment error occurs
     */
    private void handleExplodedWebappDeployment(File webappDir,
                                                List<WebContextParameter> webContextParams,
                                                List<Object> applicationEventListeners)
            throws CarbonException {
        String filename = webappDir.getName();
        String warContext = "";
        if (filename.equals("ROOT")) {
            if (webContextPrefix != null && !webContextPrefix.endsWith("/")) {
                warContext = "/";
            }
        } else {
            warContext = filename;
        }
        if (!warContext.equals("/") && webContextPrefix.length() == 0) {
            webContextPrefix = "/";
        }
        handleWebappDeployment(webappDir, webContextPrefix + warContext,
                               webContextParams, applicationEventListeners);
    }

    private void handleWebappDeployment(File webappFile, String contextStr,
                                        List<WebContextParameter> webContextParams,
                                        List<Object> applicationEventListeners) throws CarbonException {
        String filename = webappFile.getName();
        try {
            Context context =
                    TomcatUtil.getTomcat().addWebapp(contextStr, webappFile.getAbsolutePath());
            context.setManager(new StandardManager()); // TODO: Must use a clusterable manager such as BackupManager
            context.setReloadable(false);
            WebApplication webapp = new WebApplication(context, webappFile);
            webapp.setServletContextParameters(webContextParams);
            webappsHolder.getStartedWebapps().put(filename, webapp);
            webappsHolder.getFaultyWebapps().remove(filename);
            registerApplicationEventListeners(applicationEventListeners, context);
            /*ErrorPage page = new ErrorPage();
            page.setErrorCode(503);
            page.setLocation("/503.jsp");
            context.addErrorPage(page);*/
            log.info("Deployed webapp: " + webapp);
        } catch (Exception e) {
            StandardContext context = new StandardContext();
            context.setName(webappFile.getName());
            WebApplication webapp = new WebApplication(context, webappFile);
            String msg = "Cannot deploy webapp: " + webapp;
            log.error(msg, e);
            webapp.setFaultReason(e);
            webappsHolder.getFaultyWebapps().put(filename, webapp);
            webappsHolder.getStartedWebapps().remove(filename);
            throw new CarbonException(msg, e);
        }
    }

    private void registerApplicationEventListeners(List<Object> applicationEventListeners,
                                                   Context context) {
        Object[] originalEventListeners = context.getApplicationEventListeners();
        Object[] newEventListeners = new Object[originalEventListeners.length + applicationEventListeners.size()];
        if (originalEventListeners.length != 0) {
            System.arraycopy(originalEventListeners, 0, newEventListeners, 0, originalEventListeners.length);
            int i = originalEventListeners.length;
            for (Object eventListener : applicationEventListeners) {
                newEventListeners[i++] = eventListener;
            }
        } else {
            newEventListeners =
                    applicationEventListeners.toArray(new Object[applicationEventListeners.size()]);
        }
        context.setApplicationEventListeners(newEventListeners);
    }

    /**
     * Hot update an existing webapp. i.e., reload or redeploy a webapp archive which has been
     * updated
     *
     * @param webApplication The webapp which needs to be hot updated
     * @param webContextParams ServletContext params for this webapp
     * @param applicationEventListeners Application event listeners
     * @throws CarbonException If a deployment error occurs
     */
    private void handleHotUpdate(WebApplication webApplication,
                                 List<WebContextParameter> webContextParams,
                                 List<Object> applicationEventListeners) throws CarbonException {
        File webappFile = webApplication.getWebappFile();
        if (webappFile.isDirectory()) {  // webapp deployed as an exploded directory
            webApplication.reload();
            webApplication.setServletContextParameters(webContextParams);
            webApplication.setLastModifiedTime(webappFile.lastModified());
        } else { // webapp deployed from WAR
            // NOTE: context.reload() does not work for webapps deployed from WARs. Hence, we
            // need to undeploy & redeploy.
            // See http://tomcat.apache.org/tomcat-5.5-doc/manager-howto.html#Reload An Existing Application
            undeploy(webApplication);
            handleWarWebappDeployment(webappFile, webContextParams, applicationEventListeners);
        }
        log.info("Redeployed webapp: " + webApplication);
    }

    /**
     * Handle undeployment.
     *
     * @param webappFile The webapp file to be undeployed
     * @throws CarbonException If an error occurs while undeploying webapp
     */
    public void undeploy(File webappFile) throws CarbonException {
        CarbonContextHolder currentCarbonContextHolder =
                CarbonContextHolder.getCurrentCarbonContextHolder();
        currentCarbonContextHolder.startTenantFlow();
        try {
            currentCarbonContextHolder.setTenantId(tenantId);
            currentCarbonContextHolder.setTenantDomain(tenantDomain);
            Map<String, WebApplication> deployedWebapps = webappsHolder.getStartedWebapps();
            String fileName = webappFile.getName();
            if (deployedWebapps.containsKey(fileName)) {
                undeploy(deployedWebapps.get(fileName));
            }

            clearFaultyWebapp(fileName);
        } finally {
            currentCarbonContextHolder.endTenantFlow();
        }
    }

    /**
     * Handle undeployment.
     *
     * @param webappFile The webapp file to be undeployed
     * @throws CarbonException If an error occurs while lazy unloading
     */
    public void lazyUnload(File webappFile) throws CarbonException {
        CarbonContextHolder currentCarbonContextHolder =
                CarbonContextHolder.getCurrentCarbonContextHolder();
        currentCarbonContextHolder.startTenantFlow();
        try {
            currentCarbonContextHolder.setTenantId(tenantId);
            currentCarbonContextHolder.setTenantDomain(tenantDomain);
            Map<String, WebApplication> deployedWebapps = webappsHolder.getStartedWebapps();
            String fileName = webappFile.getName();
            if (deployedWebapps.containsKey(fileName)) {
                deployedWebapps.get(fileName).lazyUnload();
            }

            clearFaultyWebapp(fileName);
        } finally {
            currentCarbonContextHolder.endTenantFlow();
        }
    }

    private void clearFaultyWebapp(String fileName) {
        Map<String, WebApplication> faultyWebapps = webappsHolder.getFaultyWebapps();
        if (faultyWebapps.containsKey(fileName)) {
            WebApplication faultyWebapp = faultyWebapps.get(fileName);
            faultyWebapps.remove(fileName);
            log.info("Removed faulty webapp " + faultyWebapp);
        }
    }

    /**
     * Undeploy a webapp
     *
     * @param webapp The webapp being undeployed
     * @throws CarbonException If an error occurs while undeploying
     */
    private void undeploy(WebApplication webapp) throws CarbonException {
        webappsHolder.undeployWebapp(webapp);
        log.info("Undeployed webapp: " + webapp);
    }
}
TOP

Related Classes of org.wso2.carbon.server.TomcatGenericWebappsDeployer

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.