org.apache.ode.jbi.OdeSUManager.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ode.jbi.OdeSUManager.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.apache.ode.jbi;

import java.util.HashMap;
import java.util.Map;

import javax.jbi.component.ServiceUnitManager;
import javax.jbi.management.DeploymentException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.XMLParserUtils;

public class OdeSUManager implements ServiceUnitManager {
    private static final Log __log = LogFactory.getLog(OdeSUManager.class);

    private static final Messages __msgs = Messages.getMessages(Messages.class);

    private static final String XMLNS_JBI_MGMT = "http://java.sun.com/xml/ns/jbi/management-message";

    private OdeContext _ode;

    /** All the service units that have been "init"ed. */
    private Map<String, OdeServiceUnit> _serviceUnits = new HashMap<String, OdeServiceUnit>();

    public OdeSUManager(OdeContext odeContext) {
        _ode = odeContext;
    }

    public synchronized String deploy(String serviceUnitID, String serviceUnitRootPath) throws DeploymentException {
        __log.trace("deploy: id=" + serviceUnitID + ", path=" + serviceUnitRootPath);

        OdeServiceUnit su = new OdeServiceUnit(_ode, serviceUnitID, serviceUnitRootPath);
        try {
            su.deploy();
        } catch (Exception ex) {
            __log.error(__msgs.msgServiceUnitDeployFailed(serviceUnitID));
            return makeStatusMessage("deploy", "FAILED");
        }

        return makeStatusMessage("deploy", "SUCCESS");

    }

    public synchronized void init(String serviceUnitID, String serviceUnitRootPath) throws DeploymentException {
        __log.trace("init called for " + serviceUnitID);

        if (_serviceUnits.containsKey(serviceUnitID)) {
            __log.debug("odd, init() called for su " + serviceUnitID + ", but it is already init()ed");
            return;
        }

        try {
            OdeServiceUnit su = new OdeServiceUnit(_ode, serviceUnitID, serviceUnitRootPath);
            su.init();
            _serviceUnits.put(serviceUnitID, su);
        } catch (Exception ex) {
            String errmsg = __msgs.msgServiceUnitInitFailed(serviceUnitID);
            __log.error(errmsg, ex);
            throw new DeploymentException(errmsg, ex);
        }
    }

    public synchronized void shutDown(String serviceUnitID) throws DeploymentException {
        __log.trace("shutDown called for " + serviceUnitID);

        OdeServiceUnit su = _serviceUnits.remove(serviceUnitID);
        if (su == null)
            return;

        try {
            su.shutdown();
        } catch (Exception ex) {
            String errmsg = __msgs.msgServiceUnitShutdownFailed(serviceUnitID);
            __log.error(errmsg, ex);
            throw new DeploymentException(errmsg, ex);
        }
    }

    public synchronized void start(String serviceUnitID) throws DeploymentException {
        __log.trace("start called for " + serviceUnitID);

        OdeServiceUnit su = _serviceUnits.get(serviceUnitID);
        if (su == null) {
            // Should not really happen if JBI is working.
            String errmsg = "Unexpected state; start() called before init()";
            IllegalStateException ex = new IllegalStateException(errmsg);
            __log.error(errmsg, ex);
            throw new DeploymentException(errmsg, ex);
        }
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
            su.start();
        } catch (Exception ex) {
            String errmsg = __msgs.msgServiceUnitStartFailed(serviceUnitID);
            __log.error(errmsg, ex);
            throw new DeploymentException(errmsg, ex);
        } finally {
            Thread.currentThread().setContextClassLoader(cl);
        }

    }

    /**
     * Stop the deployment. This causes the component to cease generating service
     * requests related to the deployment. This returns the deployment to a state
     * equivalent to after init() was called
     *
     * @param serviceUnitID
     *          service unit ID
     *
     * @throws DeploymentException
     *           deployment exception
     */
    public synchronized void stop(String serviceUnitID) throws DeploymentException {
        __log.trace("stop called for " + serviceUnitID);

        OdeServiceUnit su = _serviceUnits.get(serviceUnitID);
        if (su == null) {
            // Should not really happen if JBI is working.
            String errmsg = "Unexpected state; stop() called before init()";
            IllegalStateException ex = new IllegalStateException(errmsg);
            __log.error(errmsg, ex);
            throw new DeploymentException(errmsg, ex);
        }

        try {
            su.stop();
        } catch (Exception ex) {
            String errmsg = __msgs.msgServiceUnitStopFailed(serviceUnitID);
            __log.error(errmsg, ex);
            throw new DeploymentException(errmsg, ex);
        }

    }

    /**
     * Cancel a Service Deployment. If the deployment is in use (has
     * dependencies), then will operation may fail.
     *
     * @param serviceUnitID -
     *          ID of the Service Unit being undeployed
     * @param serviceUnitRootPath -
     *          Full path to the Service Unit root.
     *
     * @return NOT YET DOCUMENTED
     *
     * @throws DeploymentException
     *           deployment exception
     */
    public synchronized String undeploy(String serviceUnitID, String serviceUnitRootPath)
            throws DeploymentException {
        __log.trace("undeploy: id=" + serviceUnitID + ", path=" + serviceUnitRootPath);

        OdeServiceUnit su = new OdeServiceUnit(_ode, serviceUnitID, serviceUnitRootPath);

        try {
            su.undeploy();
        } catch (Exception ex) {
            __log.error(__msgs.msgServiceUnitDeployFailed(serviceUnitID));
            return makeStatusMessage("undeploy", "FAILED");
        }

        return makeStatusMessage("undeploy", "SUCCESS");

    }

    /**
     * Generate those lame XML result strings that JBI requires. Oh did I mention
     * how lame this is? If not, let me remind the reader: this is just about the
     * lamest "clever idea" I have ever seen.
     *
     * @param task
     *          the task that failed and must now generate a lame result string
     * @param status
     *          the status code that will go into the lame result string.
     * @return a lame JBI result string
     */
    private String makeStatusMessage(String task, String status) {

        /*
         * Cheat sheet: <component-task-result> <component-name>BC1</component-name>
         * <component-task-result-details
         * xmlns="http://java.sun.com/xml/ns/jbi/management- <task-result-details>
         * <task-id>deploy</task-id> <task-result>SUCCESS</task-result>
         * </task-result-details> </component-task-result-details>
         * </component-task-result>
         *
         */

        // First of all, what is the logic why XML ? and if XML, why a String
        // and not a DOM ? But the 64k question is what is wrong with Exceptions?
        Document doc;
        try {
            // Note that we are using our own choice of factory (xerces), not the
            // one that is provided by the system. This is important, otherwise the
            // serialization routine won't work.
            DocumentBuilderFactory dbf = XMLParserUtils.getDocumentBuilderFactory();
            DocumentBuilder db = dbf.newDocumentBuilder();
            doc = db.newDocument();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }

        Element elem = doc.createElementNS(XMLNS_JBI_MGMT, "component-task-result");
        doc.appendChild(elem);
        Element compNameElem = doc.createElementNS(XMLNS_JBI_MGMT, "component-name");
        elem.appendChild(compNameElem);
        Element compTaskRsltDtlsElem = doc.createElementNS(XMLNS_JBI_MGMT, "component-task-result-details");
        elem.appendChild(compTaskRsltDtlsElem);
        Element taskRsltDtlsElem = doc.createElementNS(XMLNS_JBI_MGMT, "task-result-details");
        compTaskRsltDtlsElem.appendChild(taskRsltDtlsElem);

        Element taskId = doc.createElementNS(XMLNS_JBI_MGMT, "task-id");
        taskRsltDtlsElem.appendChild(taskId);

        Element taskResult = doc.createElementNS(XMLNS_JBI_MGMT, "task-result");
        taskRsltDtlsElem.appendChild(taskResult);

        // Why do I have to tell this thing the component name? It /knows/ the
        // component name....
        compNameElem.appendChild(doc.createTextNode(_ode.getContext().getComponentName()));

        // And why on earth do I have to tell my caller the method he just
        // called?
        taskId.appendChild(doc.createTextNode(task));

        taskResult.appendChild(doc.createTextNode(status));
        return DOMUtils.domToString(elem);
    }
}