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

com.datatorrent.lib.io.jms.JMSBase Maven / Gradle / Ivy

/**
 * 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 com.datatorrent.lib.io.jms;

import java.util.Map;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Session;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.commons.beanutils.BeanUtils;

import com.google.common.collect.Maps;

/**
 * Base class for any JMS input or output adapter operator.
 * 

* Operators should not be derived from this, * rather from AbstractJMSInputOperator or AbstractJMSSinglePortInputOperator or AbstractJMSOutputOperator * or AbstractJMSSinglePortOutputOperator. This creates connection with a JMS broker.
* *
* Ports:
* None
*
* Properties:
* connectionFactoryClass: Connection factory of the JMS provider (Default is ActiveMQ)
* connectionFactoryProperties: Properties to initialize the connection factory (consult your providers documentation)
* ackMode: message acknowledgment mode
* clientId: client id
* subject: name of destination
* durable: flag to indicate durable consumer
* topic: flag to indicate if the destination is a topic or queue
* transacted: flag whether the messages should be transacted or not
*
* Compile time checks:
* usr should not be null
* password should not be null
* url should not be null
*
* Run time checks:
* None
*
* Benchmarks:
* NA
*
* * @since 0.3.2 */ @org.apache.hadoop.classification.InterfaceStability.Evolving public class JMSBase { private static final Logger logger = LoggerFactory.getLogger(JMSBase.class); private transient Connection connection; private transient Session session; private transient Destination destination; private String connectionFactoryClass; private Map connectionFactoryProperties = Maps.newHashMap(); private String ackMode = "CLIENT_ACKNOWLEDGE"; private String clientId = "TestClient"; private String subject = "TEST.FOO"; private int batch = 10; private int messageSize = 255; private boolean durable = false; private boolean topic = false; private boolean verbose = false; protected boolean transacted = true; /** * @return the connection */ public Connection getConnection() { return connection; } /** * @return the session */ public Session getSession() { return session; } /** * @return the destination */ public Destination getDestination() { return destination; } public String getConnectionFactoryClass() { return connectionFactoryClass; } public void setConnectionFactoryClass(String connectionFactoryClass) { this.connectionFactoryClass = connectionFactoryClass; } /** * Return the connection factory properties. Property names are provider specific and can be set directly from configuration, for example:

* dt.operator.JMSOper.connectionFactoryProperties.brokerURL=vm://localhost * @return reference to mutable properties */ public Map getConnectionFactoryProperties() { return connectionFactoryProperties; } public void setConnectionFactoryProperties(Map connectionFactoryProperties) { this.connectionFactoryProperties = connectionFactoryProperties; } /** * @deprecated Use {@link #getConnectionFactoryProperties} to set properties supported by the connection factory. */ @Deprecated public void setUser(String user) { this.connectionFactoryProperties.put("userName", user); } /** * @deprecated Use {@link #getConnectionFactoryProperties} to set properties supported by the connection factory. */ @Deprecated public void setPassword(String password) { this.connectionFactoryProperties.put("password", password); } /** * @deprecated Use {@link #getConnectionFactoryProperties} to set properties supported by the connection factory. */ @Deprecated public void setUrl(String url) { this.connectionFactoryProperties.put("brokerURL", url); } /** * @return the message acknowledgment mode */ public String getAckMode() { return ackMode; } /** * Sets the message acknowledgment mode. * * @param ackMode the message acknowledgment mode to set */ public void setAckMode(String ackMode) { this.ackMode = ackMode; } /** * @return the clientId */ public String getClientId() { return clientId; } /** * Sets the client id. * * @param clientId the id to set for the client */ public void setClientId(String clientId) { this.clientId = clientId; } /** * @return the name of the destination */ public String getSubject() { return subject; } /** * Sets the name of the destination. * * @param subject the name of the destination to set */ public void setSubject(String subject) { this.subject = subject; } /** * @return the batch */ public int getBatch() { return batch; } /** * Sets the batch for the JMS operator. JMS can acknowledge receipt * of messages back to the broker in batches (to improve performance). * * @param batch the size of the batch */ public void setBatch(int batch) { this.batch = batch; } /** * @return the message size */ public int getMessageSize() { return messageSize; } /** * Sets the size of the message. * * @param messageSize the size of the message */ public void setMessageSize(int messageSize) { this.messageSize = messageSize; } /** * @return the durability of the consumer */ public boolean isDurable() { return durable; } /** * Sets the durability feature. Durable queues keep messages around persistently * for any suitable consumer to consume them. * * @param durable the flag to set to the durability feature */ public void setDurable(boolean durable) { this.durable = durable; } /** * @return the topic */ public boolean isTopic() { return topic; } /** * Sets of the destination is a topic or a queue. * * @param topic the flag to set the destination to topic or queue. */ public void setTopic(boolean topic) { this.topic = topic; } public boolean isVerbose() { return verbose; } /** * Sets the verbose option. * * @param verbose the flag to set to enable verbose option */ public void setVerbose(boolean verbose) { this.verbose = verbose; } /** * Get session acknowledge. * Converts acknowledge string into JMS Session variable. */ public int getSessionAckMode(String ackMode) { if ("CLIENT_ACKNOWLEDGE".equals(ackMode)) { return Session.CLIENT_ACKNOWLEDGE; } else if ("AUTO_ACKNOWLEDGE".equals(ackMode)) { return Session.AUTO_ACKNOWLEDGE; } else if ("DUPS_OK_ACKNOWLEDGE".equals(ackMode)) { return Session.DUPS_OK_ACKNOWLEDGE; } else if ("SESSION_TRANSACTED".equals(ackMode)) { return Session.SESSION_TRANSACTED; } else { return Session.CLIENT_ACKNOWLEDGE; // default } } /** * Connection specific setup for JMS. * * @throws JMSException */ public void createConnection() throws JMSException { connection = getConnectionFactory().createConnection(); if (durable && clientId != null) { connection.setClientID(clientId); } logger.debug("Before starting connection."); connection.start(); logger.debug("After starting connection."); // Create session session = connection.createSession(transacted, getSessionAckMode(ackMode)); // Create destination destination = topic ? session.createTopic(subject) : session.createQueue(subject); } /** * Implement connection factory lookup. */ protected ConnectionFactory getConnectionFactory() { logger.debug("class {} properties {}", connectionFactoryClass, connectionFactoryProperties); ConnectionFactory cf; try { if (connectionFactoryClass != null) { @SuppressWarnings("unchecked") Class clazz = (Class)Class.forName(connectionFactoryClass); cf = clazz.newInstance(); } else { cf = new org.apache.activemq.ActiveMQConnectionFactory(); } BeanUtils.populate(cf, connectionFactoryProperties); logger.debug("creation successful."); return cf; } catch (Exception e) { throw new RuntimeException("Failed to create connection factory.", e); } } /** * cleanup connection resources. */ protected void cleanup() { try { session.close(); connection.close(); session = null; connection = null; } catch (JMSException ex) { logger.debug(ex.getLocalizedMessage()); } } /** * @return the transacted */ public boolean isTransacted() { return transacted; } }