package org.calrissian.flowbox.bolt; 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 backtype.storm.tuple.Values; import org.calrissian.flowbox.model.Event; import org.calrissian.flowbox.model.Flow; import org.calrissian.flowbox.model.PartitionOp; import java.util.Collection; import java.util.HashMap; import java.util.Map; import static org.calrissian.flowbox.Constants.*; import static org.calrissian.flowbox.FlowboxFactory.declarePartitionedOutputStreams; import static org.calrissian.flowbox.spout.MockFlowLoaderSpout.FLOW_LOADER_STREAM; import static org.calrissian.flowbox.support.Window.buildKeyIndexForEvent; public class PartitionBolt extends BaseRichBolt { Map<String,Flow> flows; OutputCollector collector; @Override public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) { this.collector = outputCollector; flows = new HashMap<String, Flow>(); } @Override public void execute(Tuple tuple) { if(FLOW_LOADER_STREAM.equals(tuple.getSourceStreamId())) { for(Flow flow : (Collection<Flow>)tuple.getValue(0)) flows.put(flow.getId(), flow); } else if(!"tick".equals(tuple.getSourceStreamId())) { String flowId = tuple.getStringByField(FLOW_ID); Event event = (Event) tuple.getValueByField(EVENT); int idx = tuple.getIntegerByField(FLOW_OP_IDX); String streamName = tuple.getStringByField(STREAM_NAME); String previousStream = tuple.getStringByField(LAST_STREAM); idx++; Flow flow = flows.get(flowId); if(flow != null) { PartitionOp partitionOp = (PartitionOp) flow.getStream(streamName).getFlowOps().get(idx); String nextStream = idx+1 < flow.getStream(streamName).getFlowOps().size() ? flow.getStream(streamName).getFlowOps().get(idx + 1).getComponentName() : "output"; String hash = buildKeyIndexForEvent(event, partitionOp.getFields()); if((nextStream.equals("output") && flow.getStream(streamName).isStdOutput()) || !nextStream.equals("output")) collector.emit(nextStream, tuple, new Values(flowId, event, idx, streamName, hash, previousStream)); // send directly to any other non std output streams that may be configured if(nextStream.equals("output") && flow.getStream(streamName).getOutputs() != null) { for (String output : flow.getStream(streamName).getOutputs()) { String outputStream = flow.getStream(output).getFlowOps().get(0).getComponentName(); collector.emit(outputStream, tuple, new Values(flowId, event, -1, output, streamName)); } } } } collector.ack(tuple); } @Override public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) { declarePartitionedOutputStreams(outputFieldsDeclarer); } }