package com.activequant.transport.activemq;
import java.util.HashMap;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.log4j.Logger;
import com.activequant.domainmodel.ETransportType;
import com.activequant.domainmodel.Instrument;
import com.activequant.domainmodel.MarketDataInstrument;
import com.activequant.domainmodel.TradeableInstrument;
import com.activequant.domainmodel.exceptions.TransportException;
import com.activequant.interfaces.transport.IPublisher;
import com.activequant.interfaces.transport.IReceiver;
import com.activequant.interfaces.transport.ITransportFactory;
/**
*
* @author ustaudinger
*
*/
public class ActiveMQTransportFactory implements ITransportFactory {
private static ActiveMQConnectionFactory connectionFactory;
private static Connection connection;
private static Session session;
private Logger log = Logger.getLogger(ActiveMQConnectionFactory.class
.getName());
private HashMap<String, IPublisher> publisherMap = new HashMap<String, IPublisher>();
private HashMap<String, IReceiver> receiverMap = new HashMap<String, IReceiver>();
/**
* constructs an activemq transport factory that connects to a specific host
* and port.
*
* @param host
* JMS server host
* @param port
* JMS server port.
* @throws Exception
*/
public ActiveMQTransportFactory(String host, int port) throws Exception {
// failover: means that it will automatically reconnect.
String conUrl = "failover:tcp://" + host + ":" + port
+ "??wireFormat.maxInactivityDuration=0";
log.info("Constructing ActiveMQTransportFactory for " + conUrl);
connectionFactory = new ActiveMQConnectionFactory(conUrl);
connectionFactory.setProducerWindowSize(1024000);
connectionFactory.setUseAsyncSend(true);
connectionFactory.setOptimizeAcknowledge(true);
connection = connectionFactory.createTopicConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/**
* constructs an activemq transport factory that connects to a specific host
* and port.
*
* @param host
* JMS server host
* @param port
* JMS server port.
* @throws Exception
*/
public ActiveMQTransportFactory(String host, int port, String username, String password) throws Exception {
// failover: means that it will automatically reconnect.
String conUrl = "failover:tcp://" + host + ":" + port
+ "??wireFormat.maxInactivityDuration=0";
log.info("Constructing ActiveMQTransportFactory for " + conUrl);
//
connectionFactory = new ActiveMQConnectionFactory(conUrl);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setProducerWindowSize(1024000);
connectionFactory.setUseAsyncSend(true);
connectionFactory.setOptimizeAcknowledge(true);
connection = connectionFactory.createTopicConnection(username, password);
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/**
* constructs and in-memory active mq transport factory.
*
* @throws Exception
*/
public ActiveMQTransportFactory() throws Exception {
String conUrl = "vm://localhost";
log.info("Constructing embedded ActiveMQTransportFactory for " + conUrl);
connectionFactory = new ActiveMQConnectionFactory(conUrl);
connectionFactory.setProducerWindowSize(1024000);
connection = connectionFactory.createTopicConnection();
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/**
* creates a publisher.
*
* @param destination
* @throws Exception
*/
private void createPublisher(String destination) throws TransportException {
String originalDestination = destination;
// reducing the amount of topics. working through selectors.
if (destination.length() >= 5)
destination = destination.substring(0, 4); // +
// (destination.hashCode()
// % 5);
if (!publisherMap.containsKey(originalDestination)) {
try {
Destination topic = session.createTopic(destination);
MessageProducer producer = session.createProducer(topic);
JMSPublisher j = new JMSPublisher(session, producer,
originalDestination);
publisherMap.put(originalDestination, j);
if (log.isDebugEnabled())
log.debug("Added publisher for " + originalDestination);
} catch (Exception ex) {
throw new TransportException(ex);
}
}
}
private void createReceiver(String destination) throws TransportException {
String originalDestination = destination;
// reducing the amount of topics. working through selectors.
if (destination.length() >= 5)
destination = destination.substring(0, 4);
if (!receiverMap.containsKey(originalDestination)) {
try {
Destination topic = session.createTopic(destination);
MessageConsumer consumer = null;
if (originalDestination.endsWith(".*")) {
consumer = session.createConsumer(topic);
} else {
consumer = session.createConsumer(topic, "channelId='"
+ originalDestination + "'");
}
JMSReceiver j = new JMSReceiver();
consumer.setMessageListener(j);
receiverMap.put(originalDestination, j);
if (log.isDebugEnabled())
log.debug("Added receiver for " + originalDestination);
} catch (Exception ex) {
throw new TransportException(ex);
}
}
}
public synchronized IPublisher getPublisher(ETransportType transType,
String id) throws TransportException {
String destination = transType.toString() + "." + id;
createPublisher(destination);
return publisherMap.get(destination);
}
public synchronized IReceiver getReceiver(ETransportType transType,
String id) throws TransportException {
String destination = transType.toString() + "." + id;
createReceiver(destination);
return receiverMap.get(destination);
}
public synchronized IPublisher getPublisher(ETransportType transType,
Instrument instrument) throws TransportException {
String destination = transType.toString() + "." + instrument.getId();
createPublisher(destination);
return publisherMap.get(destination);
}
public synchronized IReceiver getReceiver(ETransportType transType,
Instrument instrument) throws TransportException {
String destination = transType.toString() + "." + instrument.getId();
createReceiver(destination);
return receiverMap.get(destination);
}
public IPublisher getPublisher(ETransportType transType,
MarketDataInstrument instrument) throws TransportException {
String destination = transType.toString() + "."
+ instrument.getMdProvider() + "."
+ instrument.getProviderSpecificId();
createPublisher(destination);
return publisherMap.get(destination);
}
public IReceiver getReceiver(ETransportType transType,
MarketDataInstrument instrument) throws TransportException {
String destination = transType.toString() + "."
+ instrument.getMdProvider() + "."
+ instrument.getProviderSpecificId();
createReceiver(destination);
return receiverMap.get(destination);
}
public IPublisher getPublisher(String channel) throws TransportException {
createPublisher(channel);
return publisherMap.get(channel);
}
public IReceiver getReceiver(String channel) throws TransportException {
createReceiver(channel);
return receiverMap.get(channel);
}
public IPublisher getPublisher(ETransportType transType,
TradeableInstrument instrument) throws TransportException {
String destination = transType.toString() + "."
+ instrument.getTradingProvider() + "."
+ instrument.getProviderSpecificId();
createPublisher(destination);
return publisherMap.get(destination);
}
public IReceiver getReceiver(ETransportType transType,
TradeableInstrument instrument) throws TransportException {
String destination = transType.toString() + "."
+ instrument.getTradingProvider() + "."
+ instrument.getProviderSpecificId();
createReceiver(destination);
return receiverMap.get(destination);
}
}