package main.java.bolts;
import static main.java.utils.constants.WorkberchConstants.INDEX_FIELD;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import main.java.utils.WorkberchTuple;
import main.java.utils.redis.RedisHandeler;
import org.apache.commons.lang.StringUtils;
import backtype.storm.generated.GlobalStreamId;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.BasicOutputCollector;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseBasicBolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
abstract public class WorkberchGenericBolt extends BaseBasicBolt {
private static final long serialVersionUID = 1656859471059135768L;
private final List<String> runningNodes = new ArrayList<String>();
private final List<String> outputFields;
private String boltId;
private int taskId;
public WorkberchGenericBolt(final List<String> outputFields) {
this.outputFields = new ArrayList<String>(outputFields);
this.outputFields.add(INDEX_FIELD);
}
protected void emitTuple(final List<Object> tuple, final BasicOutputCollector collector, final boolean lastValue,
final String uuid) {
RedisHandeler.increseEmitedState(boltId);
if (lastValue) {
RedisHandeler.setStateFinished(boltId);
}
collector.emit(tuple);
}
protected List<String> getRunningNodes() {
return runningNodes;
}
protected List<String> getOutputFields() {
return outputFields;
}
public String getBoltId() {
return boltId;
}
public int getTaskId() {
return taskId;
}
@Override
@SuppressWarnings("rawtypes")
public void prepare(final Map stormConf, final TopologyContext context) {
boltId = context.getThisComponentId();
taskId = context.getThisTaskId();
for (final GlobalStreamId globalStreamId : context.getThisSources().keySet()) {
runningNodes.add(globalStreamId.get_componentId());
}
}
@Override
public void execute(final Tuple input, final BasicOutputCollector collector) {
int runningNodesCount = 0;
final long incState = RedisHandeler.increseRecivedState(boltId + "-" + input.getSourceComponent());
for (final String node : runningNodes) {
if (StringUtils.equals(node, input.getSourceComponent()) && !(RedisHandeler.getFinishedState(node) &&
incState == RedisHandeler.getEmitedState(node))) {
runningNodesCount++;
} else if (!(RedisHandeler.getFinishedState(node)
&& RedisHandeler.getRecivedState(boltId + "-" + node) == RedisHandeler.getEmitedState(node))) {
runningNodesCount++;
}
}
final WorkberchTuple baseTuple = new WorkberchTuple(input);
executeProvenance(baseTuple, collector, runningNodesCount == 0);
}
@Override
public void declareOutputFields(final OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(outputFields));
}
abstract public void executeProvenance(WorkberchTuple input, BasicOutputCollector collector, boolean lastValues);
}