package storm.applications.spout; import backtype.storm.tuple.Values; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import storm.applications.constants.BargainIndexConstants.Conf; import storm.applications.model.finance.Quote; import storm.applications.model.finance.QuoteFetcher; import storm.applications.util.config.ClassLoaderUtils; /** * Change name to TAQ (Trade and Quotes) * @author mayconbordin <mayconbordin@gmail.com> */ public class StockPriceSpout extends AbstractSpout { private static final Logger LOG = LoggerFactory.getLogger(StockPriceSpout.class); private QuoteFetcher fetcher; protected LinkedBlockingQueue<Quote> queue; private String[] symbols; private int days; private int interval; @Override public void initialize() { days = config.getInt(Conf.SPOUT_DAYS); interval = config.getInt(Conf.SPOUT_INTERVAL); String symbolsStr = config.getString(Conf.SPOUT_SYMBOLS); symbols = symbolsStr.split(","); String fetcherClass = config.getString(Conf.SPOUT_FETCHER); fetcher = (QuoteFetcher) ClassLoaderUtils.newInstance(fetcherClass, "fetcher", LOG); queue = new LinkedBlockingQueue<>(); fetchPrices(); } private void fetchPrices() { List<Quote> quotes = new ArrayList<>(); for (String symbol : symbols) { try { String quoteStr = fetcher.fetchQuotes(symbol, days, interval); quotes.addAll(fetcher.parseQuotes(symbol, quoteStr, interval)); } catch (Exception ex) { LOG.error("Unable to fetch quotes", ex); } } Collections.sort(quotes, new Comparator<Quote>() { @Override public int compare(Quote a, Quote b) { return a.getOpenDate().compareTo(b.getOpenDate()); } }); queue.addAll(quotes); } @Override public void nextTuple() { if (queue.isEmpty()) { fetchPrices(); } Quote quote = queue.poll(); if (quote != null) { collector.emit(new Values(quote.getSymbol(), quote.getAverage(), quote.getVolume(), quote.getOpenDate(), quote.getInterval())); } } }