All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.petals.se.ase.SuManager Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2011-2012 EBM WebSourcing, 2012-2023 Linagora
 * 
 * This program/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 (at your
 * option) any later version.
 * 
 * This program/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 program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.se.ase;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.management.ObjectName;

import org.apache.activemq.ActiveMQConnection;
import org.ow2.petals.component.framework.api.configuration.AbstractConfigurationParameters;
import org.ow2.petals.component.framework.api.configuration.SuConfigurationParameters;
import org.ow2.petals.component.framework.api.exception.PEtALSCDKException;
import org.ow2.petals.component.framework.jbidescriptor.generated.Consumes;
import org.ow2.petals.component.framework.jbidescriptor.generated.Jbi;
import org.ow2.petals.component.framework.jbidescriptor.generated.MEPType;
import org.ow2.petals.component.framework.jbidescriptor.generated.Provides;
import org.ow2.petals.component.framework.se.AbstractServiceEngine;
import org.ow2.petals.component.framework.se.ServiceEngineServiceUnitManager;
import org.ow2.petals.component.framework.su.ServiceUnitDataHandler;
import org.ow2.petals.se.ase.admin.SuAdmin;
import org.ow2.petals.se.ase.jms.JMSMessageExchange;
import org.ow2.petals.se.ase.jms.JmsUtils;
import org.ow2.petals.se.ase.jms.exception.SeAseE001Exception;
import org.ow2.petals.se.ase.listener.JBIListener;

/**
 * @author Pierre-Yves Gibello - EBM WebSourcing
 */
public class SuManager extends ServiceEngineServiceUnitManager {

	/**
	 * A map associating service-unit names and Validation configuration.
	 */
	private final Map epConfigurations_ = new ConcurrentHashMap();

	/**
	 * Constructor.
	 * @param component the component's instance
	 */
    public SuManager(final AbstractServiceEngine component) {
		super(component);
	}

	@Override
    protected void doDeploy(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {

        final Jbi jbiDescriptor = suDH.getDescriptor();
        final String serviceUnitName = suDH.getName();

		final List consumesList = jbiDescriptor.getServices().getConsumes();
        if (consumesList.size() != 1) {
			logger.warning("SE-ASE-W0002: Two sections \'consume\' are declared in the JBI descriptor of the service-unit " + serviceUnitName + " instead of only one. Unexpected error can occur (using 1st one as default).");
		}

		final List providesList = jbiDescriptor.getServices().getProvides();
        if (providesList.size() != 1) {
			logger.warning("SE-ASE-W0001: Two sections \'provides\' are declared in the JBI descriptor of the service-unit " + serviceUnitName + " instead of only one. Unexpected error can occur (using 1st one as default).");
		}

		Provides provides = providesList.get(0);
		Consumes consumes = consumesList.get(0);
		
		if(! consumes.getInterfaceName().equals(provides.getInterfaceName())) {
			logger.warning("SE-ASE-W0003: Interface name of both sections \'consume\' ("
					+ consumes.getInterfaceName() + ") and \'provide\' ("
					+ provides.getInterfaceName() + ") are different. \'"
					+ consumes.getInterfaceName() + "' is used as interface name of the section \'provide\'");
			provides.setInterfaceName(consumes.getInterfaceName());
		}
		
        final String providesName = JMSMessageExchange.getEndpointName(provides);
        final EpConfiguration config = new EpConfiguration(providesName, serviceUnitName, suDH.getInstallRoot());

        final SuConfigurationParameters suProvideExtensions = suDH.getConfigurationExtensions(provides);
		
		config.setString(EpConfiguration.ACTIVEMQ_CONNECTION_USER, ActiveMQConnection.DEFAULT_USER);
		config.setString(EpConfiguration.ACTIVEMQ_CONNECTION_PASSWORD, ActiveMQConnection.DEFAULT_PASSWORD);
		config.setString(EpConfiguration.ACTIVEMQ_BROKER_URL, "tcp://localhost:61616"); // TBD ActiveMQConnection.DEFAULT_BROKER_URL);
		
        final AbstractConfigurationParameters componentExtensions = getComponent().getComponentExtensions();
		config.setString(EpConfiguration.JAVA_NAMING_FACTORY_INITIAL, componentExtensions, null);
		config.setString(EpConfiguration.JAVA_NAMING_PROVIDER_URL, componentExtensions, null);
		config.setString(EpConfiguration.JMS_CONNECTION_FACTORY_JNDINAME, componentExtensions, null);
		config.setInt(EpConfiguration.STOP_TIMEOUT, componentExtensions, "0");
		
		config.setBoolean(EpConfiguration.PROVIDES_AUTOMATICALLY_STARTED, suProvideExtensions, "true");
		config.setString(EpConfiguration.PERSISTENCE_AREA_NAME, suProvideExtensions,
				provides.getServiceName().getLocalPart());
	 	config.setString(EpConfiguration.PERSISTENCE_AREA_NAME_EXPIRED, suProvideExtensions,
	 			provides.getServiceName().getLocalPart() + "_expired");
	 	config.setString(EpConfiguration.PERSISTENCE_AREA_NAME_TIMEDOUT, suProvideExtensions,
	 			provides.getServiceName().getLocalPart() + "_error");
	 	config.setString(EpConfiguration.PERSISTENCE_AREA_NAME_ERROR, suProvideExtensions,
	 			provides.getServiceName().getLocalPart() + "_error");
	 	config.setString(EpConfiguration.PERSISTENCE_AREA_NAME_FAULT, suProvideExtensions,
	 			provides.getServiceName().getLocalPart() + "_error");
		
        final SuConfigurationParameters suConsumeExtensions = suDH.getConfigurationExtensions(consumes);

        config.setString(EpConfiguration.CONSUMES_ENDPOINT, JMSMessageExchange.getEndpointName(consumes), null);

        config.setBoolean(EpConfiguration.CONSUMES_AUTOMATICALLY_STARTED,
                suConsumeExtensions.get("mustBeAutomaticallyStarted"), "true");
		String defaultTTL = componentExtensions.get("time-to-live");
		if(defaultTTL == null) defaultTTL = "0";
        config.setInt(EpConfiguration.CONSUMES_TTL, suConsumeExtensions.get("time-to-live"), defaultTTL);
        config.setInt(EpConfiguration.CONSUMES_RETRY_POLICY_NUMBER, suConsumeExtensions.get("retry-policy-number"), "3");
        config.setInt(EpConfiguration.CONSUMES_RETRY_POLICY_BASE_INTERVAL,
                suConsumeExtensions.get("retry-policy-base-interval"), "10");
        config.setInt(EpConfiguration.CONSUMES_RETRY_POLICY_FACTOR, suConsumeExtensions.get("retry-policy-factor"), "3");

        config.setBoolean(EpConfiguration.CONSUMES_IS_IDEMPOTENT, suConsumeExtensions.get("is-idempotent"), "true");
        final MEPType mepType = consumes.getMep();
        if (MEPType.ROBUST_IN_ONLY.equals(mepType)) {
            config.setString(EpConfiguration.CONSUMES_MEP, "RobustInOnly");
        } else if (MEPType.IN_OUT.equals(mepType)) {
            config.setString(EpConfiguration.CONSUMES_MEP, "InOut");
        } else {
            config.setString(EpConfiguration.CONSUMES_MEP, "InOnly");
        }
		
		this.epConfigurations_.put(providesName, config);
		this.epConfigurations_.put(serviceUnitName, config);

        this.logger.config("Configuration of consumer queues:");
        this.logger.config("\tretry-policy-number: " + config.getInt(EpConfiguration.CONSUMES_RETRY_POLICY_NUMBER));
        this.logger.config(
                "\tretry-policy-base-interval: " + config.getInt(EpConfiguration.CONSUMES_RETRY_POLICY_BASE_INTERVAL));
        this.logger.config("\tretry-policy-factor: " + config.getInt(EpConfiguration.CONSUMES_RETRY_POLICY_FACTOR));
        this.logger.config("\tis-idempotent: " + config.getBoolean(EpConfiguration.CONSUMES_IS_IDEMPOTENT));
        this.logger.config("\ttime-to-live: " + config.getInt(EpConfiguration.CONSUMES_TTL));

		try {
			initializePersistenceAreas(config);
		} catch(JMSException e) {
			throw new PEtALSCDKException(e);
        }
		
		try {
            getComponent().getContext().getMBeanServer().registerMBean(
				new SuAdmin(config, logger), new ObjectName("org.ow2.petals.se.ase:su=" + serviceUnitName));
		} catch (Exception e) {
			logger.warning("SE-ASE-W0006: An error occurs during the creation of the administration JMX API: " + e);
		}
	}

	public EpConfiguration getEpConfiguration(final Provides endpoint) {
        return this.epConfigurations_.get(JMSMessageExchange.getEndpointName(endpoint));
	}

    private void initializePersistenceAreas(final EpConfiguration config) throws JMSException {

        // Create the session
        final JmsUtils jmsUtils = config.getJmsUtils();
        final Session session = jmsUtils.createJmsSession(false, Session.AUTO_ACKNOWLEDGE);

        String queueName = "";
        try {
            queueName = config.getString(EpConfiguration.PERSISTENCE_AREA_NAME);
            createJmsQueue(session, queueName, config);

            queueName = config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_TIMEDOUT);
            createJmsQueue(session, queueName, config);

            queueName = config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_ERROR);
            createJmsQueue(session, queueName, config);

            queueName = config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_FAULT);
            createJmsQueue(session, queueName, config);

            // TBD DLQ createJmsQueue(session, config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_EXPIRED), config);
        } catch (final JMSException e) {
            throw new SeAseE001Exception(queueName, e);
        }

        session.close();
    }
	
	private void createJmsQueue(Session session, String queue, EpConfiguration config) throws JMSException {
		Destination destination = session.createQueue(queue);
		
		// At least on ActiveMQ, destinations are not visible when created...
		// They will only appear upon first message !
		// So, let's send a TextMessage (with a short TTL)...
		MessageProducer producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        producer.setTimeToLive(1000);
        TextMessage message = session.createTextMessage("Queue started: " + queue);
        producer.send(message);
        producer.close();
	}

	@Override
    protected void doStart(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {
		
		JBIListener jbiListener = new JBIListener();
        jbiListener.init(getComponent());
        jbiListener.init();
		
        EpConfiguration config = this.epConfigurations_.get(suDH.getName());
		jbiListener.configure(config);
		boolean startNow = config.getBoolean(EpConfiguration.CONSUMES_AUTOMATICALLY_STARTED);
		try {
			config.getJmsUtils().startListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME), jbiListener, config, startNow);
			config.getJmsUtils().startListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME) + "_sending", jbiListener, config, startNow);
		} catch (JMSException e) {
			logger.warning("SE-ASE-W0004: An error occurs creating the persisted request listener: " + e);
		}
		
	}

	@Override
	protected void doStop(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {
		
		EpConfiguration config = epConfigurations_.get(suDH.getName());
		JmsUtils jmsUtils = config.getJmsUtils();
		jmsUtils.stopListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME), true);
		jmsUtils.stopListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME) + "_sending", true);
		jmsUtils.stopListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_TIMEDOUT), true);
		jmsUtils.stopListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_ERROR), true);
		jmsUtils.stopListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_FAULT), true);
		jmsUtils.stopListener(config.getString(EpConfiguration.PERSISTENCE_AREA_NAME_EXPIRED), true);
		
	}

	@Override
	protected void doUndeploy(final ServiceUnitDataHandler suDH) throws PEtALSCDKException {

        final String serviceUnitName = suDH.getName();

	    for(String key : epConfigurations_.keySet()) {
			EpConfiguration config = epConfigurations_.get(key);
            if (serviceUnitName.equals(config.getSuName())) {
				epConfigurations_.remove(key);
			}
		}
		epConfigurations_.remove(serviceUnitName);
		try {
            getComponent().getContext().getMBeanServer()
                    .unregisterMBean(
				new ObjectName("org.ow2.petals.se.ase:su=" + serviceUnitName));
        } catch (final Exception e) {
            throw new PEtALSCDKException(
                    "SE-ASE-W0007: An error occurs during the deletion of the administration JMX API", e);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy