Package io.fabric8.process.manager.service

Source Code of io.fabric8.process.manager.service.ProcessServiceFactory

/**
*  Copyright 2005-2014 Red Hat, Inc.
*
*  Red Hat 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 io.fabric8.process.manager.service;

import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import io.fabric8.process.manager.Installation;
import io.fabric8.process.manager.InstallOptions;
import io.fabric8.process.manager.InstallTask;
import io.fabric8.process.manager.ProcessController;
import io.fabric8.process.manager.ProcessManager;
import org.osgi.framework.BundleContext;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedServiceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.MalformedURLException;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

/**
* A {@link ManagedServiceFactory} for managing processes using {@link io.fabric8.process.manager.ProcessManager ProcessManager}.
*
*/
public class ProcessServiceFactory implements ManagedServiceFactory {

    protected final Logger LOG = LoggerFactory.getLogger(getClass());

    private ProcessManager processManager;
    private Map<String, Installation> installationMap = new Hashtable<String, Installation>();
    private static final String PROCESS_SERVICE_FACTORY_PID = "io.fabric8.process";
    private BundleContext bundleContext;

    @Override
    public String getName() {
        return "Fabric Process Server";
    }

    @Override
    public final void deleted(String pid) {

        Installation installation = installationMap.remove(pid);
        if (installation != null) {

            try {
                if (installation.getController().status() == 0) {
                    installation.getController().stop();
                }
                // TODO uninstall is not supported right now
//                installation.getController().uninstall();
//                processManager.uninstall(installation);
                LOG.info("Destroyed Process " + pid);
            } catch (Exception e) {
                LOG.error("Error destroying Process " + pid + " : " + e.getMessage(), e);
            }

        } else {
            LOG.error("Process " + pid + " not found");
        }

        LOG.info("Deleted " + pid);
    }

    @Override
    public void updated(String pid, Dictionary incoming) throws ConfigurationException {

        try {
            // get process install parameters,
            // note that service.pid and service.factoryPid are added too
            Map<String, String> env = new HashMap<String, String>();
            InstallOptions options = getInstallOptions(incoming, env);

            final Installation installation = installationMap.get(pid);
            if (null != installation) {

                // TODO only environment updates are supported, process installation parameters cannot be updated,
                // for that a process should be deleted and created again
                // refresh environment variables and reconfigure
                LOG.info("Refreshing Process " + pid);
                updateConfig(pid, installation, env);

            } else {

                // create and add bridge connector
                installationMap.put(pid, installProcess(pid, options, env));
                LOG.info("Started Process " + pid);

            }
        } catch (Exception ex) {
            Throwables.propagate(ex);
        }
    }

    private InstallOptions getInstallOptions(Dictionary incoming, Map<String, String> env) throws ConfigurationException, MalformedURLException {

        InstallOptions.InstallOptionsBuilder builder = InstallOptions.builder();
        for (Enumeration keys = incoming.keys(); keys.hasMoreElements(); ) {

            String key = (String) keys.nextElement();
            String value = (String) incoming.get(key);

            // TODO add jar install parameters support
            try {

                if ("url".equals(key)) {
                    Preconditions.checkNotNull(value, "Null url property");
                    Preconditions.checkArgument(!value.trim().isEmpty(), "Empty url property");
                    builder.url(value.trim());
                } else if ("controllerUrl".equals(key)) {
                    Preconditions.checkNotNull(value, "Null controllerUrl property");
                    Preconditions.checkArgument(!value.trim().isEmpty(), "Empty controllerUrl property");
                    builder.controllerUrl(value.trim());
                } else if ("kind".equals(key)) {
                    Preconditions.checkNotNull(value, "Null kind property");
                    Preconditions.checkArgument(!value.trim().isEmpty(), "Empty kind property");
                    String name = value.trim() + ".json";
                    builder.controllerUrl(bundleContext.getBundle().getResource(name));
                } else {
                    // the remaining properties become environment properties
                    env.put(key, (String) incoming.get(key));
                }

            } catch (Exception e) {
                String msg = "Error getting install parameters: " + e.getMessage();
                LOG.error(msg, e);
                throw new ConfigurationException(key, msg);
            }
        }

        return builder.build();
    }

    private void updateConfig(String pid, Installation installation, Map<String, String> env) throws ConfigurationException {

        try {

            final ProcessController controller = installation.getController();
            final boolean running = (controller.status() == 0);

            // stop if running, since config may not be changed while process is running
            if (running) {
                controller.stop();
            }

            // refresh environment variables in process config
            installation.getEnvironment().putAll(env);

            // re-configure the install using new environment variables
            controller.configure();

            // restart if it was running before
            if (running) {
                controller.start();
            }

        } catch (Exception e) {
            String msg = "Error updating process " + pid + ": " + e.getMessage();
            LOG.error(msg, e);
            throw new ConfigurationException("Update", msg, e);
        }
    }

    private Installation installProcess(String pid, InstallOptions options, Map<String, String> env) throws ConfigurationException {
        try {
            // allow bundles / features which could be specified
            InstallTask postInstall = null;

            // TODO add support for jar install parameters
            Installation installation = processManager.install(options, postInstall);

            // add environment variables from properties
            installation.getEnvironment().putAll(env);

            // now configure and start the process
            // TODO check whether commands completed successfully
            installation.getController().configure();
            installation.getController().start();

            return installation;

        } catch (Exception e) {
            String msg = "Error installing process " + pid + " : " + e.getMessage();
            LOG.error(msg);
            throw new ConfigurationException("Start", msg, e);
        }

    }

    public final void init() throws Exception {
        Preconditions.checkNotNull(processManager, "processManager property");
        Preconditions.checkNotNull(bundleContext, "bundleContext property");

        // load existing config admin based installations in map
        List<Installation> installations = processManager.listInstallations();
        for (Installation installation : installations) {
            Map<String, String> env = installation.getEnvironment();
            if (env != null) {
                String factoryPid = env.get("service.factoryPid");
                String servicePid = env.get("service.pid");
                if (servicePid != null && factoryPid != null && PROCESS_SERVICE_FACTORY_PID.equals(factoryPid)) {
                    installationMap.put(servicePid, installation);
                }
            }
        }

        LOG.info("Started");
    }

    public final void destroy() throws Exception {

        // cleanup
        installationMap.clear();

        LOG.info("Destroyed");
    }

    public ProcessManager getProcessManager() {
        return processManager;
    }

    public void setProcessManager(ProcessManager processManager) {
        this.processManager = processManager;
    }

    public BundleContext getBundleContext() {
        return bundleContext;
    }

    public void setBundleContext(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
    }

}
TOP

Related Classes of io.fabric8.process.manager.service.ProcessServiceFactory

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.