package org.hackreduce.storm.example.riak; import backtype.storm.Config; import backtype.storm.generated.AlreadyAliveException; import backtype.storm.generated.InvalidTopologyException; import backtype.storm.spout.SchemeAsMultiScheme; import backtype.storm.tuple.Fields; import com.google.common.collect.ImmutableList; import org.hackreduce.storm.HackReduceStormSubmitter; import org.hackreduce.storm.example.common.Common; import org.hackreduce.storm.example.stock.MarketCapitalization; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import storm.kafka.StringScheme; import storm.kafka.trident.TransactionalTridentKafkaSpout; import storm.kafka.trident.TridentKafkaConfig; import storm.trident.TridentTopology; import storm.trident.operation.BaseFunction; import storm.trident.operation.CombinerAggregator; import storm.trident.operation.TridentCollector; import storm.trident.tuple.TridentTuple; import static org.hackreduce.storm.HackReduceStormSubmitter.teamPrefix; public class RiakMarketCapitalization { public static void main(String[] args) throws AlreadyAliveException, InvalidTopologyException { Config config = new Config(); // The number of processes to spin up for this job config.setNumWorkers(10); TridentKafkaConfig spoutConfig = new TridentKafkaConfig( Common.getKafkaHosts(), "stock_daily_prices" ); spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme()); // This tells the spout to start at the very beginning of the data stream // If you just want to resume where you left off, remove this line spoutConfig.forceStartOffsetTime(-2); TridentTopology builder = new TridentTopology(); builder .newStream(teamPrefix("lines"), new TransactionalTridentKafkaSpout(spoutConfig)) .parallelismHint(6) .each(new Fields("str"), new MarketCapitalization.ExtractStockData(), new Fields("exchange", "symbol", "market_cap")) .groupBy(new Fields("exchange", "symbol")) .persistentAggregate( // A nontransactional state built on Riak (Use their HTTP API to see progress) new RiakBackingMap.Factory( teamPrefix("stock-state"), // The riak 'bucket' name to store results in Common.getRiakHosts(), Common.getRiakPort(), Double.class // The type of the data to store (serialized as json) ), new Fields("market_cap"), new MarketCapitalization.MaxValue(), new Fields("max_market_cap") ) .newValuesStream() .each(new Fields("exchange", "symbol", "max_market_cap"), new MarketCapitalization.LogInput(), new Fields("never_emits")); HackReduceStormSubmitter.submitTopology("market-cap", config, builder.build()); } }