org.apacheextras.camel.component.wmq.WMQProducer.java Source code

Java tutorial

Introduction

Here is the source code for org.apacheextras.camel.component.wmq.WMQProducer.java

Source

/**************************************************************************************
 https://camel-extra.github.io
    
 This program 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 3
 of the License, or (at your option) any later version.
    
 This program 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; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 02110-1301, USA.
    
 http://www.gnu.org/licenses/lgpl-3.0-standalone.html
 ***************************************************************************************/
package org.apacheextras.camel.component.wmq;

import com.ibm.mq.MQDestination;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.MQDataException;

import java.io.IOException;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.impl.DefaultProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;

public class WMQProducer extends DefaultProducer {

    private final static Logger LOGGER = LoggerFactory.getLogger(WMQProducer.class);

    private final WMQEndpoint endpoint;

    private TransactionTemplate transactionTemplate;
    private WMQUtilities wmqUtilities;

    public WMQProducer(WMQEndpoint endpoint) {
        super(endpoint);
        this.endpoint = endpoint;
        LOGGER.trace("WMQ producer created");

    }

    @Override
    public WMQEndpoint getEndpoint() {
        return (WMQEndpoint) super.getEndpoint();
    }

    public TransactionTemplate getTransactionTemplate() {
        return transactionTemplate;
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    public WMQUtilities getWmqUtilities() {
        return wmqUtilities;
    }

    public void setWmqUtilities(WMQUtilities wmqUtilities) {
        this.wmqUtilities = wmqUtilities;
    }

    /**
     * Populate headers on the IBM MQ Message based on those found on the Exchange.
     * @param in The Exchange
     * @param message The IBM message
     * @throws IOException
     * @throws MQDataException
     */
    public void populateHeaders(Message in, MQMessage message) throws IOException {
        LOGGER.trace("Populating MQMD headers");
        if (in.getHeader("mq.mqmd.format") != null)
            message.format = (String) in.getHeader("mq.mqmd.format");
        if (in.getHeader("mq.mqmd.charset") != null)
            message.characterSet = (Integer) in.getHeader("mq.mqmd.charset");
        if (in.getHeader("mq.mqmd.expiry") != null)
            message.expiry = (Integer) in.getHeader("mq.mqmd.expiry");
        if (in.getHeader("mq.mqmd.put.appl.name") != null)
            message.putApplicationName = (String) in.getHeader("mq.mqmd.put.appl.name");
        if (in.getHeader("mq.mqmd.group.id") != null)
            message.groupId = (byte[]) in.getHeader("mq.mqmd.group.id");
        if (in.getHeader("mq.mqmd.msg.seq.number") != null)
            message.messageSequenceNumber = (Integer) in.getHeader("mq.mqmd.msg.seq.number");
        if (in.getHeader("mq.mqmd.msg.accounting.token") != null)
            message.accountingToken = (byte[]) in.getHeader("mq.mqmd.msg.accounting.token");
        if (in.getHeader("mq.mqmd.correl.id") != null)
            message.correlationId = (byte[]) in.getHeader("mq.mqmd.correl.id");
        if (in.getHeader("mq.mqmd.replyto.q") != null)
            message.replyToQueueName = (String) in.getHeader("mq.mqmd.replyto.q");
        if (in.getHeader("mq.mqmd.replyto.q.mgr") != null)
            message.replyToQueueManagerName = (String) in.getHeader("mq.mqmd.replyto.q.mgr");
        boolean rfh2 = false;
        if (in.getHeaders().containsKey("mq.rfh2.format")) {
            LOGGER.trace("mq.rfh2.format");
            message.format = MQConstants.MQFMT_RF_HEADER_2;
            rfh2 = true;
        }
        if (in.getHeader("mq.rfh2.struct.id") != null && rfh2) {
            LOGGER.trace("mq.rfh2.struct.id defined: {}", in.getHeader("mq.rfh2.struct.id"));
            message.writeString((String) in.getHeader("mq.rfh2.struct.id"));
        } else if (rfh2) {
            LOGGER.trace("mq.rfh2.struct.id not defined, fallback: {}", MQConstants.MQRFH_STRUC_ID);
            message.writeString(MQConstants.MQRFH_STRUC_ID);
        }
        if (in.getHeader("mq.rfh2.version") != null && rfh2) {
            LOGGER.trace("mq.rfh2.version defined: {}", in.getHeader("mq.rfh2.version"));
            message.writeInt4((Integer) in.getHeader("mq.rfh2.version"));
        } else if (rfh2) {
            LOGGER.trace("mq.rfh2.version not defined, fallback: {}", MQConstants.MQRFH_VERSION_2);
            message.writeInt4(MQConstants.MQRFH_VERSION_2);
        }

        // TODO iterator on the headers and folders
        // v2 folders: mcd, jms, usr, PubSub, pscr, other
        LOGGER.trace("Dealing with RFH2 folders");
        String mcd = (String) in.getHeader("mq.rfh2.folder.mcd");
        String jms = (String) in.getHeader("mq.rfh2.folder.jms");
        String usr = (String) in.getHeader("mq.rfh2.folder.usr");
        String pub = (String) in.getHeader("mq.rfh2.folder.psc");
        String pscr = (String) in.getHeader("mq.rfh2.folder.pscr");
        String other = (String) in.getHeader("mq.rfh2.folder.other");

        if (mcd != null) {
            LOGGER.trace("MCD V2 FOLDER: {}", mcd);
            while (mcd.length() % 4 != 0) {
                mcd = mcd + " ";
            }
        }
        if (jms != null) {
            LOGGER.trace("JMS V2 FOLDER: {}", jms);
            while (jms.length() % 4 != 0) {
                jms = jms + " ";
            }
        }
        if (usr != null) {
            LOGGER.trace("USR V2 FOLDER: {}", usr);
            while (usr.length() % 4 != 0) {
                usr = usr + " ";
            }
        }
        if (pub != null) {
            LOGGER.trace("PUB V2 FOLDER: {}", pub);
            while (pub.length() % 4 != 0) {
                pub = pub + " ";
            }
        }
        if (pscr != null) {
            LOGGER.trace("PSCR V2 FOLDER: {}", pscr);
            while (pscr.length() % 4 != 0) {
                pscr = pscr + " ";
            }
        }
        if (other != null) {
            LOGGER.trace("OTHER V2 FOLDER: {}", other);
            while (other.length() % 4 != 0) {
                other = other + " ";
            }
        }

        int folderSize = 0;
        int overhead = 0;
        if (mcd != null) {
            folderSize = folderSize + mcd.length();
            overhead = overhead + 4;
        }
        if (jms != null) {
            folderSize = folderSize + jms.length();
            overhead = overhead + 4;
        }
        if (usr != null) {
            folderSize = folderSize + usr.length();
            overhead = overhead + 4;
        }
        if (pub != null) {
            folderSize = folderSize + pub.length();
            overhead = overhead + 4;
        }
        if (pscr != null) {
            folderSize = folderSize + pscr.length();
            overhead = overhead + 4;
        }
        if (other != null) {
            folderSize = folderSize + other.length();
            overhead = overhead + 4;
        }

        if (rfh2) {
            LOGGER.trace("Set message length: {}", MQConstants.MQRFH_STRUC_LENGTH_FIXED_2 + folderSize + overhead);
            message.writeInt4(MQConstants.MQRFH_STRUC_LENGTH_FIXED_2 + folderSize + overhead);
        }
        if (in.getHeader("mq.rfh2.encoding") != null && rfh2) {
            LOGGER.trace("mq.rfh2.encoding defined: {}", in.getHeader("mq.rfh2.encoding"));
            message.writeInt4((Integer) in.getHeader("mq.rfh2.encoding"));
        } else if (rfh2) {
            LOGGER.trace("mq.rfh2.encoding not defined, fallback: {}", MQConstants.MQENC_NATIVE);
            message.writeInt4(MQConstants.MQENC_NATIVE);
        }
        if (in.getHeader("mq.rfh2.coded.charset.id") != null && rfh2) {
            LOGGER.trace("mq.rfh2.coded.charset.id defined: {}", in.getHeader("mq.rfh2.coded.charset.id"));
            message.writeInt4((Integer) in.getHeader("mq.rfh2.coded.charset.id"));
        } else if (rfh2) {
            LOGGER.trace("mq.rfh2.coded.charset.id not defined, fallback: {}", MQConstants.MQCCSI_DEFAULT);
            message.writeInt4(MQConstants.MQCCSI_DEFAULT);
        }
        if (rfh2) {
            message.writeString(MQConstants.MQFMT_NONE);
            message.writeInt4(MQConstants.MQRFH_NO_FLAGS);
            message.writeInt4(1208);
        }
        if (mcd != null) {
            message.writeInt4(mcd.length());
            message.writeString(mcd);
        }
        if (jms != null) {
            message.writeInt4(jms.length());
            message.writeString(jms);
        }
        if (usr != null) {
            message.writeInt4(usr.length());
            message.writeString(usr);
        }
        if (pub != null) {
            message.writeInt4(pub.length());
            message.writeString(pub);
        }
        if (pscr != null) {
            message.writeInt4(pscr.length());
            message.writeString(pscr);
        }
        if (other != null) {
            message.writeInt4(other.length());
            message.writeString(other);
        }
    }

    /**
     * Checks whether message segmentation is enabled. Currently always set to true.
     * @return true
     */
    public boolean isSegmented() {
        return true;
    }

    /**
     * Creates put options on the IBM MQ Message based on the header mq.put.options on the exchange
     * @param in
     * @return
     */
    public MQPutMessageOptions createPutMessageOptions(Message in) {
        MQPutMessageOptions options = new MQPutMessageOptions();
        // check if header exists, if it does then use values otherwise return null
        if (in.getHeader("mq.put.options") != null) {
            String[] optionsA = ((String) in.getHeader("mq.put.options")).split(",");

            int optionValue = 0;
            for (int i = 0; i < optionsA.length; i++) {
                optionValue += MQConstants.getIntValue(optionsA[i]);
            }
            options.options = optionValue;
            return options;
        } else {
            return null;
        }
    }

    /**
     * {@inheritDoc}
     * 
     * Process a message in the following way:
     *   Get the queue manager for this transaction
     *   Create a connection to a destination
     *   Populate headers
     *   Send message
     *   Close connection
     */
    public void process(Exchange exchange) throws Exception {

        LOGGER.trace("Get the MQQueueManager for this transaction");
        MQQueueManager manager = (MQQueueManager) TransactionSynchronizationManager.getResource("queueManager");
        String id = (String) TransactionSynchronizationManager.getResource("id");

        LOGGER.debug("Producer transaction started with id " + id + " and mananger " + manager.toString()
                + " on thread " + Thread.currentThread().getId());

        Message in = exchange.getIn();

        LOGGER.trace("Accessing to MQQueue {}", endpoint.getDestinationName());
        int MQOO = MQConstants.MQOO_OUTPUT;
        if (in.getHeader("MQOO") != null) {
            LOGGER.trace("MQOO defined to {}", in.getHeader("MQOO"));
            MQOO = (Integer) in.getHeader("MQOO");
        }

        MQDestination destination = null;
        try {
            destination = wmqUtilities.accessDestination(getEndpoint().getDestinationName(), MQOO, manager);

            LOGGER.trace("Creating MQMessage");
            MQMessage message = new MQMessage();
            populateHeaders(in, message);

            LOGGER.trace("Set message segmentation to on based on segmentation settings");
            if (isSegmented()) {
                message.messageFlags = MQConstants.MQMF_SEGMENTATION_ALLOWED;
                message.groupId = null;
            }

            message.writeString(in.getBody(String.class));

            LOGGER.trace("Putting the message ...");
            MQPutMessageOptions putOptions = createPutMessageOptions(in);
            if (putOptions != null) {
                LOGGER.trace("PutOptions are present");
                destination.put(message, putOptions);
            } else {
                destination.put(message);
            }
            LOGGER.debug("Producer transaction finished with id " + id + " and mananger " + manager.toString()
                    + " on thread " + Thread.currentThread().getId());
            destination.close();
        } finally {
            if (destination != null) {
                destination.close();
            }
        }
    }
}