package com.hadooparchitecturebook.movingavg.topology;
import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseRichSpout;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values;
import backtype.storm.utils.Utils;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
/**
* Ingest tick data and emit into our topology. This spout just reads tick data
* from a file.
*/
public class StockTicksSpout extends BaseRichSpout {
private SpoutOutputCollector outputCollector;
private List<String> ticks;
@Override
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
outputFieldsDeclarer.declare(new Fields("tick"));
}
/**
* Open file with stock tick data and read into List object.
*/
@Override
public void open(Map map,
TopologyContext context,
SpoutOutputCollector outputCollector) {
this.outputCollector = outputCollector;
try {
ticks =
IOUtils.readLines(ClassLoader.getSystemResourceAsStream(
"NASDAQ_daily_prices_A.csv"),
Charset.defaultCharset().name());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Emit each tick record in List into topology.
*/
@Override
public void nextTuple() {
for (String tick : ticks) {
// In order to ensure reliability, tuples need to be "anchored" with
// a tuple ID. In this case we're just using the tuple itself as an ID.
// In a real topology this would probably be something like a message ID.
outputCollector.emit(new Values(tick), tick);
}
}
}