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

org.apacheextras.camel.component.wmq.WMQConsumer Maven / Gradle / Ivy

/**************************************************************************************
 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.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.headers.MQHeaderList;
import com.ibm.mq.headers.MQRFH2;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.SuspendableService;
import org.apache.camel.impl.ScheduledPollConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.function.Function;

public class WMQConsumer extends ScheduledPollConsumer implements SuspendableService {

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

    private final Function mqHeaderListFactory;

    private MQQueueManager mqQueueManager = null;

    public WMQConsumer(WMQEndpoint endpoint, Processor processor) {
        this(endpoint, processor, WMQConsumer::createMqHeaderList);
    }


    public WMQConsumer(WMQEndpoint endpoint, Processor processor,
                       Function mqHeaderListFactory) {
        super(endpoint, processor);
        this.mqHeaderListFactory = mqHeaderListFactory;
    }


    @Override
    protected int poll() throws Exception {
        Exchange exchange = getEndpoint().createExchange();

        Message in = exchange.getIn();

        WMQComponent component = (WMQComponent) getEndpoint().getComponent();

        if (mqQueueManager == null) {
            mqQueueManager = component.getQueueManager(getEndpoint().getQueueManagerName(),
                    getEndpoint().getQueueManagerHostname(),
                    getEndpoint().getQueueManagerPort(),
                    getEndpoint().getQueueManagerChannel(),
                    getEndpoint().getQueueManagerUserID(),
                    getEndpoint().getQueueManagerPassword(),
                    getEndpoint().getQueueManagerCCSID());
        }

        MQDestination destination = null;
        try {
            LOGGER.debug("Consuming from {}", getEndpoint().getDestinationName());

            if (getEndpoint().getDestinationName().startsWith("topic:")) {
                String destinationName = getEndpoint().getDestinationName().substring("topic:".length());
                int options = CMQC.MQSO_CREATE | CMQC.MQSO_RESUME | CMQC.MQSO_DURABLE | CMQC.MQSO_FAIL_IF_QUIESCING;
                destination = mqQueueManager.accessTopic(destinationName, null, options, null, null);
            } else {
                String destinationName = getEndpoint().getDestinationName();
                if (destinationName.startsWith("queue:")) {
                    destinationName = destinationName.substring("queue:".length());
                }
                destination = mqQueueManager.accessQueue(destinationName, MQConstants.MQOO_INPUT_AS_Q_DEF, null, null, null);
            }

            MQMessage message = new MQMessage();
            MQGetMessageOptions options = new MQGetMessageOptions();
            options.options = MQConstants.MQGMO_WAIT + MQConstants.MQGMO_PROPERTIES_COMPATIBILITY + MQConstants.MQGMO_ALL_SEGMENTS_AVAILABLE + MQConstants.MQGMO_COMPLETE_MSG + MQConstants.MQGMO_ALL_MSGS_AVAILABLE;
            options.waitInterval = MQConstants.MQWI_UNLIMITED;
            LOGGER.info("Waiting for message ...");
            destination.get(message, options);

            LOGGER.info("Message consumed");

            LOGGER.info("Dealing with MQMD headers");
            LOGGER.info("\tmq.mqmd.format: {}", message.format);
            in.setHeader("mq.mqmd.format", message.format);
            LOGGER.info("\tmq.mqmd.charset: {}", message.characterSet);
            in.setHeader("mq.mqmd.charset", message.characterSet);
            LOGGER.info("\tmq.mqmd.expiry: {}", message.expiry);
            in.setHeader("mq.mqmd.expiry", message.expiry);
            LOGGER.info("\tmq.mqmd.put.appl.name: {}", message.putApplicationName);
            in.setHeader("mq.mqmd.put.appl.name", message.putApplicationName);
            LOGGER.info("\tmq.mqmd.group.id: {}", message.groupId);
            in.setHeader("mq.mqmd.group.id", message.groupId);
            LOGGER.info("\tmq.mqmd.msg.seq.number: {}", message.messageSequenceNumber);
            in.setHeader("mq.mqmd.msg.seq.number", message.messageSequenceNumber);
            LOGGER.info("\tmq.mqmd.msg.accounting.token: {}", message.accountingToken);
            in.setHeader("mq.mqmd.msg.accounting.token", message.accountingToken);
            LOGGER.info("\tmq.mqmd.correl.id: {}", message.correlationId);
            in.setHeader("mq.mqmd.correl.id", message.correlationId);
            LOGGER.info("\tmq.mqmd.replyto.q: {}", message.replyToQueueName);
            in.setHeader("mq.mqmd.replyto.q", message.replyToQueueName);
            LOGGER.info("\tmq.mqmd.replyto.q.mgr: {}", message.replyToQueueManagerName);
            in.setHeader("mq.mqmd.replyto.q.mgr", message.replyToQueueManagerName);
            LOGGER.info("\tmq.mqmd.putdatetime: {}", message.putDateTime);
            in.setHeader("mq.mqmd.putdatetime", message.putDateTime);
            LOGGER.info("\tmq.mqmd.user.id: {}", message.userId);
            in.setHeader("mq.mqmd.user.id", message.userId);
            LOGGER.info("\tmq.mqmd.type", message.messageType);
            in.setHeader("mq.mqmd.type", message.messageType);
            LOGGER.info("\tmq.mqmd.priority", message.priority);
            in.setHeader("mq.mqmd.priority", message.priority);
            LOGGER.info("\tmq.mqmd.persistence", message.persistence);
            in.setHeader("mq.mqmd.persistence", message.persistence);
            LOGGER.info("\tmq.mqmd.backout.count", message.backoutCount);
            in.setHeader("mq.mqmd.backout.count", message.backoutCount);
            LOGGER.info("\tmq.mqmd.report", message.report);
            in.setHeader("mq.mqmd.report", message.report);
            LOGGER.info("\tmq.mqmd.feedback", message.feedback);
            in.setHeader("mq.mqmd.feedback", message.feedback);
            LOGGER.info("\tmq.mqmd.original.length", message.originalLength);
            in.setHeader("mq.mqmd.original.length", message.originalLength);
            LOGGER.info("\tmq.mqmd.appl.type", message.putApplicationType);
            in.setHeader("mq.mqmd.appl.type", message.putApplicationType);
            LOGGER.info("\tmq.mqmd.appl.id.data", message.applicationIdData);
            in.setHeader("mq.mqmd.appl.id.data", message.applicationIdData);
            LOGGER.info("\tmq.mqmd.appl.origin.data", message.applicationOriginData);
            in.setHeader("mq.mqmd.appl.origin.data", message.applicationOriginData);
            LOGGER.info("\tmq.mqmd.id", message.messageId);
            in.setHeader("mq.mqmd.id", message.messageId);
            LOGGER.info("\tmq.mqmd.offset", message.offset);
            in.setHeader("mq.mqmd.offset", message.offset);
            LOGGER.info("\tmq.mqmd.flags", message.messageFlags);
            in.setHeader("mq.mqmd.flags", message.messageFlags);
            LOGGER.info("\tmq.mqmd.length.total", message.getTotalMessageLength());
            in.setHeader("mq.mqmd.length.total", message.getTotalMessageLength());
            LOGGER.info("\tmq.mqmd.length.data", message.getDataLength());
            in.setHeader("mq.mqmd.length.data", message.getDataLength());
            LOGGER.info("\tmq.mqmd.encoding", message.encoding);
            in.setHeader("mq.mqmd.encoding", message.encoding);

            MQHeaderList headerList = this.mqHeaderListFactory.apply(message);
            // TODO MQRFH, MQCIH, MQDLH, MQIIH, MQRMH, MQSAPH, MQWIH, MQXQH, MQDH, MQEPH headers support
            int index = headerList.indexOf("MQRFH2");
            if (index >= 0) {
                LOGGER.info("MQRFH2 header detected (index " + index + ")");
                MQRFH2 rfh = (MQRFH2) headerList.get(index);
                LOGGER.info("\tmq.rfh2.format: " + rfh.getFormat());
                in.setHeader("mq.rfh2.format", rfh.getFormat());
                LOGGER.info("\tmq.rfh2.struct.id: " + rfh.getStrucId());
                in.setHeader("mq.rfh2.struct.id", rfh.getStrucId());
                LOGGER.info("\tmq.rfh2.encoding: " + rfh.getEncoding());
                in.setHeader("mq.rfh2.encoding", rfh.getEncoding());
                LOGGER.info("\tmq.rfh2.coded.charset.id: " + rfh.getCodedCharSetId());
                in.setHeader("mq.rfh2.coded.charset.id", rfh.getCodedCharSetId());
                LOGGER.info("\tmq.rfh2.flags: " + rfh.getFlags());
                in.setHeader("mq.rfh2.flags", rfh.getFlags());
                LOGGER.info("\tmq.rfh2.version: " + rfh.getVersion());
                in.setHeader("mq.rfh2.version", rfh.getVersion());
                MQRFH2.Element[] folders = rfh.getFolders();
                for (MQRFH2.Element folder : folders) {
                    LOGGER.info("mq.rfh2.folder " + folder.getName() + ": " + folder.toXML());
                    in.setHeader("mq.rfh2.folder." + folder.getName(), folder.toXML());
                }
            }


            LOGGER.info("Reading body");
            byte[] buffer = new byte[message.getDataLength()];
            message.readFully(buffer);
            saveBody(in, buffer);

            getProcessor().process(exchange);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            exchange.setException(e);
        } finally {
            if (destination != null)
                destination.close();
        }

        if (exchange.getException() != null) {
            getExceptionHandler().handleException("Error processing exchange", exchange, exchange.getException());
        }

        return 1;
    }

    private void saveBody(Message in, byte[] buffer) throws Exception {
        if ("bytes".equals(getEndpoint().getBodyType())) {
            in.setBody(ByteBuffer.wrap(buffer), ByteBuffer.class);
        } else {
            String body;
            if (getEndpoint().getBodyType() != null) {
                body = new String(buffer, getEndpoint().getBodyType());
            } else {
                body = new String(buffer);
            }
            in.setBody(body, String.class);
        }
    }


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


    private static MQHeaderList createMqHeaderList(MQMessage mqMessage) {
        try {
            return new MQHeaderList(mqMessage);
        } catch (IOException | MQDataException e) {
            throw new IllegalStateException(e);
        } catch (NoSuchMethodError e) {
            throw new IllegalStateException("This error can happen when a specific IBM class is not on the classpath (com.ibm.mq.headers.internal.MQMessageWrapper). If you don't add it, constructor throws NoSucheMethodError. Message found : " + e.getMessage(), e);
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy