package udacity.storm; import backtype.storm.Config; import backtype.storm.LocalCluster; import backtype.storm.StormSubmitter; import backtype.storm.task.OutputCollector; import backtype.storm.task.TopologyContext; import backtype.storm.testing.TestWordSpout; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.topology.TopologyBuilder; import backtype.storm.topology.base.BaseRichBolt; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; import backtype.storm.utils.Utils; import java.util.HashMap; import java.util.Map; //******* Import MyLikesSpout and MyNamesSpout import udacity.storm.spout.MyLikesSpout; import udacity.storm.spout.MyNamesSpout; /** * This is a basic example of a Storm topology. */ /** * This is a basic example of a storm topology. * * This topology demonstrates how to add three exclamation marks '!!!' * to each word emitted * * This is an example for Udacity Real Time Analytics Course - ud381 * */ public class ExclamationTopology { /** * A bolt that adds the exclamation marks '!!!' to word */ public static class ExclamationBolt extends BaseRichBolt { // To output tuples from this bolt to the next stage bolts, if any OutputCollector _collector; //**** ADDED // Map to store the favorites mapping private Map<String, String> favoritesMap; @Override public void prepare( Map map, TopologyContext topologyContext, OutputCollector collector) { // save the output collector for emitting tuples _collector = collector; //**** ADDED // create and initialize the map favoritesMap = new HashMap<String, String>(); } @Override public void execute(Tuple tuple) { //**** ADD COMPONENT ID String componentId = tuple.getSourceComponent(); /* * Use component id to modify behavior */ if(componentId.equals("my-likes")) { String name = tuple.getString(0); String favorite = tuple.getString(1); if (favoritesMap.get(name) == null) { // not present, add the name with favorite favoritesMap.put(name, favorite); } //Note we do not emit! } else if(componentId.equals("my-names")) { // get the column name from tuple and check if favorites exists String name = tuple.getString(0); if (favoritesMap.get(name) != null) { // name in our favorites! construct farovites sentence. String favorite = favoritesMap.get(name); StringBuilder exclamatedFavorites = new StringBuilder(); exclamatedFavorites.append(name).append("\'s favorite is ").append(favorite).append("!!!"); // emit the word with exclamations _collector.emit(new Values(exclamatedFavorites.toString())); } } else if(componentId.equals("exclaim1")) { String word = tuple.getString(0); // build the word with the exclamation marks appended StringBuilder exclamatedWord = new StringBuilder(); exclamatedWord.append(word).append("!!!"); // emit the word with exclamations _collector.emit(new Values(exclamatedWord.toString())); } //**** END COMPONENT ID } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { // tell storm the schema of the output tuple for this spout // tuple consists of a single column called 'exclamated-word' declarer.declare(new Fields("exclamated-word")); } } public static void main(String[] args) throws Exception { // create the topology TopologyBuilder builder = new TopologyBuilder(); // attach the word spout to the topology - parallelism of 10 //builder.setSpout("word", new TestWordSpout(), 10); //******** Add MyLikesSpout and MyNamesSpout builder.setSpout("my-likes", new MyLikesSpout(), 10); builder.setSpout("my-names", new MyNamesSpout(), 10); // attach the exclamation bolt to the topology - parallelism of 3 builder.setBolt("exclaim1", new ExclamationBolt(), 3) .shuffleGrouping("my-likes") .shuffleGrouping("my-names"); // attach another exclamation bolt to the topology - parallelism of 2 builder.setBolt("exclaim2", new ExclamationBolt(), 2).shuffleGrouping("exclaim1"); //******* Attach ReportBolt builder.setBolt("report-bolt", new ReportBolt(), 1).globalGrouping("exclaim2"); // create the default config object Config conf = new Config(); // set the config in debugging mode conf.setDebug(true); if (args != null && args.length > 0) { // run it in a live cluster // set the number of workers for running all spout and bolt tasks conf.setNumWorkers(3); // create the topology and submit with config StormSubmitter.submitTopology(args[0], conf, builder.createTopology()); } else { // run it in a simulated local cluster // create the local cluster instance LocalCluster cluster = new LocalCluster(); // submit the topology to the local cluster cluster.submitTopology("exclamation", conf, builder.createTopology()); // let the topology run for 30 seconds. note topologies never terminate! Thread.sleep(30000); // kill the topology cluster.killTopology("exclamation"); // we are done, so shutdown the local cluster cluster.shutdown(); } } }