The Tuple interface has many methods to read data sent from upstream components, and these methods can be divided into two categories.
- Get data by subscript
- Get data by field name
read data method
public class TupleImpl extends IndifferentAccessMap implements Seqable, Indexed, IMeta, Tuple { private List<Object> values; private int taskId; private String streamId; private GeneralTopologyContext context; private MessageId id; private IPersistentMap _meta = null; public TupleImpl(GeneralTopologyContext context, List<Object> values, int taskId, String streamId, MessageId id) { this.values = values; this.taskId = taskId; this.streamId = streamId; this.id = id; this.context = context; String componentId = context.getComponentId(taskId); Fields schema = context.getComponentOutputFields(componentId, streamId); if(values.size()!=schema.size()) { throw new IllegalArgumentException( "Tuple created with wrong number of fields. " + "Expected " + schema.size() + " fields but got " + values.size() + " fields"); } } public TupleImpl(GeneralTopologyContext context, List<Object> values, int taskId, String streamId) { this(context, values, taskId, streamId, MessageId.makeUnanchored()); } Long _processSampleStartTime = null; Long _executeSampleStartTime = null; //Get the Fields defined by Tuple from the context of the task [defined when the task is created] public Fields getFields() { return context.getComponentOutputFields(getSourceComponent(), getSourceStreamId()); } //Get the subscript of the field, and directly get the corresponding data in the values[List] public Object getValueByField(String field) { return values.get(fieldIndex(field)); } public String getStringByField(String field) { return (String) values.get(fieldIndex(field)); } //Get data directly from Values[List] according to the subscript public Object getValue(int i) { return values.get(i); } //....... }
task context
public class GeneralTopologyContext implements JSONAware { private StormTopology _topology; private Map<Integer, String> _taskToComponent; private Map<String, List<Integer>> _componentToTasks; private Map<String, Map<String, Fields>> _componentToStreamToFields; private String _stormId; protected Map _stormConf; // pass in componentToSortedTasks for the case of running tons of tasks in single executor public GeneralTopologyContext(StormTopology topology, Map stormConf, Map<Integer, String> taskToComponent, Map<String, List<Integer>> componentToSortedTasks, Map<String, Map<String, Fields>> componentToStreamToFields, String stormId) { _topology = topology; _stormConf = stormConf; _taskToComponent = taskToComponent; _stormId = stormId; _componentToTasks = componentToSortedTasks; _componentToStreamToFields = componentToStreamToFields; } /** * Gets the declared output fields for the specified component/stream. */ public Fields getComponentOutputFields(String componentId, String streamId) { Fields ret = _componentToStreamToFields.get(componentId).get(streamId); if(ret==null) { throw new IllegalArgumentException("No output fields defined for component:stream " + componentId + ":" + streamId); } return ret; } //...... }