org.fusesource.cloudmix.agent.jbi.AgentComponent.java Source code

Java tutorial

Introduction

Here is the source code for org.fusesource.cloudmix.agent.jbi.AgentComponent.java

Source

/**
 *  Copyright (C) 2008 Progress Software, Inc. All rights reserved.
 *  http://fusesource.com
 *
 *  The software in this package is published under the terms of the AGPL license
 *  a copy of which has been included with this distribution in the license.txt file.
 */
package org.fusesource.cloudmix.agent.jbi;

import java.io.File;
import java.io.FileInputStream;
import java.net.URI;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.jbi.JBIException;
import javax.jbi.component.Component;
import javax.jbi.component.ComponentContext;
import javax.jbi.component.ComponentLifeCycle;
import javax.jbi.component.ServiceUnitManager;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.servicedesc.ServiceEndpoint;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.ObjectName;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fusesource.cloudmix.agent.AgentPoller;
import org.fusesource.cloudmix.agent.InstallerAgent;
import org.fusesource.cloudmix.agent.RestGridClient;
import org.fusesource.cloudmix.agent.security.DialogPasswordProvider;
import org.fusesource.cloudmix.agent.security.FilePasswordProvider;
import org.fusesource.cloudmix.agent.security.PasswordProvider;

public class AgentComponent implements ComponentLifeCycle, Component {

    private static final Log LOGGER = LogFactory.getLog(AgentComponent.class);

    private static final String CONFIG_PROP_FILE = "agent.properties.file";
    private static final String CONFIG_REPO_URI = "agent.repository.uri";
    private static final String CONFIG_ID = InstallerAgent.PERSISTABLE_PROPERTY_AGENT_ID;
    private static final String CONFIG_NAME = InstallerAgent.PERSISTABLE_PROPERTY_AGENT_NAME;
    private static final String CONFIG_PROFILE = InstallerAgent.PERSISTABLE_PROPERTY_PROFILE_ID;
    private static final String CONFIG_MBEAN_NAME = "agent.deployservice.mbean";
    private static final String CONFIG_AGENT_USER = "agent.user";
    private static final String CONFIG_AGENT_PASSWORD_PROV = "agent.password.provider";
    private static final String CONFIG_AGENT_PASSWORD_FILE = "agent.password.file";

    private static final String CONFIG_AGENT_TYPE = "agent.type";
    private static final String CONFIG_AGENT_LINK = "agent.link";
    private static final String CONFIG_AGENT_PACKAGES = "agent.packages";
    private static final String CONFIG_AGENT_MBEAN_CONTAINER = "agent.mbean.container";

    private static final String DEFAULT_PROP_FILE = "conf/agent.properties";
    private static final String DEFAULT_CONTAINER_TYPE = "smx3";
    private static final String DEFAULT_REPO_URI = "http://localhost:9091/controller";
    private static final String DEFAULT_PROFILE = "default";
    private static final String DEFAULT_AGENT_USER = "Agent";
    private static final String DEFAULT_AGENT_PASSWORD = "agent";
    private static final String DEFAULT_AGENT_PASSWORD_PROV = "file";
    private static final String DEFAULT_AGENT_PASSWORD_FILE = "conf/agent.password";
    private static final String FILE_PROVIDER = "file";
    private static final String DIALOG_PROVIDER = "dialog";

    private static final String DEFAULT_MBEAN_NAME = "org.apache.servicemix:" + "ContainerName=ServiceMix,"
            + "Type=SystemService," + "Name=DeploymentService";
    private static final String DEFAULT_PACKAGES = "jbi";
    private static final String DEFAULT_AGENT_MBEAN_CONTAINER = "ServiceMix";

    private static final int MAX_FEATURES = 25;
    private static final long INITIAL_POLLING_DELAY = 5000;
    private static final long POLLING_PERIOD = 1000;

    private RestGridClient gridClient = new RestGridClient();
    private JBIInstallerAgent agent = new JBIInstallerAgent();
    private AgentPoller poller = new AgentPoller();

    private MBeanServer mbeanServer;

    private ObjectName mbeanName;

    public AgentComponent() {
        // Complete
    }

    public ObjectName getExtensionMBeanName() {
        // Complete
        return null;
    }

    public void init(ComponentContext ctx) throws JBIException {

        LOGGER.info("initialising agent");

        StringBuilder sb = new StringBuilder().append("\n")
                .append("CloudMix Agent JBI Service Assembly Deployer\n");

        try {
            Properties properties = System.getProperties();
            String agentPropertiesFile = getConfig(System.getProperties(), CONFIG_PROP_FILE, DEFAULT_PROP_FILE);
            Properties newProperties = loadProperties(agentPropertiesFile);
            if (newProperties != null) {
                properties = newProperties;
            }
            String agentUser = getConfig(properties, CONFIG_AGENT_USER, DEFAULT_AGENT_USER);

            PasswordProvider provider = null;
            String providerType = getConfig(properties, CONFIG_AGENT_PASSWORD_PROV, DEFAULT_AGENT_PASSWORD_PROV);
            if (FILE_PROVIDER.equals(providerType)) {
                FilePasswordProvider fpp = new FilePasswordProvider();
                fpp.setPasswordFile(getConfig(properties, CONFIG_AGENT_PASSWORD_FILE, DEFAULT_AGENT_PASSWORD_FILE));
                provider = fpp;
            } else if (DIALOG_PROVIDER.equals(providerType)) {
                DialogPasswordProvider dpp = new DialogPasswordProvider();
                dpp.setUsername(agentUser);
                provider = dpp;
            } else {
                throw new RuntimeException("Unknown password provider " + providerType);
            }

            String agentId = getConfig(properties, CONFIG_ID, null);
            String agentName = getConfig(properties, CONFIG_NAME, null);
            String agentProfile = getConfig(properties, CONFIG_PROFILE, DEFAULT_PROFILE);

            String anMbeanName = getConfig(properties, CONFIG_MBEAN_NAME, DEFAULT_MBEAN_NAME);
            String rootUri = getConfig(properties, CONFIG_REPO_URI, DEFAULT_REPO_URI);
            String agentType = getConfig(properties, CONFIG_AGENT_TYPE, DEFAULT_CONTAINER_TYPE);
            String agentLink = getConfig(properties, CONFIG_AGENT_LINK, null);
            String[] supportPackageTypes = getConfigList(properties, CONFIG_AGENT_PACKAGES, DEFAULT_PACKAGES);
            String mbeanContainer = getConfig(properties, CONFIG_AGENT_MBEAN_CONTAINER,
                    DEFAULT_AGENT_MBEAN_CONTAINER);

            mbeanServer = ctx.getMBeanServer();
            ObjectName oname = validateMbean(mbeanServer, anMbeanName);
            if (oname == null) {
                throw new JBIException("DeploymentService MBean not available using name " + anMbeanName);
            }

            gridClient.setRootUri(new URI(rootUri));
            gridClient.setUsername(agentUser);
            gridClient.setPasswordProvider(provider);

            agent.setAgentId(agentId);
            agent.setAgentName(agentName);

            agent.setDetailsPropertyFilePath(agentPropertiesFile);

            agent.setMBeanServer(mbeanServer);
            agent.setMBeanName(oname);
            agent.setMaxFeatures(MAX_FEATURES);
            agent.setProfile(agentProfile);
            agent.setClient(gridClient);
            agent.setContainerType(agentType);
            agent.setSupportPackageTypes(supportPackageTypes);
            agent.setAgentLink(agentLink);
            agent.init();

            sb.append("\nConfiguration:")
                    .append("\n  Agent ID:     " + agentId == null ? "unassigned yet" : agentId)
                    .append("\n  Agent Name:     " + agentName == null ? "unassigned yet" : agentName)
                    .append("\n  Agent profile:     " + agentProfile).append("\n  Repository URI:    " + rootUri)
                    .append("\n  Agent user:        " + agentUser)
                    .append("\n  Agent type:        " + agent.getContainerType())
                    .append("\n  Agent link:        " + agentLink).append("\n  Agent mbean name:  " + anMbeanName)
                    .append("\n  Package types:     ");
            for (String packageType : supportPackageTypes) {
                sb.append(packageType).append(" ");
            }

            poller.setInitialPollingDelay(INITIAL_POLLING_DELAY);
            poller.setPollingPeriod(POLLING_PERIOD);
            poller.setAgent(agent);

            mbeanServer = ctx.getMBeanServer();

            AgentMBean agentMBean = new Agent(agent, gridClient, poller);
            registerMBean(agentMBean, ctx.getMBeanNames().getJmxDomainName(), mbeanContainer);

            sb.append("\n");
            LOGGER.info(sb.toString());

        } catch (JBIException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("Failed to initialise agent.  Exception " + e);
            throw new JBIException(e);
        }
    }

    public void shutDown() throws JBIException {

        LOGGER.info("shutting down agent");

        if (mbeanName != null) {
            try {
                mbeanServer.unregisterMBean(mbeanName);
            } catch (Exception e) {
                LOGGER.warn("Exception unregistering agent mbean " + e);
            }
        }
    }

    public void start() throws JBIException {

        LOGGER.info("starting agent");

        // TODO: need to support restarting agent.

        try {
            poller.afterPropertiesSet();
        } catch (Exception e) {
            LOGGER.warn("Exception " + e + " starting agent poller");
        }
    }

    public void stop() throws JBIException {

        LOGGER.info("stopping agent");

        try {
            LOGGER.info("destroying poller");
            agent.setClient(null);
            poller.destroy();
        } catch (Exception e) {
            LOGGER.warn("Exception destroying poller; " + e);
        }
    }

    public ComponentLifeCycle getLifeCycle() {
        return this;
    }

    public Document getServiceDescription(ServiceEndpoint se) {
        // Complete
        return null;
    }

    public ServiceUnitManager getServiceUnitManager() {
        // Complete
        return null;
    }

    public boolean isExchangeWithConsumerOkay(ServiceEndpoint se, MessageExchange me) {
        // Complete
        return false;
    }

    public boolean isExchangeWithProviderOkay(ServiceEndpoint se, MessageExchange me) {
        // Complete
        return false;
    }

    public ServiceEndpoint resolveEndpointReference(DocumentFragment df) {
        // Complete
        return null;
    }

    private Properties loadProperties(String file) {

        try {
            if (file == null || "".equals(file)) {
                return null;
            }
            File f = new File(file);
            if (!f.exists()) {
                LOGGER.warn("properties file " + file + " does not exist");
                return null;
            }
            Properties properties = new Properties();
            LOGGER.info("Loading properties from file " + f);
            properties.load(new FileInputStream(f));
            return properties;
        } catch (Exception e) {
            LOGGER.warn("error loading properties file " + file + ", exception " + e);
            return null;
        }
    }

    private String getConfig(Properties properties, String name, String defaultValue) {

        String value = properties.getProperty(name);
        if (value == null) {
            value = defaultValue;
        }
        LOGGER.debug("  Property " + name + " = " + defaultValue);
        return value;
    }

    private String[] getConfigList(Properties properties, String name, String defaultValue) {

        String value = properties.getProperty(name);
        if (value == null) {
            value = defaultValue;
        }

        StringTokenizer tokeniser = new StringTokenizer(value, ",");
        int arraySize = tokeniser.countTokens();
        String[] array = new String[arraySize];
        for (int i = 0; i < arraySize; i++) {
            String item = (String) tokeniser.nextElement();
            array[i] = item.trim();
        }
        return array;
    }

    private void registerMBean(AgentMBean agentMBean, String domainName, String containerName) {

        try {
            String name = domainName + ":ContainerName=" + containerName + ",Type=ServiceGrid,Name=Agent";

            mbeanName = new ObjectName(name);
            LOGGER.info("registering agent mbean with name " + mbeanName);
            mbeanServer.registerMBean(agentMBean, mbeanName);
        } catch (Exception e) {
            LOGGER.warn("Exception registering mbean " + e);
        }
    }

    private ObjectName validateMbean(MBeanServer anMbeanServer, String anMbeanName) {
        try {
            ObjectName oname = new ObjectName(anMbeanName);
            MBeanInfo info = anMbeanServer.getMBeanInfo(oname);
            if (info != null) {
                LOGGER.info("Successfully accesses Deployment Service mbean");
                LOGGER.info("Description: " + info.getDescription());
                return oname;
            }
        } catch (Exception e) {
            LOGGER.debug("Exception getting DeploymentService mbean " + e);
        }
        LOGGER.error("Cannot resolve DeploymentService MBean using name " + anMbeanName);
        return null;
    }

}