Package org.ow2.easybeans.server.ra

Source Code of org.ow2.easybeans.server.ra.EasyBeansResourceAdapter$EmbeddedStarter

/**
* EasyBeans
* Copyright (C) 2006-2008 Bull S.A.S.
* Contact: easybeans@ow2.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: EasyBeansResourceAdapter.java 5369 2010-02-24 14:58:19Z benoitf $
* --------------------------------------------------------------------------
*/

package org.ow2.easybeans.server.ra;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.resource.ResourceException;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapterInternalException;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.rmi.PortableRemoteObject;
import javax.transaction.xa.XAResource;

import org.ow2.easybeans.container.mdb.helper.JOnAS4ResourceAdapterFinder;
import org.ow2.easybeans.container.mdb.helper.MDBResourceAdapterHelper;
import org.ow2.easybeans.deployer.JOnASDeployer;
import org.ow2.easybeans.security.propagation.context.SecurityCurrent;
import org.ow2.easybeans.security.propagation.jonas.JOnASSecurityCurrent;
import org.ow2.easybeans.server.EasyBeans;
import org.ow2.easybeans.server.Embedded;
import org.ow2.easybeans.server.EmbeddedException;
import org.ow2.easybeans.util.loader.ClassUtils;
import org.ow2.util.ee.deploy.api.deployer.DeployerException;
import org.ow2.util.ee.deploy.api.deployer.IDeployerManager;
import org.ow2.util.ee.deploy.impl.deployer.DeployerManager;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
* Defines a resource adapter which allow to embed the EJB3 server in Application Server.
* application server.
* @author Florent Benoit
*/
public class EasyBeansResourceAdapter implements javax.resource.spi.ResourceAdapter {

    /**
     * Default XML file.
     */
    public static final String DEFAULT_XML_FILE = "org/ow2/easybeans/server/ra/easybeans-ra.xml";

    /**
     * JOnAS ADM interface.
     */
    public static final String JONAS_ADM_ITF = "org.objectweb.jonas.adm.AdmInterface";


    /**
     * Logger.
     */
    private static Log logger = LogFactory.getLog(EasyBeansResourceAdapter.class);

    /**
     * Embedded instance.
     */
    private Embedded embedded = null;

    /**
     * Starts the embedded server.
     * @param ctx - a bootstrap context containing references to useful
     *        facilities that could be used by a resource adapter instance.
     * @throws ResourceAdapterInternalException indicates bootstrap failure.
     */
    public void start(final BootstrapContext ctx) throws ResourceAdapterInternalException {

        // user configuration ?
        URL xmlConfigurationURL = Thread.currentThread().getContextClassLoader().getResource(EasyBeans.USER_XML_FILE);

        if (xmlConfigurationURL == null) {
            xmlConfigurationURL = Thread.currentThread().getContextClassLoader().getResource(DEFAULT_XML_FILE);
            logger.info(
                    "No user-defined configuration file named ''{0}'' found in classpath. Using default settings from ''{1}''",
                    EasyBeans.USER_XML_FILE, xmlConfigurationURL);
        }

        // Add the configuration URL to the existing list
        this.embedded = new Embedded();
        this.embedded.getServerConfig().getConfigurationURLs().add(xmlConfigurationURL);

        // Use JOnAS deployer
        IDeployerManager deployerManager = new DeployerManager();
        this.embedded.setDeployerManager(deployerManager);
        try {
            JOnASDeployer deployer = new JOnASDeployer();
            deployer.setEmbedded(this.embedded);
            deployerManager.register(deployer);
        } catch (DeployerException e) {
            throw new ResourceAdapterInternalException("Cannot register the JOnAS deployer", e);
        }


        // Update configuration
        String jBase = System.getProperty("jonas.base");
        if (jBase == null) {
            throw new ResourceAdapterInternalException("No JONAS_BASE found, cannot continue.");
        }
        File workDir = new File(jBase + File.separator + Embedded.DEFAULT_DEPLOY_DIRECTORY);
        workDir.mkdir();

        // Add deploy directory
        this.embedded.getServerConfig().addDeployDirectory(workDir);

        // Use JOnAS 4.x MDB Helper
        MDBResourceAdapterHelper.setResourceAdapterFinder(new JOnAS4ResourceAdapterFinder());

        // Use of JOnAS 4.x security model
        SecurityCurrent.setSecurityCurrent(new JOnASSecurityCurrent());

        // start of the embedded object will be delayed until JOnAS is started.
        // This is because Datasource could be deployed after this adapter and
        // then datasource won't be found.
        new EmbeddedStarter().start();

    }

    /**
     * Stopp the embedded server.
     */
    public void stop() {
        try {
            this.embedded.stop();
        } catch (EmbeddedException e) {
            throw new IllegalStateException("Cannot stop the embedded server", e);
        } finally {
            this.embedded = null;
        }
    }

    /**
     * This is called during the activation of a message endpoint.
     * @param endpointFactory - a message endpoint factory instance.
     * @param spec an activation spec JavaBean instance.
     * @throws ResourceException - indicates message endpoint activation
     *         rejection due to incorrect activation setup information.
     */
    public void endpointActivation(final MessageEndpointFactory endpointFactory, final ActivationSpec spec)
            throws ResourceException {

    }

    /**
     * This is called when a message endpoint is deactivated. The instances
     * passed as arguments to this method call should be identical to those
     * passed in for the corresponding endpointActivation call. This causes the
     * resource adapter to stop delivering messages to the message endpoint. Any
     * exception thrown by this method is ignored. After this method call, the
     * endpoint is deemed inactive.
     * @param endpointFactory a message endpoint factory instance.
     * @param spec an activation spec JavaBean instance.
     */
    public void endpointDeactivation(final MessageEndpointFactory endpointFactory, final ActivationSpec spec) {

    }

    /**
     * This method is called by the application server during crash recovery.
     * @param specs an array of ActivationSpec JavaBeans each of which
     *        corresponds to an deployed endpoint application that was active
     *        prior to the system crash.
     * @return an array of XAResource objects each of which represents a unique
     *         resource manager.
     * @throws ResourceException generic exception if operation fails due to an
     *         error condition.
     */
    public XAResource[] getXAResources(final ActivationSpec[] specs) throws ResourceException {

        return null;
    }

    /**
     * Gets the embedded object.
     * @return embedded server.
     */
    protected Embedded getEmbedded() {
        return this.embedded;
    }

    /**
     * This inner class will wait until the JOnAS server is ready and start the
     * embedded server.
     * @author Florent Benoit
     */
    public class EmbeddedStarter extends Thread {

        /**
         * Sleep time for this waiter thread (1 second).
         */
        private static final int SLEEP_TIME = 1000;

        /**
         * Logger.
         */
        private Log logger = LogFactory.getLog(EmbeddedStarter.class);

        /**
         * Wait until JOnAS is started.<br>
         * Then, start embedded object.
         */
        @Override
        public void run() {
            boolean embeddedStarted = false;

            while (!embeddedStarted) {

                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException e) {
                    throw new RuntimeException("Thread fail to sleep");
                }

                if (jonasIsReady()) {
                    try {
                        getEmbedded().start();
                    } catch (EmbeddedException e) {
                        this.logger.error("Cannot start the embedded server", e);
                    }
                    embeddedStarted = true;
                }
            }
        }

        /**
         *  @return true if the JOnAS server is ready, else false
         */
        private boolean jonasIsReady() {
            String jonasName = System.getProperty("jonas.name", "jonas");

            // Get Adm object
            String admName = jonasName + "_Adm";
            Context initialContext = null;
            try {
                initialContext = new InitialContext();
            } catch (NamingException e) {
                this.logger.error("Cannot get an initial context", e);
                return false;
            }
            Object adm = null;
            try {
                adm = initialContext.lookup(admName);
            } catch (NamingException e) {
                this.logger.error("No {0} object found in the initial context", admName, e);
                return false;
            }


            // Cast object into Adm object
            // Load Adm interface
            Class<?> admItfClass;
            try {
                admItfClass = ClassUtils.forName(JONAS_ADM_ITF);
            } catch (ClassNotFoundException e) {
                this.logger.error("Cannot load the class ''{0}''", JONAS_ADM_ITF, e);
                return false;
            }
            adm = PortableRemoteObject.narrow(adm, admItfClass);

            // Try to see if there is a method getServerState on this object
            Method getStateMethod;
            String methodName = "getServerState";
            try {
                getStateMethod = adm.getClass().getMethod(methodName);
            } catch (SecurityException e) {
                this.logger.error("Cannot get method name {0}", methodName, e);
                return false;
            } catch (NoSuchMethodException e) {
                this.logger.error("Cannot get method name {0}", methodName, e);
                return false;
            }

            if (getStateMethod == null) {
                this.logger.warn("No method getStateMethod() found on object {0}", adm);
                return false;
            }

            Integer state = null;
            try {
                state = (Integer) getStateMethod.invoke(adm);
            } catch (IllegalArgumentException e) {
                this.logger.error("Cannot call method {0} on object {1}.", methodName, adm, e);
                return false;
            } catch (IllegalAccessException e) {
                this.logger.error("Cannot call method {0} on object {1}.", methodName, adm, e);
                return false;
            } catch (InvocationTargetException e) {
                this.logger.error("Cannot call method {0} on object {1}.", methodName, adm, e);
                return false;
            }

            // check the status
            if (state.intValue() == 1) {
                this.logger.info("JOnAS has been started, EasyBeans is now starting.");
                // JOnAS is ready, can start embedded !
                return true;
            }

            return false;

        }

    }

}
TOP

Related Classes of org.ow2.easybeans.server.ra.EasyBeansResourceAdapter$EmbeddedStarter

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.