package cgl.iotcloud.transport.kestrel; import cgl.iotcloud.core.Configuration; import cgl.iotcloud.core.transport.Channel; import cgl.iotcloud.core.transport.ChannelName; import cgl.iotcloud.core.transport.Direction; import cgl.iotcloud.core.transport.Transport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; public class KestrelTransport implements Transport { private static final Integer KESTREL_DEFAULT_PORT = 1235; private static Logger LOG = LoggerFactory.getLogger(KestrelTransport.class); public static final String PROP_URLS = "servers"; public static final String QUEUE_NAME_PROPERTY = "queueName"; public static final String ACK = "ack"; public static final String SERVER = "server"; public static final String BLACKLIST_TIME = "blackListTime"; public static final String EXPIRATION_TIME = "expirationTIme"; public static final String RECEIVE_TIMEOUT = "receiveTimeOut"; private Map<ChannelName, KestrelConsumer> receivers = new HashMap<ChannelName, KestrelConsumer>(); private Map<ChannelName, KestrelProducer> senders = new HashMap<ChannelName, KestrelProducer>(); private Map<String, Server> urls = new HashMap<String, Server>(); private String siteId; @Override public void configure(String siteId, Map properties) { this.siteId = siteId; try { Map params = (Map)properties.get(Configuration.TRANSPORT_PROPERTIES); Object urlProp = params.get(PROP_URLS); if (urlProp == null || !(urlProp instanceof Map)) { String message = "servers is required by the Kestrel Transport"; LOG.error(message); throw new RuntimeException(message); } Map servers = (Map) urlProp; for (Object o : servers.keySet()) { if (o instanceof String) { String url = ((Map) urlProp).get(o).toString(); String server = (String) o; String tokens[] = url.split(":"); if (tokens.length == 2) { urls.put(server, new Server(tokens[0], Integer.parseInt(tokens[1]))); } else { urls.put(server, new Server(tokens[0], KESTREL_DEFAULT_PORT)); } } } } catch (Exception e) { String msg = "Error in key management for rabbitMQ"; LOG.error(msg, e); throw new RuntimeException(msg, e); } } @Override public void registerChannel(ChannelName name, Channel channel) { Map channelConf = channel.getProperties(); if (channelConf == null) { throw new IllegalArgumentException("Channel properties must be specified"); } String queueName = (String) channelConf.get(QUEUE_NAME_PROPERTY); String qosProp = (String) channelConf.get(ACK); String server = (String) channelConf.get(SERVER); if (server == null) { throw new IllegalArgumentException("The server should be present"); } String blackListProp = (String) channelConf.get(BLACKLIST_TIME); String expirationProp = (String) channelConf.get(EXPIRATION_TIME); String timeOutProp = (String) channelConf.get(RECEIVE_TIMEOUT); int qosInt = 0; if (qosProp != null) { qosInt = Integer.parseInt(qosProp); } Server s = urls.get(server); if (s == null) { throw new IllegalArgumentException("The server configuration should exist " + server); } if (channel.getDirection() == Direction.OUT) { KestrelProducer sender = new KestrelProducer(new KestrelDestination(s.getHost(), s.getPort(), siteId + "." + queueName), channel.getOutQueue()); if (blackListProp != null) { long blackListTime = Long.parseLong(blackListProp); sender.setBlackListTime(blackListTime); } if (expirationProp != null) { long expirationTime = Long.parseLong(expirationProp); sender.setBlackListTime(expirationTime); } sender.open(); senders.put(name, sender); } else if (channel.getDirection() == Direction.IN) { KestrelConsumer listener = new KestrelConsumer(new KestrelDestination(s.getHost(), s.getPort(), siteId + "." + queueName), channel.getInQueue()); if (blackListProp != null) { long blackListTime = Long.parseLong(blackListProp); listener.setBlackListTime(blackListTime); } if (timeOutProp != null) { int timOut = Integer.parseInt(timeOutProp); listener.setTimeoutMillis(timOut); } listener.open(); receivers.put(name, listener); } } @Override public void unRegisterChannel(ChannelName name, Channel channel) { } @Override public void start() { for (KestrelProducer producer : senders.values()) { producer.open(); } for (KestrelConsumer consumer : receivers.values()) { consumer.open(); } } @Override public void stop() { for (KestrelProducer producer : senders.values()) { producer.close(); } for (KestrelConsumer consumer : receivers.values()) { consumer.close(); } } static class Server { private String host; private int port; Server(String host, int port) { this.host = host; this.port = port; } public String getHost() { return host; } public int getPort() { return port; } } }