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

com.jkoolcloud.tnt4j.streams.inputs.JMSStream Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
/*
 * Copyright 2014-2022 JKOOL, LLC.
 *
 * Licensed 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 com.jkoolcloud.tnt4j.streams.inputs;

import java.lang.IllegalStateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import com.jkoolcloud.tnt4j.core.OpLevel;
import com.jkoolcloud.tnt4j.sink.EventSink;
import com.jkoolcloud.tnt4j.streams.configure.JMSStreamProperties;
import com.jkoolcloud.tnt4j.streams.configure.StreamProperties;
import com.jkoolcloud.tnt4j.streams.utils.LoggerUtils;
import com.jkoolcloud.tnt4j.streams.utils.StreamsConstants;
import com.jkoolcloud.tnt4j.streams.utils.StreamsResources;
import com.jkoolcloud.tnt4j.streams.utils.Utils;

/**
 * Implements a JMS message transported activity stream, where each JMS message payload carried data is assumed to
 * represent a single activity or event which should be recorded.
 * 

* This activity stream requires parsers that can support JMS {@link javax.jms.Message} data. *

* This activity stream supports the following configuration properties (in addition to those supported by * {@link AbstractBufferedStream}): *

    *
  • java.naming.provider.url - JMS server URL. (Required)
  • *
  • Queue - queue destination name or names delimited using {@code ','} char. (Required - at least one of 'Queue' or * 'Topic')
  • *
  • Topic - topic destination name or names delimited using {@code ','} char. (Required - at least one of 'Queue' or * 'Topic')
  • *
  • java.naming.factory.initial - JNDI context factory name. (Required)
  • *
  • JMSConnFactory - JMS connection factory name. (Required)
  • *
  • List of JNDI context configuration properties supported by JMS server implementation. See * {@link javax.naming.Context} for more details. (Optional)
  • *
* * @version $Revision: 1 $ * * @see com.jkoolcloud.tnt4j.streams.parsers.ActivityParser#isDataClassSupported(Object) */ public class JMSStream extends AbstractBufferedStream { private static final EventSink LOGGER = LoggerUtils.getLoggerSink(JMSStream.class); private static final String DEFINITION_DELIMITER = ",";// NON-NLS // Stream properties private String[] queueNames = null; private String[] topicNames = null; private String jmsConnFactory = null; // JMS Context properties private Properties ctxProps = new Properties(); private List jmsDataReceivers = new ArrayList<>(); /** * Constructs an empty JMSStream. Requires configuration settings to set input stream source. */ public JMSStream() { super(); } @Override protected EventSink logger() { return LOGGER; } @Override public Object getProperty(String name) { if (StreamProperties.PROP_QUEUE_NAME.equalsIgnoreCase(name)) { return StringUtils.join(queueNames, DEFINITION_DELIMITER); } if (StreamProperties.PROP_TOPIC_NAME.equalsIgnoreCase(name)) { return StringUtils.join(topicNames, DEFINITION_DELIMITER); } if (JMSStreamProperties.PROP_JMS_CONN_FACTORY.equalsIgnoreCase(name)) { return jmsConnFactory; } String cpv = ctxProps.getProperty(name); if (cpv != null) { return cpv; } return super.getProperty(name); } @Override public void setProperty(String name, String value) { super.setProperty(name, value); if (StreamProperties.PROP_QUEUE_NAME.equalsIgnoreCase(name)) { queueNames = value.split(DEFINITION_DELIMITER); } else if (StreamProperties.PROP_TOPIC_NAME.equalsIgnoreCase(name)) { topicNames = value.split(DEFINITION_DELIMITER); } else if (JMSStreamProperties.PROP_JMS_CONN_FACTORY.equalsIgnoreCase(name)) { jmsConnFactory = value; } else if (!StreamsConstants.isStreamCfgProperty(name, JMSStreamProperties.class)) { ctxProps.put(name, decPassword(value)); } } @Override protected void applyProperties() throws Exception { super.applyProperties(); if (StringUtils.isEmpty(ctxProps.getProperty(Context.PROVIDER_URL))) { throw new IllegalStateException(StreamsResources.getStringFormatted(StreamsResources.RESOURCE_BUNDLE_NAME, "TNTInputStream.property.undefined", Context.PROVIDER_URL)); } if (ArrayUtils.isEmpty(queueNames) && ArrayUtils.isEmpty(topicNames)) { throw new IllegalStateException(StreamsResources.getStringFormatted(StreamsResources.RESOURCE_BUNDLE_NAME, "TNTInputStream.property.undefined.one.of", StreamProperties.PROP_QUEUE_NAME, StreamProperties.PROP_TOPIC_NAME)); } } @Override protected void initialize() throws Exception { super.initialize(); Context ic = new InitialContext(ctxProps); initReceivers(queueNames, ic); initReceivers(topicNames, ic); } private void initReceivers(String[] destinations, Context ic) throws Exception { if (destinations != null) { JMSDataReceiver jmsDataReceiver; for (String destName : destinations) { String tDestName = destName.trim(); if (StringUtils.isNotEmpty(tDestName)) { jmsDataReceiver = new JMSDataReceiver(); jmsDataReceivers.add(jmsDataReceiver); jmsDataReceiver.initialize(ic, tDestName, jmsConnFactory); } } } } @Override protected void start() throws Exception { super.start(); for (JMSDataReceiver jmsDataReceiver : jmsDataReceivers) { jmsDataReceiver.start(); } logger().log(OpLevel.DEBUG, StreamsResources.getBundle(StreamsResources.RESOURCE_BUNDLE_NAME), "TNTInputStream.stream.start", getClass().getSimpleName(), getName()); } @Override protected void cleanup() { for (JMSDataReceiver jmsDataReceiver : jmsDataReceivers) { jmsDataReceiver.shutdown(); } super.cleanup(); } @Override protected boolean isInputEnded() { for (JMSDataReceiver jmsDataReceiver : jmsDataReceivers) { if (!jmsDataReceiver.isInputEnded()) { return false; } } offerDieMarker(); return true; } @Override protected long getActivityItemByteSize(Message itemMsg) { try { if (itemMsg instanceof BytesMessage) { return ((BytesMessage) itemMsg).getBodyLength(); } else if (itemMsg instanceof MapMessage) { } else if (itemMsg instanceof ObjectMessage) { } else if (itemMsg instanceof StreamMessage) { } else if (itemMsg instanceof TextMessage) { String text = ((TextMessage) itemMsg).getText(); return text == null ? 0 : text.length(); } } catch (JMSException exc) { } return 0; // TODO } private class JMSDataReceiver extends InputProcessor implements MessageListener { private ConnectionFactory jmsConFactory; private Connection jmsCon; private Session jmsSession; private MessageConsumer jmsReceiver; private Destination destination; private JMSDataReceiver() { super("JMSStream.JMSDataReceiver"); // NON-NLS } /** * Input data receiver initialization - JMS client configuration. * * @param params * initialization parameters array * * @throws Exception * if fails to initialize data receiver and configure JMS client */ @Override protected void initialize(Object... params) throws Exception { Context ctx = (Context) params[0]; String destinationName = (String) params[1]; String jmsConnFactoryName = (String) params[2]; jmsConFactory = (ConnectionFactory) ctx.lookup(jmsConnFactoryName); jmsCon = jmsConFactory.createConnection(); jmsSession = jmsCon.createSession(false, Session.AUTO_ACKNOWLEDGE); destination = (Destination) ctx.lookup(destinationName); jmsReceiver = jmsSession.createConsumer(destination); jmsReceiver.setMessageListener(this); } /** * Starts JMS client to receive incoming data. Shuts down this data receiver if exception occurs. */ @Override public void run() { if (jmsCon != null) { try { jmsCon.start(); } catch (JMSException exc) { Utils.logThrowable(logger(), OpLevel.ERROR, StreamsResources.getBundle(StreamsResources.RESOURCE_BUNDLE_NAME), "AbstractBufferedStream.input.start.failed", exc); shutdown(); } } } /** * Closes JMS client objects. * * @throws JMSException * if JMS fails to close objects due to internal error */ @Override void closeInternals() throws JMSException { if (jmsReceiver != null) { jmsReceiver.close(); } if (jmsSession != null) { jmsSession.close(); } if (jmsCon != null) { jmsCon.close(); } } /** * Adds received JMS message to input buffer destination. * * @param msg * received JMS message */ @Override public void onMessage(Message msg) { if (msg == null) { return; } addInputToBuffer(msg); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy