package edu.isi.karma.storm.bolt;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.json.simple.parser.ParseException;
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.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import edu.isi.karma.storm.function.JSONToMerge;
public class KarmaReducerBolt extends BaseRichBolt {
/**
*
*/
private static final long serialVersionUID = 1L;
private OutputCollector collector;
protected Map<String, JSONToMerge> allJsonToMerge;
protected Set<String> models;
protected Boolean outputId = false;
public KarmaReducerBolt(Set<String> models)
{
this.models = models;
}
public KarmaReducerBolt(Set<String> models, boolean outputId)
{
this.models = models;
this.outputId = outputId;
}
@SuppressWarnings("rawtypes")
@Override
public void prepare(Map globalConf, TopologyContext context,
OutputCollector collector) {
allJsonToMerge = new HashMap<>();
this.collector = collector;
}
@Override
public void execute(Tuple input) {
String id = input.getStringByField("id");
if(!allJsonToMerge.containsKey(input.getValueByField("id")))
{
allJsonToMerge.put(id, new JSONToMerge(models.size()));
}
JSONToMerge jsonToMerge = allJsonToMerge.get(id);
jsonToMerge.addJSON(input, input.getStringByField("model"), input.getStringByField("json"));
if(jsonToMerge.isReadyToMerge())
{
String mergedJson;
try {
mergedJson = jsonToMerge.merge();
} catch (ParseException e) {
//TODO handle this properly
mergedJson = "";
}
if(outputId)
{
collector.emit(new Values(id, mergedJson));
}
else
{
collector.emit(new Values(mergedJson));
}
List<Tuple> tuplesToAck = jsonToMerge.getTuplesToAck();
for(Tuple tuple : tuplesToAck)
{
collector.ack(tuple);
}
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
if(outputId)
{
declarer.declare(new Fields("id", "json"));
}
else
{
declarer.declare(new Fields("json"));
}
}
}