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.FlowboxFactory; import org.calrissian.flowbox.model.Event; import org.calrissian.flowbox.model.Flow; import org.calrissian.flowbox.model.SelectOp; import java.util.*; import static org.calrissian.flowbox.Constants.*; import static org.calrissian.flowbox.spout.MockFlowLoaderSpout.FLOW_LOADER_STREAM; public class SelectorBolt 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) { SelectOp selectOp = (SelectOp) flow.getStream(streamName).getFlowOps().get(idx); String nextStream = idx+1 < flow.getStream(streamName).getFlowOps().size() ? flow.getStream(streamName).getFlowOps().get(idx + 1).getComponentName() : "output"; Event newEvent = new Event(event.getId(), event.getTimestamp()); for(Map.Entry<String, Set<org.calrissian.flowbox.model.Tuple>> eventTuple : event.getTuples().entrySet()) { if(selectOp.getFields().contains(eventTuple.getKey())) { for(org.calrissian.flowbox.model.Tuple curTuple : eventTuple.getValue()) { newEvent.put(curTuple); } } } /** * If no selected tuples existed, event will not be emitted */ if((nextStream.equals("output") && flow.getStream(streamName).isStdOutput()) || !nextStream.equals("output")) { if (newEvent.getTuples().size() > 0) collector.emit(nextStream, tuple, new Values(flowId, newEvent, idx, streamName, previousStream)); } // send directly to any non std output streams 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) { FlowboxFactory.declareOutputStreams(outputFieldsDeclarer); } }