package resa.topology;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import redis.clients.jedis.Jedis;
import java.util.Arrays;
import java.util.Map;
/**
* Created by ding on 14-1-16.
*/
public class RedisQueueSpout extends BaseRichSpout {
public static final String OUTPUT_FIELD_NAME = "text";
protected SpoutOutputCollector collector;
private String queue;
private String host;
private byte[] byteQueueName;
private int port;
private transient Jedis jedis = null;
public RedisQueueSpout(String host, int port, String queue) {
this.host = host;
this.port = port;
this.queue = queue;
}
public RedisQueueSpout(String host, int port, String queue, boolean useBinary) {
this.host = host;
this.port = port;
this.queue = queue;
useBinary(useBinary);
}
public void useBinary(boolean use) {
if (use) {
byteQueueName = queue.getBytes();
} else {
byteQueueName = null;
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(OUTPUT_FIELD_NAME));
}
@Override
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
this.collector = spoutOutputCollector;
}
@Override
public void close() {
disconnect();
}
@Override
public void nextTuple() {
Jedis jedis = getConnectedJedis();
if (jedis == null) {
return;
}
Object text;
try {
text = byteQueueName == null ? jedis.lpop(queue) : jedis.lpop(byteQueueName);
} catch (Exception e) {
disconnect();
return;
}
if (text != null) {
emitData(text);
}
}
protected void emitData(Object data) {
collector.emit(Arrays.asList(data), data);
}
private Jedis getConnectedJedis() {
if (jedis != null) {
return jedis;
}
//try connect to redis server
try {
jedis = new Jedis(host, port);
} catch (Exception e) {
}
return jedis;
}
private void disconnect() {
try {
jedis.disconnect();
} catch (Exception e) {
}
jedis = null;
}
}