package bharati.binita.storm.trident.eg7;

import storm.trident.Stream;
import storm.trident.TridentTopology;
import storm.trident.operation.builtin.Count;
import backtype.storm.Config;
import backtype.storm.StormSubmitter;
import backtype.storm.generated.AlreadyAliveException;
import backtype.storm.generated.InvalidTopologyException;
import backtype.storm.generated.StormTopology;
import backtype.storm.tuple.Fields;

 * @author [email protected]
 *  Illustrates the following:
 *  - Demo of Opaque transactional State. (Refer to Opaque transactional spout here :
 *  - State API usage, using API. This example shows use of OpaqueMap MapState type.
 *  - Persistence of State, using API. 
 *      (In Trident, State can not be called as a 'State' without effective persistence. Redis is used as for underlying storage.) 

public class ExampleTopology {
	public static StormTopology buildTopology()
		TridentTopology topology = new TridentTopology();
		RandomPhraseSpout spout1 = new RandomPhraseSpout();
		Stream inputStream = topology.newStream("dumbo", spout1);//where is dump used ? No where as per as I see.
		 * persistentAggregate : The persistentAggregate operation updates a source of state.
		 * persistentAggregate is an additional abstraction built on top of partitionPersist that knows how to take a 
		 * Trident aggregator and use it to apply updates to the source of state.
		 * Args:
		 * StateFactory instance - This factory implement the makeState API, that should return a instance of State.
		 * Fields list, that needs to be persisted. These field list should be present in the input stream.
		 * StateUpdater instance - The StateUpdater instance will update the underlying State.
		    //input stream generated by spout1 has a field called randomPhrase.
		    //RandomPhraseSplitter takes a randomPhrase and additionally emits a field called randomWord into the stream.
		    .each(new Fields("randomPhrase"), new RandomPhraseSplitter(), new Fields("randomWord"))
		    //the input stream is grouped by randomWord - Isn't this same as storm field grouping ? yes , similar.
		    .groupBy(new Fields("randomWord"))
		    //count the occurence of randomWord using Count aggregrator, that will add a field called count to the stream.
		    //persist the count in Redis.
		    .persistentAggregate(new RedisStoreStateFactory(), new Count(), new Fields("count"));

	public static void main(String[] args) throws Exception {
		Config conf = new Config();
		conf.put("redisServerIP", args[0]);
		conf.put("redisServerPort", args[1]);
		conf.put("phraseCount", "4");

		StormSubmitter.submitTopology("trident-eg7", conf,