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;
}
}