Package org.wso2.carbon.core.init

Source Code of org.wso2.carbon.core.init.CarbonServerManager

/*
*  Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you 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.init;

import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.clustering.ClusteringAgent;
import org.apache.axis2.clustering.ClusteringConstants;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.TransportInDescription;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.ListenerManager;
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.TreeBidiMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.equinox.http.helper.FilterServletAdaptor;
import org.osgi.framework.*;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.base.CarbonContextHolderBase;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.base.ServerConfigurationException;
import org.wso2.carbon.bridge.FrameworkLauncherFactory;
import org.wso2.carbon.bridge.FrameworkRestarter;
import org.wso2.carbon.core.*;
import org.wso2.carbon.core.deployment.OSGiAxis2ServiceDeployer;
import org.wso2.carbon.core.deployment.RegistryBasedRepositoryUpdater;
import org.wso2.carbon.core.internal.CarbonCoreDataHolder;
import org.wso2.carbon.core.internal.CarbonCoreServiceComponent;
import org.wso2.carbon.core.internal.HTTPGetProcessorListener;
import org.wso2.carbon.core.multitenancy.MultitenantServerManager;
import org.wso2.carbon.core.multitenancy.SuperTenantCarbonContext;
import org.wso2.carbon.core.security.CarbonJMXAuthenticator;
import org.wso2.carbon.core.transports.CarbonServlet;
import org.wso2.carbon.core.transports.TransportPersistenceManager;
import org.wso2.carbon.core.util.HouseKeepingTask;
import org.wso2.carbon.core.util.ParameterUtil;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.registry.core.session.UserRegistry;
import org.wso2.carbon.user.core.UserRealm;
import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.utils.*;
import org.wso2.carbon.utils.deployment.Axis2ServiceRegistry;
import org.wso2.carbon.utils.multitenancy.CarbonContextHolder;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import javax.management.MBeanServer;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.servlet.Filter;
import javax.servlet.ServletException;
import javax.smartcardio.Card;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.lang.management.ManagementPermission;
import java.net.SocketException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

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


/**
* This class is responsible for managing the WSO2 Carbon server core. Handles server starting,
* restarting & shutting down.
*/
public final class CarbonServerManager implements Controllable {
    private static Log log = LogFactory.getLog(CarbonServerManager.class);

    private final Map<String, String> pendingItemMap = new ConcurrentHashMap<String, String>();

    private BundleContext bundleContext;

    private PreAxis2ConfigItemListener configItemListener;
    private PreAxis2RequiredServiceListener requiredServiceListener;
    private OSGiAxis2ServicesListener osgiAxis2ServicesListener;

    private Timer timer = new Timer();

    private final String CLIENT_REPOSITORY_LOCATION = "Axis2Config.ClientRepositoryLocation";
    private final String CLIENT_AXIS2_XML_LOCATION = "Axis2Config.clientAxis2XmlLocation";

    protected String serverName;

    private String carbonHome;
    private ServerConfiguration serverConfig;
    private Thread shutdownHook;
    public boolean isEmbedEnv = false;

    public String serverWorkDir;

    public String axis2RepoLocation;

    private ConfigurationContext serverConfigContext;
    private ConfigurationContext clientConfigContext;

    /**
     * Indicates whether the shutdown of the server was triggered by the Carbon shutdown hook
     */
    private volatile boolean isShutdownTriggeredByShutdownHook = false;
    private MultitenantServerManager multitenantServerManager;

    /**
     * The lock used when handling, pending items that the server waits for until it can commence
     * starting
     */
    private final Object pendingItemsLock = new Object();

    private CarbonCoreDataHolder dataHolder = CarbonCoreDataHolder.getInstance();

    public CarbonServerManager() {
    }

    /**
     * Start the CarbonServerManager
     *
     * @param context The CarbonCore BundleContext
     */
    public void start(BundleContext context) {
        // Need permissions in order to instantiate CarbonServerManager
        SecurityManager secMan = System.getSecurityManager();
        if (secMan != null) {
            secMan.checkPermission(new ManagementPermission("control"));
            new Timer("JavaSecPolicyUpdateTimer").
                    scheduleAtFixedRate(new TimerTask() {
                        public void run() {
                            java.security.Policy.getPolicy().refresh();
                        }
                    }, 120000, 5000);
        }

        if (System.getProperty(CarbonConstants.START_TIME) == null) {
            System.setProperty(CarbonConstants.START_TIME, System.currentTimeMillis() + "");
        }

        this.bundleContext = context;

        //Initializing ConfigItem Listener - Modules and Deployers
        configItemListener = new PreAxis2ConfigItemListener(bundleContext, this);

        //Initializing Required OSGi service listener
        requiredServiceListener = new PreAxis2RequiredServiceListener(bundleContext, this);

        osgiAxis2ServicesListener = new OSGiAxis2ServicesListener(bundleContext, this);

        populateListeners();

        if (configItemListener.registerBundleListener()) {
            configItemListener.start();
        }

        if (requiredServiceListener.registerServiceListener()) {
            requiredServiceListener.start();
        }

        if (osgiAxis2ServicesListener.registerBundleListener()) {
            osgiAxis2ServicesListener.start();
        }

        //check whether pending list is empty, If so initialize Carbon
        if (pendingItemMap.isEmpty()) {
            initializeCarbon();
        } else {
            //Scheduling timer to run if the required items are being delayed.
            timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    try {
                        if (!pendingItemMap.isEmpty()) {
                            log.warn("Carbon initialization is delayed due to the following unsatisfied items:");
                            for (String configItem : pendingItemMap.keySet()) {
                                log.warn("Waiting for required " + pendingItemMap.get(configItem) + ": " + configItem);
                            }
                        }
                    } catch (Exception ignored) {
                    }
                }
            }, 60000, 60000);
        }
    }

    /**
     * Populate both listeners with the relavent bundles
     */
    public void populateListeners() {
        Dictionary headers;
        String value;
        for (Bundle bundle : bundleContext.getBundles()) {
            headers = bundle.getHeaders();

            //Searching for a Deployer
            value = (String) headers.get(CarbonConstants.CarbonManifestHeaders.AXIS2_DEPLOYER);
            if (value != null) {
                configItemListener.addDeployerBundle(value, bundle);
            }

            //Searching for a Module
            value = (String) headers.get(CarbonConstants.CarbonManifestHeaders.AXIS2_MODULE);
            if (value != null) {
                configItemListener.addModuleBundle(value, bundle);
            }

            // Searching for Axis2 services defined as OSGi bundles
            Enumeration entries = bundle.findEntries("META-INF", "*services.xml", true);
            if (entries != null && entries.hasMoreElements()) {
                osgiAxis2ServicesListener.addOSGiAxis2Service(bundle);
            }

            //Searching for a pre Axis2 required OSGi service before
            value = (String) headers.get(CarbonConstants.CarbonManifestHeaders.AXIS2_INIT_REQUIRED_SERVICE);
            if (value != null) {
                requiredServiceListener.addRequiredServiceBundle(bundle, value);
            }
        }
    }

    void addPendingItem(String requiredItemName, String itemType) {
        synchronized (pendingItemsLock) {
            if (log.isDebugEnabled()) {
                log.debug("Pending Item added : " + requiredItemName);
            }
            pendingItemMap.put(requiredItemName, itemType);
        }
    }

    void removePendingItem(String requiredItemName) {
        synchronized (pendingItemsLock) {
            if (pendingItemMap.containsKey(requiredItemName)) {
                if (log.isDebugEnabled()) {
                    log.debug("Pending Item removed : " + requiredItemName);
                }
                pendingItemMap.remove(requiredItemName);
                if (pendingItemMap.isEmpty()) {
                    initializeCarbon();
                }
            }
        }
    }

    private void initializeCarbon() {

        // Reset the SAAJ Interfaces
        System.getProperties().remove("javax.xml.soap.MessageFactory");
        System.getProperties().remove("javax.xml.soap.SOAPConnectionFactory");

        //remove bundlelistener and service listener
        configItemListener.unregisterBundleListener();
        requiredServiceListener.unregisterServiceListener();
        osgiAxis2ServicesListener.unregisterBundleListener();

        //Cancelling the timer task
        timer.cancel();

        try {
            log.info("Starting Carbon initialization...");

            // Location for expanding web content within AAR files
            String webLocation = System.getProperty(CarbonConstants.WEB_RESOURCE_LOCATION);
            if (webLocation == null) {
                webLocation = System.getProperty("carbon.home") + File.separator +
                        "repository" + File.separator + "deployment" +
                        File.separator + "server" +
                        File.separator + "webapps" +
                        File.separator + "wservices";
            }

            String temp = System.getProperty(ServerConstants.STANDALONE_MODE);
            if (temp != null) {
                temp = temp.trim();
                isEmbedEnv = temp.equals("true");
            } else {
                isEmbedEnv = false;
            }

            serverConfig = ServerConfiguration.getInstance();

            //Checking Carbon home
            carbonHome = System.getProperty(ServerConstants.CARBON_HOME);
            if (carbonHome == null) {
                String msg = ServerConstants.CARBON_HOME +
                        "System property has not been set.";
                log.fatal(msg);
                log.fatal(serverName + " startup failed.");
                throw new ServletException(msg);
            }

            try {
                System.setProperty(ServerConstants.LOCAL_IP_ADDRESS, NetworkUtils.getLocalHostname());
            } catch (SocketException ignored) {
            }

            initServerConfiguration();
            serverName = serverConfig.getFirstProperty("Name");


            String hostName = serverConfig.getFirstProperty("ClusteringHostName");
            if (System.getProperty(ClusteringConstants.LOCAL_IP_ADDRESS) == null &&
                    hostName != null && hostName.trim().length() != 0) {
                System.setProperty(ClusteringConstants.LOCAL_IP_ADDRESS, hostName);
            }

            // Set the JGroups bind address for the use of the Caching Implementation based on
            // Infinispan.
            if (System.getProperty("bind.address") == null) {
                System.setProperty("bind.address",
                        (hostName != null && hostName.trim().length() != 0) ?
                                hostName.trim() : NetworkUtils.getLocalHostname());
            }
            // Initialize the distributed cache for the super-tenant at start-up. If not, the first
            // few cache look-ups will result in misses, until the cache manager joins the cluster.
            SuperTenantCarbonContext.getCurrentContext().getCache();

            serverWorkDir =
                    new File(serverConfig.getFirstProperty("WorkDirectory")).getAbsolutePath();
            System.setProperty("axis2.work.dir", serverWorkDir);

            setAxis2RepoLocation();

            Axis2ConfigItemHolder configItemHolder = new Axis2ConfigItemHolder();
            configItemHolder.setDeployerBundles(configItemListener.getDeployerBundles());
            configItemHolder.setModuleBundles(configItemListener.getModuleBundles());

            String carbonContextRoot = serverConfig.getFirstProperty("WebContextRoot");

            CarbonAxisConfigurator carbonAxisConfigurator = new CarbonAxisConfigurator();
            carbonAxisConfigurator.setAxis2ConfigItemHolder(configItemHolder);
            carbonAxisConfigurator.setBundleContext(bundleContext);
            carbonAxisConfigurator.setCarbonContextRoot(carbonContextRoot);
            if (!carbonAxisConfigurator.isInitialized()) {
                carbonAxisConfigurator.init(axis2RepoLocation, webLocation);
            }

            //This is the point where we initialize Axis2.
            long start = System.currentTimeMillis();
            log.info("Creating super-tenant Axis2 ConfigurationContext");
            serverConfigContext =
                    CarbonConfigurationContextFactory.
                            createNewConfigurationContext(carbonAxisConfigurator, bundleContext);
            long end = System.currentTimeMillis();
            log.info("Completed super-tenant Axis2 ConfigurationContext creation in " +
                    ((double) (end - start) / 1000) + " sec");

            // Initialize ListenerManager
            ListenerManager listenerManager = serverConfigContext.getListenerManager();
            if (listenerManager == null) {
                listenerManager = new ListenerManager();
                listenerManager.init(serverConfigContext);
            }

            serverConfigContext.setContextRoot(carbonContextRoot);

            // At this point all the services and modules are deployed
            // Therefore it is time to allows other deployers to be registered.
            carbonAxisConfigurator.addAxis2ConfigServiceListener();

            initNetworkUtils(serverConfigContext.getAxisConfiguration());


            // Enabling http binding generation
            Parameter enableHttp = new Parameter("enableHTTP", "true");
            AxisConfiguration axisConfig = serverConfigContext.getAxisConfiguration();
            axisConfig.addParameter(enableHttp);

            new TransportPersistenceManager(axisConfig).
                    updateEnabledTransports(axisConfig.getTransportsIn().values(),
                            axisConfig.getTransportsOut().values());

            runInitializers();

            populateConnectionProperties();

            new JMXServerManager().startJMXService();

            serverConfigContext.setProperty(Constants.CONTAINER_MANAGED, "true");
            serverConfigContext.setProperty(ServerConstants.WORK_DIR, serverWorkDir);
            // This is used inside the sever-admin component.
            serverConfigContext.setProperty(ServerConstants.CARBON_INSTANCE, this);

            multitenantServerManager = new MultitenantServerManager();
            multitenantServerManager.start();

            //TODO As a tempory solution this part is added here. But when ui bundle are seperated from the core bundles
            //TODO this should be fixed.
            ServerConfiguration config = ServerConfiguration.getInstance();
            String type = config.getFirstProperty("Security.TrustStore.Type");
            String password = config.getFirstProperty("Security.TrustStore.Password");
            String storeFile = new File(config.getFirstProperty("Security.TrustStore.Location")).getAbsolutePath();

            System.setProperty("javax.net.ssl.trustStore", storeFile);
            System.setProperty("javax.net.ssl.trustStoreType", type);
            System.setProperty("javax.net.ssl.trustStorePassword", password);

            addShutdownHook();
            registerHouseKeepingTask(serverConfigContext);

            // Creating the Client side configuration context
            clientConfigContext = getClientConfigurationContext();

            //TOa house keeping taskDO add this map to a house keeping task
            //Adding FILE_RESOURCE_MAP
            Object property = new TreeBidiMap();
            clientConfigContext.setProperty(ServerConstants.FILE_RESOURCE_MAP, property);
            clientConfigContext.setContextRoot(carbonContextRoot);

            //Deploying Web service which resides in bundles
            Axis2ServiceRegistry serviceRegistry = new Axis2ServiceRegistry(serverConfigContext);
            serviceRegistry.register(bundleContext.getBundles());
            new OSGiAxis2ServiceDeployer(serverConfigContext, bundleContext).registerBundleListener(); // This will register the OSGi bundle listener

            HttpService httpService = dataHolder.getHttpService();
            HttpContext defaultHttpContext = httpService.createDefaultHttpContext();

            registerCarbonServlet(httpService, defaultHttpContext);

            RealmService realmService = dataHolder.getRealmService();
            UserRealm teannt0Realm = realmService.getBootstrapRealm();
            CarbonJMXAuthenticator.setUserRealm(teannt0Realm);

            log.info("Repository       : " + axis2RepoLocation);

            //Registering the configuration contexts as an OSGi service.
            start = System.currentTimeMillis();
            bundleContext.registerService(ConfigurationContextService.class.getName(),
                    new ConfigurationContextService(serverConfigContext,
                            clientConfigContext),
                    null);
            end = System.currentTimeMillis();
            log.info("ConfigurationContextService registered in " + (end - start) + "ms");

            //Registering ServerConfiguration as an OSGi service
            bundleContext.registerService(ServerConfiguration.class.getName(), serverConfig, null);

            if (CarbonUtils.useRegistryBasedRepository()) {
                log.info("Using registry based repository");
                UserRegistry userRegistry =
                        dataHolder.getRegistryService().getLocalRepository();
                RegistryBasedRepositoryUpdater.scheduleAtFixedRate(userRegistry,
                        "/repository/deployment/server",
                        axis2RepoLocation, 0, 10);
            }

//            log.info("Successfully initialized WSO2 Carbon");
        } catch (Throwable e) {
            log.fatal("WSO2 Carbon initialization Failed", e);
        }
    }

    private void registerCarbonServlet(HttpService httpService, HttpContext defaultHttpContext)
            throws ServletException, NamespaceException, InvalidSyntaxException {
        if (!"false".equals(serverConfig.getFirstProperty("RequireCarbonServlet"))) {
            CarbonServlet carbonServlet = new CarbonServlet(serverConfigContext);
            String servicePath = "/services";
            String path = serverConfigContext.getServicePath();
            if (path != null) {
                servicePath = path.trim();
            }
            if (!servicePath.startsWith("/")) {
                servicePath = "/" + servicePath;
            }
            ServiceReference filterServiceReference = bundleContext.getServiceReference(Filter.class.getName());
            if (filterServiceReference != null) {
                Filter filter = (Filter) bundleContext.getService(filterServiceReference);
                httpService.registerServlet(servicePath, new FilterServletAdaptor(filter, null, carbonServlet), null, defaultHttpContext);
            } else {
                httpService.registerServlet(servicePath, carbonServlet, null, defaultHttpContext);
            }
            HTTPGetProcessorListener getProcessorListener =
                    new HTTPGetProcessorListener(carbonServlet, bundleContext);
            // Check whether there are any services that expose HTTPGetRequestProcessors
            ServiceReference[] getRequestProcessors =
                    bundleContext.getServiceReferences(null,
                            "(" + CarbonConstants.HTTP_GET_REQUEST_PROCESSOR_SERVICE + "=*)");

            // If there are any we need to register them explicitly
            if (getRequestProcessors != null) {
                for (ServiceReference getRequestProcessor : getRequestProcessors) {
                    getProcessorListener.addHTTPGetRequestProcessor(getRequestProcessor,
                            ServiceEvent.REGISTERED);
                }
            }

            // We also add a service listener to make sure we react to changes in the bundles that
            // expose HTTPGetRequestProcessors
            bundleContext.addServiceListener(getProcessorListener,
                    "(" + CarbonConstants.HTTP_GET_REQUEST_PROCESSOR_SERVICE + "=*)");
        }
    }

    private ConfigurationContext getClientConfigurationContext() throws AxisFault {
        String clientRepositoryLocation =
                serverConfig.getFirstProperty(CLIENT_REPOSITORY_LOCATION);
        String clientAxis2XmlLocationn = serverConfig.getFirstProperty(CLIENT_AXIS2_XML_LOCATION);
        ConfigurationContext clientConfigContext =
                ConfigurationContextFactory.createConfigurationContextFromFileSystem(
                        clientRepositoryLocation, clientAxis2XmlLocationn);
        registerHouseKeepingTask(clientConfigContext);
        clientConfigContext.setProperty(ServerConstants.WORK_DIR, serverWorkDir);
        return clientConfigContext;
    }

    private void setAxis2RepoLocation() {
        if (System.getProperty("axis2.repo") != null) {
            axis2RepoLocation = System.getProperty("axis2.repo");
            /* First see whether this is the -n scenario */
            if (CarbonUtils.isMultipleInstanceCase()) {
                /* Now check whether this is a ChildNode or not, if this is the
                   a ChildNode we do not deploy services to this */
                if (!CarbonUtils.isChildNode()) {
                    axis2RepoLocation = CarbonUtils.getCarbonHome();
                }
            }
            serverConfig.setConfigurationProperty(ServerConfiguration.AXIS2_CONFIG_REPO_LOCATION,
                    axis2RepoLocation);
        } else {
            axis2RepoLocation = serverConfig
                    .getFirstProperty(ServerConfiguration.AXIS2_CONFIG_REPO_LOCATION);
        }

        if (!axis2RepoLocation.endsWith("/")) {
            serverConfig.setConfigurationProperty(ServerConfiguration.AXIS2_CONFIG_REPO_LOCATION,
                    axis2RepoLocation + "/");
            axis2RepoLocation = axis2RepoLocation + "/";
        }
    }

    private void initServerConfiguration() throws ServletException {
        File carbonXML = new File(CarbonUtils.getServerXml());
        InputStream in = null;
        try {
            in = new FileInputStream(carbonXML);
            serverConfig.forceInit(in);
        } catch (ServerConfigurationException e) {
            String msg = "Could not initialize server configuration";
            log.fatal(msg);
            throw new ServletException(msg);
        } catch (FileNotFoundException e) {
            throw new ServletException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.warn("Cannot close FileInputStream of file " + carbonXML.getAbsolutePath());
                }
            }
        }
    }

    private void populateConnectionProperties() throws Exception {
        RegistryService registryService = dataHolder.getRegistryService();
        Registry registry = registryService.getConfigSystemRegistry();
        Resource resource = registry.newResource();
        String contextRoot = serverConfigContext.getContextRoot();
        String servicePath = serverConfigContext.getServicePath();
        resource.setProperty("service-path", servicePath);
        resource.setProperty("bundleContext-root", contextRoot);
        String requestIP =
                org.apache.axis2.util.Utils.getIpAddress(serverConfigContext.getAxisConfiguration());
        resource.setProperty("host-name", requestIP);
        registry.put(RegistryResources.CONNECTION_PROPS, resource);
        resource.discard();
    }

    public void stopListenerManager() throws AxisFault {
        try {
            ListenerManager listenerManager = dataHolder.getListenerManager();
            if (listenerManager != null) {
                listenerManager.destroy();
            }

            //we need to call this method to clean the temp files we created.
            if (serverConfigContext != null) {
                serverConfigContext.terminate();
            }
        } catch (Exception e) {
            log.error("Exception occurred while shutting down listeners", e);
        }
    }

    private void registerHouseKeepingTask(ConfigurationContext configurationContext) {
        if (Boolean.valueOf(serverConfig.getFirstProperty("HouseKeeping.AutoStart"))) {
            Timer houseKeepingTimer = new Timer();
            long houseKeepingInterval =
                    Long.parseLong(serverConfig.
                            getFirstProperty("HouseKeeping.Interval")) * 60 * 1000;
            Object property =
                    configurationContext.getProperty(ServerConstants.FILE_RESOURCE_MAP);
            if (property == null) {
                property = new TreeBidiMap();
                configurationContext.setProperty(ServerConstants.FILE_RESOURCE_MAP, property);
            }
            houseKeepingTimer.
                    scheduleAtFixedRate(new HouseKeepingTask(serverWorkDir, (BidiMap) property),
                            houseKeepingInterval,
                            houseKeepingInterval);
        }
    }

    private void runInitializers() throws ServerException {

        String[] initializers =
                serverConfig.getProperties("ServerInitializers.Initializer");
        for (String clazzName : initializers) {
            try {
                Class clazz = bundleContext.getBundle().loadClass(clazzName);
                ServerInitializer intializer = (ServerInitializer) clazz.newInstance();
                if (log.isDebugEnabled()) {
                    log.debug("Using ServerInitializer " + intializer.getClass().getName());
                }
                intializer.init(serverConfigContext);
            } catch (Exception e) {
                throw new ServerException(e);
            }
        }
    }

    private static String getProperty(String name) {
        return System.getProperty(name);
    }

    private void initNetworkUtils(AxisConfiguration axisConfiguration)
            throws AxisFault, SocketException {
        String hostName = serverConfig.getFirstProperty("HostName");
        if (hostName != null) {
            Parameter param = axisConfiguration.getParameter(HOST_ADDRESS);
            if (param != null) {
                param.setEditable(true);
                param.setValue(hostName);
            } else {
                param = ParameterUtil.createParameter(HOST_ADDRESS, hostName);
                axisConfiguration.addParameter(param);
            }
        } else {
            Parameter param = axisConfiguration.getParameter(HOST_ADDRESS);
            if (param != null) {
                hostName = (String) param.getValue();
                log.info(HOST_ADDRESS + " has been selected from Axis2.xml.");
            }
        }
        NetworkUtils.init(hostName);
    }

    public void restart() {
        restart(false);
    }

    public void restartGracefully() {
        restart(true);
    }

    /**
     * Restart the Carbon server
     *
     * @param isGraceful True, if the server should be gracefully restarted, false, if a
     *                   restart should be forced
     */
    private void restart(boolean isGraceful) {
        SecurityManager secMan = System.getSecurityManager();
        if (secMan != null) {
            secMan.checkPermission(new ManagementPermission("control"));
        }
        Runtime.getRuntime().removeShutdownHook(shutdownHook);
        new JMXServerManager().stopJmxService();

        try {
            ServerStatus.setServerRestarting();

            Map<String, TransportInDescription> inTransports =
                    serverConfigContext.getAxisConfiguration().getTransportsIn();
            String serverName = ServerConfiguration.getInstance().getFirstProperty("Name");
            if (isGraceful) {
                log.info("Gracefully restarting " + serverName + "...");
                new ServerManagement(inTransports, serverConfigContext).startMaintenance();
            } else {
                log.info("Restarting " + serverName + "...");
            }
            try {
                ServerStatus.setServerRestarting();
            } catch (AxisFault e) {
                String msg = "Cannot set server to restarting mode";
                log.error(msg, e);
            }
            MBeanRegistrar.unregisterAllMBeans();
            CarbonContextHolderBase.unloadTenant(MultitenantConstants.SUPER_TENANT_ID);
            ClusteringAgent clusteringAgent =
                    serverConfigContext.getAxisConfiguration().getClusteringAgent();
            if (clusteringAgent != null) {
                clusteringAgent.finalize();
            }
            if (!CarbonUtils.isRunningInStandaloneMode()) {
                int waitFor = 5;
                log.info("Waiting for " + waitFor + " sec before initiating restart");
                Thread.sleep(waitFor * 1000); // The H2 DB connections do not get closed if this is not done
            }
            new Thread(new FrameworkRestarter()).start();
        } catch (Exception e) {
            String msg = "Cannot set server to restarting mode";
            log.error(msg, e);
        }
    }

    /**
     * Forced shutdown
     */
    public void shutdown() {
        SecurityManager secMan = System.getSecurityManager();
        if (secMan != null) {
            secMan.checkPermission(new ManagementPermission("control"));
        }
        log.info("Shutting down " + serverName + "...");
        if (!isShutdownTriggeredByShutdownHook) {
            Runtime.getRuntime().removeShutdownHook(shutdownHook);
        }
        try {
            try {
                ServerStatus.setServerShuttingDown();
            } catch (AxisFault e) {
                String msg = "Cannot set server to shutdown mode";
                log.error(msg, e);
            }
            CarbonCoreServiceComponent.shutdown();
            stopListenerManager();
            new JMXServerManager().stopJmxService();
            log.info("Shutting down OSGi framework...");
            FrameworkLauncherFactory.getFrameworkLauncher().stop();
            log.info("Shutdown complete");
            log.info("Halting JVM");
            if (!isShutdownTriggeredByShutdownHook) {
                System.exit(0);
            }
        } catch (Exception e) {
            log.error("Error occurred while shutting down " + serverName, e);
            if (!isShutdownTriggeredByShutdownHook) {
                System.exit(1);
            }
        }
    }

    /**
     * Graceful shutdown
     */
    public void shutdownGracefully() {
        try {
            ServerStatus.setServerShuttingDown();
        } catch (Exception e) {
            String msg = "Cannot set server to shutdown mode";
            log.error(msg, e);
        }
        try {
            log.info("Gracefully shutting down " + serverName + "...");
            Map<String, TransportInDescription> inTransports =
                    serverConfigContext.getAxisConfiguration().getTransportsIn();
            new ServerManagement(inTransports, serverConfigContext).startMaintenance();
        } catch (Exception e) {
            String msg = "Cannot put transports into maintenance mode";
            log.error(msg, e);
        }
        shutdown();
    }

    private void addShutdownHook() {
        if (shutdownHook != null) {
            return;
        }
        shutdownHook = new Thread() {
            public void run() {
                isShutdownTriggeredByShutdownHook = true;
                shutdownGracefully();
            }
        };
        Runtime.getRuntime().addShutdownHook(shutdownHook);
    }

    /**
     * Stop the Carbon server
     *
     * @throws Exception If an error occurs while stopping
     */
    public void stop() throws Exception {
        log.info("Stopping CarbonServerManager...");
        FileManipulator.deleteDir(new File(carbonHome + File.separator +
                serverConfig.getFirstProperty("WorkDirectory")));
        if (serverConfigContext != null) {
            Object property = serverConfigContext.getProperty(ServerConstants.FILE_RESOURCE_MAP);
            if (property != null) {
                ((Map) property).clear();
            }
        }

        MBeanRegistrar.unregisterAllMBeans();

        this.configItemListener = null;
        this.osgiAxis2ServicesListener = null;
        this.requiredServiceListener = null;
        this.shutdownHook = null;
        CarbonConfigurationContextFactory.clear();
        multitenantServerManager.cleanup();
        if (CarbonUtils.useRegistryBasedRepository()) {
            RegistryBasedRepositoryUpdater.cleanup();
        }
        if (serverConfigContext != null) {
            serverConfigContext.removeProperty(ServerConstants.CARBON_INSTANCE);
            serverConfigContext.removeProperty(WSO2Constants.PRIMARY_BUNDLE_CONTEXT);
            serverConfigContext.terminate();
        }
        if (clientConfigContext != null) {
            clientConfigContext.terminate();
        }
        serverConfigContext = null;
        clientConfigContext = null;
    }



}
TOP

Related Classes of org.wso2.carbon.core.init.CarbonServerManager

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.