package main.java.bolts; import static main.java.utils.constants.WorkberchConstants.INDEX_FIELD; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import main.java.utils.WorkberchTuple; import org.apache.commons.lang.StringUtils; import backtype.storm.topology.BasicOutputCollector; public class WorkberchCartesianDummyBolt extends WorkberchProvenanceBolt { private static final long serialVersionUID = 1L; private final String flowField; private final int singleValuesSize; private final Map<String, Object> singleValues = new HashMap<String, Object>(); private final List<WorkberchTuple> waitingTuples = new ArrayList<WorkberchTuple>(); private void emitTuple(final WorkberchTuple input, final BasicOutputCollector collector, final boolean lastValues, final String uuid) { final List<Object> emitTuple = new ArrayList<Object>(); for (final String field : getOutputFields()) { if (StringUtils.equals(field, getBoltId().replace("CROSS_", StringUtils.EMPTY) + "." + flowField)) { emitTuple.add(input.getValues().get(getBoltId().replace("CROSS_", StringUtils.EMPTY) + "." + flowField)); } else if (StringUtils.equals(field, INDEX_FIELD)) { emitTuple.add(input.getValues().get(INDEX_FIELD)); } else { emitTuple.add(singleValues.get(field)); } } emitTuple(emitTuple, collector, lastValues, uuid); } public WorkberchCartesianDummyBolt(final String guid, final List<String> outputFields, final String flowField) { super(guid, outputFields); singleValuesSize = outputFields.size() - 1; this.flowField = flowField; } @Override public void executeLogic(final WorkberchTuple input, final BasicOutputCollector collector, final boolean lastValues, final String uuid) { final String fieldFlowId = getBoltId().replace("CROSS_", "") + "." + flowField; if (!input.getValues().containsKey(fieldFlowId)) { for (final String field: input.getFields()) { if (!field.equals(INDEX_FIELD)) { singleValues.put(field, input.getValues().get(field)); } } if (singleValues.size() >= singleValuesSize) { final Iterator<WorkberchTuple> iterWaiting = waitingTuples.iterator(); while (iterWaiting.hasNext()) { final WorkberchTuple valueTuEmit = iterWaiting.next(); for(final String keyValue: singleValues.keySet()) { valueTuEmit.getValues().put(keyValue, singleValues.get(keyValue)); valueTuEmit.getFields().add(keyValue); } emitTuple(valueTuEmit, collector, lastValues && !iterWaiting.hasNext(), uuid); } } else { waitingTuples.add(input); } } else if (input.getValues().containsKey(fieldFlowId) && singleValues.size() >= singleValuesSize) { for(final String keyValue: singleValues.keySet()) { input.getValues().put(keyValue, singleValues.get(keyValue)); input.getFields().add(keyValue); } emitTuple(input, collector, lastValues, uuid); } } }