package nl.us2.cloudpelican.stormprocessor;
import backtype.storm.Config;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichBolt;
import backtype.storm.tuple.Tuple;
import org.apache.commons.lang.NotImplementedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import storm.starter.util.TupleHelpers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* Created by robin on 30/06/15.
*/
public class AbstractSinkBolt extends BaseRichBolt {
protected HashMap<String, ArrayList<String>> resultAggregator;
protected OutputCollector _collector;
protected String sinkId;
protected Settings settings;
protected int batchSize;
protected Executor executor;
private static final Logger LOG = LoggerFactory.getLogger(AbstractSinkBolt.class);
public AbstractSinkBolt(String sinkId, Settings settings) {
this.sinkId = sinkId;
this.settings = settings;
this.batchSize = 500;
}
public void prepare(Map conf, TopologyContext context, OutputCollector collector) {
_collector = collector;
resultAggregator = new HashMap<String, ArrayList<String>>();
prepareSink(conf, context, collector);
executor = Executors.newFixedThreadPool(2);
}
public void execute(Tuple tuple) {
if (TupleHelpers.isTickTuple(tuple)) {
_collector.ack(tuple);
executeTick();
} else {
executeTuple(tuple);
_collector.ack(tuple);
}
}
protected String _sinkVarPrefix(String k) {
return "sinks." + sinkId + "." + k;
}
public String getSinkVar(String k) {
return getSinkVarOrDefault(k, null);
}
public String getSinkVarOrDefault(String k, String d) {
String pk = _sinkVarPrefix(k);
String val = settings.getOrDefault(pk, d);
LOG.info("Sink var: " + pk + "=" + val);
return val;
}
public boolean isValid() {
return false;
}
public void executeTick() {
_flush();
}
protected void _flush() {
throw new NotImplementedException();
}
public void executeTuple(Tuple tuple) {
String filterId = tuple.getStringByField("filter_id");
String msg = tuple.getStringByField("msg");
// Append in-memory
if (!resultAggregator.containsKey(filterId)) {
resultAggregator.put(filterId, new ArrayList<String>());
}
resultAggregator.get(filterId).add(msg);
// Flush auto
if (resultAggregator.get(filterId).size() >= batchSize) {
_flush();
}
// No ack, is handled in outer
}
public Map<String, Object> getComponentConfiguration() {
Config conf = new Config();
int tickFrequencyInSeconds = 10;
conf.put(Config.TOPOLOGY_TICK_TUPLE_FREQ_SECS, tickFrequencyInSeconds);
return conf;
}
public void prepareSink(Map conf, TopologyContext context, OutputCollector collector) {
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
}
}