Package org.wso2.carbon.core.multitenancy

Source Code of org.wso2.carbon.core.multitenancy.TenantAxisConfigurator

/*                                                                            
* Copyright 2004,2005 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.wso2.carbon.core.multitenancy;

import org.apache.axis2.AxisFault;
import org.apache.axis2.deployment.AxisConfigBuilder;
import org.apache.axis2.deployment.DeploymentConstants;
import org.apache.axis2.deployment.DeploymentEngine;
import org.apache.axis2.deployment.DeploymentException;
import org.apache.axis2.deployment.ModuleDeployer;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.AxisConfigurator;
import org.apache.axis2.engine.AxisObserver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.wso2.carbon.context.RegistryType;
import org.wso2.carbon.core.CarbonAxisConfigurator;
import org.wso2.carbon.core.deployment.DeploymentInterceptor;
import org.wso2.carbon.core.deployment.RegistryBasedRepository;
import org.wso2.carbon.core.deployment.RegistryBasedRepositoryUpdater;
import org.wso2.carbon.core.internal.CarbonCoreDataHolder;
import org.wso2.carbon.core.multitenancy.utils.TenantAxisUtils;
import org.wso2.carbon.core.util.ParameterUtil;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.carbon.utils.PreAxisConfigurationPopulationObserver;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.utils.WSO2Constants;
import org.wso2.carbon.utils.deployment.Axis2DeployerRegistry;
import org.wso2.carbon.utils.deployment.Axis2ModuleRegistry;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.Collection;

import static org.apache.axis2.transport.TransportListener.HOST_ADDRESS;

/**
* The tenant specific AxisConfigurator
*/
public class TenantAxisConfigurator extends DeploymentEngine implements AxisConfigurator {


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

    private Collection globallyEngagedModules = new ArrayList();

    private final AxisConfiguration mainAxisConfig;
    private final String tenantDomain;
    private final int tenantId;
    private final String repoLocation;
    private final UserRegistry registry;
    private final BundleContext bundleContext;
    private final Bundle[] moduleBundles;
    private final Bundle[] deployerBundles;

    @Deprecated
    public TenantAxisConfigurator(AxisConfiguration mainAxisConfig,
                                  String tenantDomain,
                                  int tenantId,
                                  UserRegistry registry) throws AxisFault {
        this.tenantDomain = tenantDomain;
        this.tenantId = tenantId;
        this.mainAxisConfig = mainAxisConfig;
        this.registry = registry;
        this.bundleContext = CarbonCoreDataHolder.getInstance().getBundleContext();
        this.moduleBundles =
                ((CarbonAxisConfigurator) mainAxisConfig.getConfigurator()).
                        getConfigItemHolder().getModuleBundles();
        this.deployerBundles =
                ((CarbonAxisConfigurator) mainAxisConfig.getConfigurator()).
                        getConfigItemHolder().getDeployerBundles();
        File tenantDir = new File(CarbonUtils.getCarbonTenantsDirPath() + File.separator + tenantId);
        if (!tenantDir.exists() && !tenantDir.mkdirs()) {
            log.warn("Could not create directory " + tenantDir.getAbsolutePath());
        }
        this.repoLocation = tenantDir.getAbsolutePath();

        // Use registry based deployer if necessary
        if (CarbonUtils.useRegistryBasedRepository()) {
            String registryPath = "/repository/deployment";
            new RegistryBasedRepository(registry,
                                        registryPath,
                                        repoLocation).updateFileSystemFromRegistry();
            RegistryBasedRepositoryUpdater.scheduleAtFixedRate(registry,
                                                               registryPath,
                                                               repoLocation, 0, 10);
        }
    }
   
    // New constructor is introduced to set the config and local registry separately

    public TenantAxisConfigurator(AxisConfiguration mainAxisConfig,
                                  String tenantDomain,
                                  int tenantId,
                                  UserRegistry configRegistry,
                                  UserRegistry localRegistry) throws AxisFault {
        this.tenantDomain = tenantDomain;
        this.tenantId = tenantId;
        this.mainAxisConfig = mainAxisConfig;
        this.registry = configRegistry;
        this.bundleContext = CarbonCoreDataHolder.getInstance().getBundleContext();
        this.moduleBundles =
                ((CarbonAxisConfigurator) mainAxisConfig.getConfigurator()).
                        getConfigItemHolder().getModuleBundles();
        this.deployerBundles =
                ((CarbonAxisConfigurator) mainAxisConfig.getConfigurator()).
                        getConfigItemHolder().getDeployerBundles();
        String filePath = MultitenantUtils.getAxis2RepositoryPath(tenantId);
        File tenantDir = new File(filePath);
        if (!tenantDir.exists() && !tenantDir.mkdirs()) {
            log.warn("Could not create directory " + tenantDir.getAbsolutePath());
        }
        this.repoLocation = filePath;

        // Use registry based deployer if necessary
        if (CarbonUtils.useRegistryBasedRepository()) {
            String registryPath = "/repository/deployment";
            new RegistryBasedRepository(localRegistry,
                                        registryPath,
                                        repoLocation).updateFileSystemFromRegistry();
            RegistryBasedRepositoryUpdater.scheduleAtFixedRate(localRegistry,
                                                               registryPath,
                                                               repoLocation, 0, 10);
        }
    }
   
    private String getTenantString(String tenantDomain, int tenantId) {
        return tenantDomain + "[" + tenantId + "]";
    }

    /**
     * First create a Deployment engine, use that to create an AxisConfiguration
     *
     * @return Axis Configuration
     * @throws AxisFault
     */
    public AxisConfiguration getAxisConfiguration() throws AxisFault {
        //ClassLoader origTccl = Thread.currentThread().getContextClassLoader();
        //Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
        log.info("Creating tenant AxisConfiguration for tenant: " +
                 getTenantString(tenantDomain, tenantId));
        SuperTenantCarbonContext.startTenantFlow();
        try {
            SuperTenantCarbonContext carbonContext = SuperTenantCarbonContext.getCurrentContext();
            carbonContext.setTenantId(tenantId);
            carbonContext.setTenantDomain(tenantDomain);
            if (log.isDebugEnabled()) {
                log.debug("Axis2 repo: " + repoLocation);
            }
            populateAxisConfig();
            addDeployer(new ModuleDeployer(), repoLocation + File.separator +
                                              "axis2modules", "mar");
            axisConfig.setConfigurator(this);

            //TODO: May need to set certain parameters into the AxisConfig

            // Hot deployment & update should be turned on for tenants
            axisConfig.addParameter(new Parameter(DeploymentConstants.TAG_HOT_DEPLOYMENT,
                                                  "true"));
            axisConfig.addParameter(new Parameter(DeploymentConstants.TAG_HOT_UPDATE,
                                                  "true"));

            globallyEngagedModules = axisConfig.getEngagedModules();
            loadRepository(repoLocation);

            for (Object globallyEngagedModule : globallyEngagedModules) {
                AxisModule module = (AxisModule) globallyEngagedModule;
                if (log.isDebugEnabled()) {
                    log.debug("Globally engaging module: " + module.getName());
                }
            }

            // Remove all the transports made available in the tenant's axis2.xml
            axisConfig.getTransportsOut().clear();

            // Remove all in-transports made available in the tenant's axis2.xml
            axisConfig.getTransportsIn().clear();

            // Add the transports that are made available in the main axis2.xml file
            TenantAxisUtils.setTenantTransports(mainAxisConfig, tenantDomain, axisConfig);


        } finally {
            SuperTenantCarbonContext.endTenantFlow();
            //Thread.currentThread().setContextClassLoader(origTccl);
        }
        return axisConfig;
    }

    private void populateAxisConfig() throws DeploymentException {
        InputStream axis2xmlStream = null;
        try {
            File tenantAxis2XML = new File(CarbonUtils.getAdvancedCarbonConfigDirPath() +
                                               File.separator + "tenant-axis2.xml");
            axis2xmlStream = new FileInputStream(tenantAxis2XML);
            axisConfig = populateAxisConfiguration(axis2xmlStream);
        } catch (FileNotFoundException e) {
            String msg = "Cannot read tenant-axis2.xml";
            log.error(msg, e);
            throw new DeploymentException(msg, e);
        } finally {
            try {
                if (axis2xmlStream != null) {
                    axis2xmlStream.close();
                }
            } catch (IOException e) {
                log.error("Could not close input stream to " +
                          DeploymentConstants.AXIS2_CONFIGURATION_RESOURCE, e);
            }
        }
    }

    public boolean isGlobalyEngaged(AxisModule axisModule) {
        String modName = axisModule.getName();
        for (Object globallyEngagedModule : globallyEngagedModules) {
            AxisModule module = (AxisModule) globallyEngagedModule;
            if (modName.startsWith(module.getName())) {
                return true;
            }
        }
        return false;
    }

    public void engageGlobalModules() throws AxisFault {
        engageModules();
    }

    public AxisConfiguration populateAxisConfiguration(InputStream in) throws DeploymentException {
        axisConfig = TenantAxisConfiguration.createInstance();
        SuperTenantCarbonContext carbonContext = SuperTenantCarbonContext.getCurrentContext(axisConfig);
        carbonContext.setTenantId(tenantId);
        carbonContext.setTenantDomain(tenantDomain);

        // Notify all observers
        if (bundleContext != null) {
            ServiceTracker tracker =
                    new ServiceTracker(bundleContext,
                                       PreAxisConfigurationPopulationObserver.class.getName(), null);
            tracker.open();
            Object[] services = tracker.getServices();
            if (services != null) {
                for (Object service : services) {
                    ((PreAxisConfigurationPopulationObserver) service).createdAxisConfiguration(axisConfig);
                }
            }
            tracker.close();
        }
        try {
            // Add the relevant AxisObservers to the tenantAxisConfig
            if (bundleContext != null) {
                ServiceTracker tracker =
                        new ServiceTracker(bundleContext, AxisObserver.class.getName(), null);
                tracker.open();
                ServiceReference[] serviceRefs = tracker.getServiceReferences();
                if (serviceRefs != null) {
                    for (ServiceReference serviceRef : serviceRefs) {
                        if (serviceRef.getProperty(MultitenantConstants.TENANT_ID) != null &&
                            tenantId == (Integer) serviceRef.getProperty(MultitenantConstants.TENANT_ID)) {
                            axisConfig.addObservers((AxisObserver) bundleContext.getService(serviceRef));
                        }
                    }
                }
                tracker.close();
            }

            // Set services dir
            String servicesDirName = "axis2services";
            File servicesDir = new File(repoLocation + File.separator + servicesDirName);
            if (!servicesDir.exists() && !servicesDir.mkdirs()) {
                throw new DeploymentException("Could not create services directory " +
                                              servicesDir.getAbsolutePath());
            }
            axisConfig.addParameter(new Parameter(DeploymentConstants.SERVICE_DIR_PATH,
                                                  servicesDirName));

            // Set modules dir
            String modulesDirName = "axis2modules";
            File modulesDir = new File(repoLocation + File.separator + modulesDirName);
            if(!modulesDir.exists() && !modulesDir.mkdirs()){
                throw new DeploymentException("Could not create modules directory " +
                                              modulesDir.getAbsolutePath());
            }
            axisConfig.addParameter(new Parameter(DeploymentConstants.MODULE_DRI_PATH,
                                                  modulesDirName));
        } catch (AxisFault e) {
            String msg =
                    "Cannot add DeploymentConstants.SERVICE_DIR_PATH or " +
                    "DeploymentConstants.MODULE_DIR_PATH parameters";
            log.error(msg, e);
            throw new DeploymentException(msg, e);
        }

        carbonContext.setRegistry(RegistryType.SYSTEM_CONFIGURATION, registry);
        try {
            // TODO: The governance system registry should be passed into the tenant axis
            // configurator like the config system registry - Senaka.
            carbonContext.setRegistry(RegistryType.SYSTEM_GOVERNANCE,
                    CarbonCoreDataHolder.getInstance().getRegistryService()
                            .getGovernanceSystemRegistry(tenantId));
        } catch (Exception ignored) {
            // We are not worried about the exception in here.
        }

        // The following two lines of code are kept for backward compatibility. Remove this once we
        // are certain that this is not required. -- Senaka.
        // Please also note that we no longer need to set the user realm to the configuration
        // explicitly.
        setRegistry();
        setUserRealm();

        // Add the DeploymentInterceptor for the tenant AxisConfigurations
        DeploymentInterceptor interceptor = new DeploymentInterceptor();
        interceptor.setRegistry(registry);
        interceptor.init(axisConfig);
        axisConfig.addObservers(interceptor);

        setHostName(axisConfig);

        //TCCL will be based on OSGi
        AxisConfigBuilder builder = new AxisConfigBuilder(in, axisConfig, this);
        builder.populateConfig();
        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException e) {
            String msg = "error in closing input stream";
            log.error(msg, e);
        }
        axisConfig.setConfigurator(this);
        moduleDeployer = new ModuleDeployer(axisConfig);
        new Axis2ModuleRegistry(axisConfig).register(moduleBundles);
        new Axis2DeployerRegistry(axisConfig).register(deployerBundles);
        return axisConfig;
    }

    @Override
    public void cleanup() {
        super.cleanup();
        if (CarbonUtils.useRegistryBasedRepository()) {
            RegistryBasedRepositoryUpdater.cancelTask(repoLocation);
        }
    }

    private void setRegistry() throws DeploymentException {
        Parameter param = new Parameter(WSO2Constants.CONFIG_SYSTEM_REGISTRY_INSTANCE, registry);
        try {
            axisConfig.addParameter(param);
        } catch (AxisFault axisFault) {
            throw new DeploymentException(axisFault.getMessage(), axisFault);
        }
    }

    private void setUserRealm() throws DeploymentException {
        Parameter param = new Parameter(WSO2Constants.USER_REALM_INSTANCE, registry.getUserRealm());
        try {
            axisConfig.addParameter(param);
        } catch (AxisFault axisFault) {
            throw new DeploymentException(axisFault.getMessage(), axisFault);
        }
    }

    private static void setHostName(AxisConfiguration axisConfig) throws DeploymentException {
        try {
            ServerConfiguration serverConfig = ServerConfiguration.getInstance();
            String hostName = serverConfig.getFirstProperty("HostName");
            if (hostName != null) {
                Parameter param = ParameterUtil.createParameter(HOST_ADDRESS, hostName);
                axisConfig.addParameter(param);
            }
        } catch (AxisFault axisFault) {
            throw new DeploymentException(axisFault.getMessage(), axisFault);
        }
    }
}
TOP

Related Classes of org.wso2.carbon.core.multitenancy.TenantAxisConfigurator

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.