package com.alibaba.jstorm.transactional;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.alibaba.jstorm.client.ConfigExtension;
import com.alibaba.jstorm.transactional.bolt.ITransactionBoltExecutor;
import com.alibaba.jstorm.transactional.bolt.ITransactionStatefulBoltExecutor;
import com.alibaba.jstorm.transactional.bolt.TransactionBolt;
import com.alibaba.jstorm.transactional.bolt.TransactionStatefulBolt;
import com.alibaba.jstorm.transactional.spout.BasicTransactionSpout;
import com.alibaba.jstorm.transactional.spout.ITransactionSpoutExecutor;
import backtype.storm.Config;
import backtype.storm.generated.GlobalStreamId;
import backtype.storm.generated.Grouping;
import backtype.storm.generated.NullStruct;
import backtype.storm.generated.StormTopology;
import backtype.storm.topology.BoltDeclarer;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.IRichSpout;
import backtype.storm.topology.SpoutDeclarer;
import backtype.storm.topology.TopologyBuilder;
public class TransactionTopologyBuilder extends TopologyBuilder {
private Map<String, Set<String>> upToDownstreamComponentsMap = new HashMap<String, Set<String>>();
@Override
public StormTopology createTopology() {
System.setProperty(ConfigExtension.TASK_BATCH_TUPLE, "true");
System.setProperty(Config.TOPOLOGY_ACKER_EXECUTORS, "0");
return super.createTopology();
}
public BoltDeclarer setBolt(String id, ITransactionBoltExecutor bolt) {
return setBolt(id, bolt, null);
}
public BoltDeclarer setBolt(String id, ITransactionBoltExecutor bolt, Number parallelism_hint) {
upToDownstreamComponentsMap.put(id, new HashSet<String>());
validateUnusedId(id);
IRichBolt boltExecutor;
boolean isStatefulBolt = false;
if (bolt instanceof ITransactionStatefulBoltExecutor) {
isStatefulBolt = true;
boltExecutor = new TransactionStatefulBolt((ITransactionStatefulBoltExecutor) bolt);
} else {
boltExecutor = new TransactionBolt((ITransactionBoltExecutor) bolt);
}
initCommon(id, boltExecutor, parallelism_hint);
_bolts.put(id, boltExecutor);
BoltDeclarer ret = new TransactionBoltDeclarer(id);
ret.addConfiguration(TransactionCommon.TRANSACTION_STATEFUL_BOLT, isStatefulBolt);
return ret;
}
public SpoutDeclarer setSpout(String id, ITransactionSpoutExecutor spout) {
return setSpout(id, spout, null);
}
public SpoutDeclarer setSpout(String id, ITransactionSpoutExecutor spout, Number parallelism_hint) {
upToDownstreamComponentsMap.put(id, new HashSet<String>());
IRichSpout spoutExecutor = new BasicTransactionSpout((ITransactionSpoutExecutor) spout);
return super.setSpout(id, spoutExecutor, parallelism_hint);
}
public class TransactionBoltDeclarer extends BoltGetter {
public TransactionBoltDeclarer(String boltId) {
super(boltId);
}
protected BoltDeclarer grouping(String componentId, String streamId, Grouping grouping) {
// Add barrier snapshot stream and success stream for transaction topology
Set<String> downstreamBolts = upToDownstreamComponentsMap.get(componentId);
if (downstreamBolts != null && downstreamBolts.contains(_boltId) == false) {
downstreamBolts.add(_boltId);
_commons.get(_boltId).put_to_inputs(new GlobalStreamId(componentId, TransactionCommon.BARRIER_STREAM_ID),
Grouping.all(new NullStruct()));
}
_commons.get(_boltId).put_to_inputs(new GlobalStreamId(componentId, streamId), grouping);
return this;
}
}
}