Package org.apache.servicemix.jms.jca

Source Code of org.apache.servicemix.jms.jca.JcaConsumerProcessor

/*
* 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.servicemix.jms.jca;

import java.util.Map;

import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.InOnly;
import javax.jbi.messaging.MessageExchange;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.transaction.TransactionManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.common.BaseLifeCycle;
import org.apache.servicemix.jms.AbstractJmsProcessor;
import org.apache.servicemix.jms.JmsEndpoint;
import org.apache.servicemix.soap.Context;
import org.jencks.SingletonEndpointFactory;

import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;

/**
*
* @author <a href="mailto:gnodet [at] gmail.com">Guillaume Nodet</a>
*/
public class JcaConsumerProcessor extends AbstractJmsProcessor implements MessageListener {

    private static final Log log = LogFactory.getLog(JcaConsumerProcessor.class);

    protected Map pendingMessages = new ConcurrentHashMap();
    protected ResourceAdapter resourceAdapter;
    protected MessageEndpointFactory endpointFactory;
    protected ActivationSpec activationSpec;
    protected BootstrapContext bootstrapContext;
    protected TransactionManager transactionManager;
    protected ConnectionFactory connectionFactory;
   
    public JcaConsumerProcessor(JmsEndpoint endpoint) throws Exception {
        super(endpoint);
    }

    public void start() throws Exception {
        transactionManager = (TransactionManager) context.getTransactionManager();
        endpointFactory = new SingletonEndpointFactory(this, transactionManager);
        bootstrapContext = endpoint.getBootstrapContext();
        if (bootstrapContext == null) {
            throw new IllegalArgumentException("bootstrapContext not set");
        }
        connectionFactory = endpoint.getConnectionFactory();
        if (connectionFactory == null) {
            throw new IllegalArgumentException("connectionFactory not set");
        }
        activationSpec = endpoint.getActivationSpec();
        if (activationSpec == null) {
            throw new IllegalArgumentException("activationSpec not set");
        }
        resourceAdapter = endpoint.getResourceAdapter();
        if (resourceAdapter == null) {
            resourceAdapter = activationSpec.getResourceAdapter();
            if (resourceAdapter == null) {
                throw new IllegalArgumentException("resourceAdapter not set");
            }
        } else if (activationSpec.getResourceAdapter() == null) {
            activationSpec.setResourceAdapter(resourceAdapter);
        }
        resourceAdapter.start(bootstrapContext);
        resourceAdapter.endpointActivation(endpointFactory, activationSpec);
    }

    public void stop() throws Exception {
        resourceAdapter.endpointDeactivation(endpointFactory, activationSpec);
        pendingMessages.clear();
    }

    public void onMessage(final Message message) {
        try {
            if (log.isDebugEnabled()) {
                log.debug("Received jms message " + message);
            }
            Context context = createContext();
            MessageExchange exchange = toNMS(message, context);
            if (exchange instanceof InOnly == false) {
                throw new UnsupportedOperationException("JCA consumer endpoints can only use InOnly MEP");
            }
            exchange.setProperty(MessageExchange.JTA_TRANSACTION_PROPERTY_NAME, transactionManager.getTransaction());
            pendingMessages.put(exchange.getExchangeId(), context);
            if (endpoint.isSynchronous()) {
                channel.sendSync(exchange);
                process(exchange);
            } else {
                BaseLifeCycle lf = (BaseLifeCycle) endpoint.getServiceUnit().getComponent().getLifeCycle();
                lf.sendConsumerExchange(exchange, JcaConsumerProcessor.this.endpoint);
            }
        } catch (Throwable e) {
            log.error("Error while handling jms message", e);
        }
    }

    public void process(MessageExchange exchange) throws Exception {
        Context context = (Context) pendingMessages.remove(exchange.getExchangeId());
        Message message = (Message) context.getProperty(Message.class.getName());
        Message response = null;
        Connection connection = null;
        try {
            if (exchange.getStatus() == ExchangeStatus.DONE) {
                return;
            } else if (exchange.getStatus() == ExchangeStatus.ERROR) {
                if (endpoint.isRollbackOnError()) {
                    TransactionManager tm = (TransactionManager) endpoint.getServiceUnit().getComponent().getComponentContext().getTransactionManager();
                    tm.setRollbackOnly();
                    return;
                } else if (exchange instanceof InOnly) {
                    log.info("Exchange in error: " + exchange, exchange.getError());
                    return;
                } else {
                    connection = connectionFactory.createConnection();
                    Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
                    Exception error = exchange.getError();
                    if (error == null) {
                        error = new Exception("Exchange in error");
                    }
                    response = session.createObjectMessage(error);
                    MessageProducer producer = session.createProducer(message.getJMSReplyTo());
                    if (endpoint.isUseMsgIdInResponse()) {
                        response.setJMSCorrelationID(message.getJMSMessageID());
                    } else {
                        response.setJMSCorrelationID(message.getJMSCorrelationID());
                    }
                    producer.send(response);
                }
            } else {
                connection = connectionFactory.createConnection();
                Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
                response = fromNMSResponse(exchange, context, session);
                if (response != null) {
                    MessageProducer producer = session.createProducer(message.getJMSReplyTo());
                    if (endpoint.isUseMsgIdInResponse()) {
                        response.setJMSCorrelationID(message.getJMSMessageID());
                    } else {
                        response.setJMSCorrelationID(message.getJMSCorrelationID());
                    }
                    producer.send(response);
                }
            }
        } finally {
            if (connection != null) {
                connection.close();
            }
            if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
                exchange.setStatus(ExchangeStatus.DONE);
                channel.send(exchange);
            }
        }
    }

}
TOP

Related Classes of org.apache.servicemix.jms.jca.JcaConsumerProcessor

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.