/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string sentence = tuple.GetString(0); foreach (string word in sentence.Split(' ')) { Context.Logger.Info("Emit: {0}", word); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple> { tuple }, new Values(word, word[0])); } if (enableAck) { if (Sample(50)) // this is to demo how to fail tuple. We do it randomly { Context.Logger.Info("fail tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Fail(tuple); } else { if (Sample(50)) // this is to simulate timeout { Context.Logger.Info("sleep {0} seconds", msgTimeoutSecs+1); Thread.Sleep((msgTimeoutSecs + 1) * 1000); } Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } } Context.Logger.Info("Execute exit"); }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string word = tuple.GetString(0); int count = counts.ContainsKey(word) ? counts[word] : 0; count++; counts[word] = count; Context.Logger.Info("Emit: {0}, count: {1}", word, count); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple> { tuple }, new Values(word, count)); if (enableAck) { Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } // log some info to out file for bvt test validataion if (taskIndex == 0) // For component with multiple parallism, only one of them need to log info { string fileName = @"..\..\..\..\..\HelloWorldOutput" + Process.GetCurrentProcess().Id + ".txt"; FileStream fs = new FileStream(fileName, FileMode.Append); using (StreamWriter writer = new StreamWriter(fs)) { writer.WriteLine("word: {0}, count: {1}", word, count); } } Context.Logger.Info("Execute exit"); }
public void Execute(SCPTuple tuple) { try { //TODO: Insert or Upsert or Delete depending on your logic //Delete(new List<int>() { 1, 2 }, tuple.GetValues()); //Upsert(new List<int>() { 1, 2 }, tuple.GetValues()); Insert(tuple.GetValues()); //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); if (Constants.SYSTEM_TICK_STREAM_ID.Equals(tuple.GetSourceStreamId())) { long data = tuple.GetLong(0); Context.Logger.Info("tick tuple, value: {0}", data); } else { byte[] data = tuple.GetBinary(0); int bytesNum = data.Count(); if (enableAck) { this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple> { tuple }, new Values(bytesNum)); this.ctx.Ack(tuple); Context.Logger.Info("emit bytesNum: {0}", bytesNum); Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); } else { this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new Values(bytesNum)); Context.Logger.Info("emit bytesNum: {0}", bytesNum); } } Context.Logger.Info("Execute exit"); }
public void Execute(SCPTuple tuple) { try { // TwitterFeed tweet = tuple.GetValue(0) as TwitterFeed; TwitterFeed tweet = tuple.GetValue(0) as TwitterFeed; if (tweet != null) { Context.Logger.Info("SQL AZURE: Id:" + tweet.Id.ToString()); Context.Logger.Info("SQL AZURE: Text:" + tweet.Text.ToString()); Context.Logger.Info("SQL AZURE: RetweetCount:" + tweet.RetweetCount.ToString()); Context.Logger.Info("SQL AZURE: FavoriteCount:" + tweet.FavoriteCount.ToString()); Context.Logger.Info("SQL AZURE: Score:" + tweet.Score.ToString()); Context.Logger.Info("SQL AZURE: Created Date:" + tweet.Createddate.ToString()); Context.Logger.Info("SQL AZURE: DateTime.UtcNow:" + DateTime.UtcNow.ToString()); } List <object> rowValue = new List <object>(); rowValue.Add(tweet.Id); rowValue.Add(tweet.Text); rowValue.Add(tweet.RetweetCount); rowValue.Add(tweet.FavoriteCount); rowValue.Add(tweet.Score); rowValue.Add(GetSentimentType(tweet.Text)); rowValue.Add(tweet.Createddate); rowValue.Add(DateTime.UtcNow); //Upsert(new List<int> { 1 }, rowValue); Insert(rowValue); } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); } }
/// <summary> /// The Execute() function will be called, when a new tuple is available. /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); string word = tuple.GetString(0); int count = counts.ContainsKey(word) ? counts[word] : 0; count++; counts[word] = count; Context.Logger.Info("Emit: {0}, count: {1}", word, count); this.ctx.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple> { tuple }, new Values(word, count)); if (enableAck) { Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } // log some info to out file for bvt test validataion if (taskIndex == 0) // For component with multiple parallism, only one of them need to log info { string fileName = @"..\..\..\..\..\HelloWorldOutput" + Process.GetCurrentProcess().Id + ".txt"; FileStream fs = new FileStream(fileName, FileMode.Append); using (StreamWriter writer = new StreamWriter(fs)) { writer.WriteLine("word: {0}, count: {1}", word, count); } } Context.Logger.Info("Execute exit"); }
/// <summary> /// Executes incoming tuples /// </summary> /// <param name="tuple">The first field is treated as rowkey and rest as column values</param> public void Execute(SCPTuple tuple) { try { var isTickTuple = tuple.GetSourceStreamId().Equals(Constants.SYSTEM_TICK_STREAM_ID); //Only add to cache if its not a Tick tuple if (!isTickTuple) { //seqId helps in keeping the incoming tuples in order of their arrival cachedTuples.Add(seqId, tuple); seqId++; } //TODO: You can choose to write into HBase based on cached tuples count or when the tick tuple arrives //To use Tick tuples make sure that you configure topology.tick.tuple.freq.secs on the bolt and also add the stream in the input streams /* Add this section to your SetBolt in TopologyBuilder to trigger Tick tuples * addConfigurations(new Dictionary<string, string>() * { * {"topology.tick.tuple.freq.secs", "5"} * }) */ //For this example, just emit on every tuple //since we will be randomly generating end tuples only every few minutes. if (cachedTuples.Count >= 1 || isTickTuple) { WriteToHBase(); //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { //Ack all the tuples in the batch foreach (var cachedTuple in cachedTuples) { this.context.Ack(cachedTuple.Value); } } cachedTuples.Clear(); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Is ack enabled? if (enableAck) { Context.Logger.Error("Failing the entire current batch"); //Fail all the tuples in the batch foreach (var cachedTuple in cachedTuples) { this.context.Fail(cachedTuple.Value); } } } }
public void Execute(SCPTuple tuple) { var isTickTuple = tuple.GetSourceStreamId().Equals(Constants.SYSTEM_TICK_STREAM_ID); if (isTickTuple) { // Get top 10 higest score tweets from last time window Context.Logger.Debug($"Total tweets in window: {tweetCache.Count}"); var topNTweets = tweetCache.OrderByDescending(o => o.Score).Take(Math.Min(10, tweetCache.Count)).ToList(); // Emit it to TopNTweet Stream foreach (var tweet in topNTweets) { //this.context.Emit(StormConstants.TOPNTWEETS_STREAM, new Values(tweet.Text, tweet.Id, tweet.RetweetCount, tweet.FavoriteCount, tweet.UserFollowerCount, tweet.Score)); this.context.Emit("TOPNTWEETS_STREAM", new Values(tweet)); } // Remove all existing data and wait for new one tweetCache.Clear(); } else { try { // Process tuple and then acknowledge it SerializableTweet tweet = tuple.GetValue(0) as SerializableTweet; if (!tweetCache.Any(o => o.Id.Equals(tweet.Id))) { tweetCache.Add(tweet); } Context.Logger.Info(tweet.ToString()); if (enableAck) { this.context.Ack(tuple); Context.Logger.Info("Total Ack: " + ++totalAck); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } } }
public void Execute(SCPTuple tuple) { Context.Logger.Info("Execute enter"); int bytesNum = tuple.GetInteger(0); totalNum += bytesNum; Context.Logger.Info("bytesNum: {0}, totalNum: {1}", bytesNum, totalNum); if (enableAck) { Context.Logger.Info("Ack tuple: tupleId: {0}", tuple.GetTupleId()); this.ctx.Ack(tuple); } Context.Logger.Info("Execute exit"); }
public void Execute(SCPTuple tuple) { var isTickTuple = tuple.GetSourceStreamId().Equals(Constants.SYSTEM_TICK_STREAM_ID); if (isTickTuple) { // Get top 10 higest forwards + retweets count from last time window of 5 seconds Context.Logger.Debug($"Total tweets in window: {tweetCache.Count}"); var topNTweets = tweetCache.OrderByDescending(o => o.Score).Take(Math.Min(10, tweetCache.Count)).ToList(); foreach (var tweet in topNTweets) { this.context.Emit("TWEETRANK_STREAM", new Values(tweet)); } tweetCache.Clear(); } else { try { TwitterFeed tweet = tuple.GetValue(0) as TwitterFeed; if (!tweetCache.Any(o => o.Id.Equals(tweet.Id))) { tweetCache.Add(tweet); } Context.Logger.Info(tweet.ToString()); if (enableAck) { this.context.Ack(tuple); Context.Logger.Info("Total Ack: " + ++totalAck); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); if (enableAck) { this.context.Fail(tuple); } } } }
public void Execute(SCPTuple tuple) { try { count++; var sb = new StringBuilder(); sb.AppendFormat("Received Tuple {0}: ", count); var values = tuple.GetValues(); for (int i = 0; i < values.Count; i++) { if (i > 0) { sb.Append(", "); } sb.AppendFormat("{0} = {1}", i, values[i].ToString()); } Context.Logger.Info(sb.ToString()); Context.Logger.Info("Tuple values as JSON: " + (values.Count == 1 ? JsonConvert.SerializeObject(values[0]) : JsonConvert.SerializeObject(values))); //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
public void Execute(SCPTuple tuple) { try { if (hubConnection.State != ConnectionState.Connected) { hubConnection.Stop(); StartSignalRHubConnection(); } var values = tuple.GetValues(); hubProxy.Invoke(this.SignalRMethod, values); //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
/// <summary> /// The execute method for incoming tuples /// </summary> /// <param name="tuple">The incoming tuple</param> public void Execute(SCPTuple tuple) { try { //Assuming that the first field of the incoming tuple has the lookup value you are interested in var value = tuple.GetValue(0); var lookupValue = value.ToString(); IEnumerable <object> documents = null; if (value is string) { documents = this.documentClient.CreateDocumentQuery(documentCollection.DocumentsLink). Where(d => d.Id.Equals(value)).AsEnumerable(); } else { Context.Logger.Info("Lookup value is not a string, getting the value for the lookup field in the object."); lookupValue = value.GetType().GetProperty(this.DocumentDbLookupField).GetValue(value).ToString(); string query = "SELECT * FROM ROOT R WHERE R[\"" + this.DocumentDbLookupField + "\"] = \"" + lookupValue + "\""; Context.Logger.Info("DocumentDb Query: {0}", query); documents = this.documentClient.CreateDocumentQuery(documentCollection.DocumentsLink, query).AsEnumerable(); } if (documents.Count() == 0) { Context.Logger.Info("No documents found for lookup field: {0}, lookup value: {1}", this.DocumentDbLookupField, lookupValue); } else { foreach (var document in documents) { //A document is just JSON so we will call a ToString() to set the emitValue as JSON string var emitValue = document.ToString(); Context.Logger.Info("Found document for lookup field: {0}, lookup value: {1}, document: {2}", this.DocumentDbLookupField, lookupValue, emitValue); if (enableAck) { //NOTE: For a Bolt with enableAck we need to emit with anchors - list of tuples //In this scenario we are emitting per tuple so the anchor is only for this tuple this.context.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple>() { tuple }, new Values(emitValue)); } else { this.context.Emit(Constants.DEFAULT_STREAM_ID, new Values(emitValue)); } } } //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
/// <summary> /// Executes incoming tuples /// </summary> /// <param name="tuple">The first field is treated as rowkey and rest as column names</param> public void Execute(SCPTuple tuple) { try { //TODO: Change the HBase scanning criteria as per your needs //filter = new PrefixFilter(ToBytes(tuple.GetValue(0))) //Or, use a different field for end scan like: endRow = ToBytes(tuple.GetValue(1)) var scannersettings = new Scanner() { startRow = ToBytes(tuple.GetValue(0)), endRow = ToBytes(tuple.GetValue(0)), }; var scannerInfo = HBaseClusterClient.CreateScanner(this.HBaseTableName, scannersettings); CellSet readSet = null; while ((readSet = HBaseClusterClient.ScannerGetNext(scannerInfo)) != null) { Context.Logger.Info("Rows found: {0}", readSet.rows.Count); foreach (var row in readSet.rows) { var emitValues = new List <object>(); //TODO: You can choose to emit the row key along with the values emitValues.Add(Encoding.UTF8.GetString(row.key)); //Add the values from the readSet //TODO: The byte[] from HBase can be any type, make sure you type cast it correctly before emitting //The code below only handles strings emitValues.AddRange(row.values.Select(v => Encoding.UTF8.GetString(v.data))); Context.Logger.Info("Rowkey: {0}, Values: {1}", Encoding.UTF8.GetString(row.key), String.Join(", ", row.values.Select(v => Encoding.UTF8.GetString(v.data)))); if (enableAck) { this.context.Emit(Constants.DEFAULT_STREAM_ID, new List <SCPTuple>() { tuple }, emitValues); } else { this.context.Emit(Constants.DEFAULT_STREAM_ID, emitValues); } } } //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
/// <summary> /// The execute method for tuple received /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { try { var task = eventHubSender.SendAsync(new EventData(Encoding.UTF8.GetBytes(tuple.GetString(0)))); if (ackEnabled) { tasks.Add(task); this.context.Ack(tuple); if (tasks.Count >= 100) { Context.Logger.Info("Total tasks in waiting = {0}", tasks.Count); Task.WaitAll(tasks.ToArray()); tasks.Clear(); Context.Logger.Info("All waiting tasks completed successfully!", tasks.Count); } } global_emit_count++; if (global_emit_count % 5000 == 0) { Context.Logger.Info("Total events sent to EventHub = {0} ({1} events/sec)", global_emit_count, global_emit_count / globalStopwatch.Elapsed.TotalSeconds); } } catch (Exception ex) { Context.Logger.Error("Failed to send tuples. Last Id = {0}, Value = {1}. Tasks = {2}", tuple.GetTupleId(), tuple.GetString(0), tasks.Count); Context.Logger.Error("Error Details: {0}", ex.ToString()); if (ackEnabled) { this.context.Fail(tuple); } global_error_count++; if (global_error_count > 10) { Context.Logger.Error("High error count: {0}", global_error_count); throw; } } }
/// <summary> /// The execute method for tuple received /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { try { var task = eventHubSender.SendAsync(new EventData(Encoding.UTF8.GetBytes(tuple.GetString(0)))); if (ackEnabled) { tasks.Add(task); this.context.Ack(tuple); if (tasks.Count >= 100) { Context.Logger.Info("Total tasks in waiting = {0}", tasks.Count); Task.WaitAll(tasks.ToArray()); tasks.Clear(); Context.Logger.Info("All waiting tasks completed successfully!", tasks.Count); } } global_emit_count++; if (global_emit_count % 5000 == 0) { Context.Logger.Info("Total events sent to EventHub = {0} ({1} events/sec)", global_emit_count, global_emit_count / globalStopwatch.Elapsed.TotalSeconds); } } catch (Exception ex) { Context.Logger.Error("Failed to send tuples. Last Id = {0}, Value = {1}. Tasks = {2}", tuple.GetTupleId(), tuple.GetString(0), tasks.Count); Context.Logger.Error("Error Details: {0}", ex.ToString()); if (ackEnabled) { this.context.Fail(tuple); } global_error_count++; if (global_error_count > 10) { Context.Logger.Error("High error count: {0}", global_error_count); throw; } if (eventHubSender.IsClosed) { Context.Logger.Warn("EventHubSender is closed, re-intializing..."); InitializeEventHub(); } } }
/// <summary> /// The execute method for incoming tuples /// </summary> /// <param name="tuple">The incoming tuple</param> public void Execute(SCPTuple tuple) { try { var values = tuple.GetValues(); foreach (var value in values) { Context.Logger.Info("Creating document: {0} with value: {1}", value, JsonConvert.SerializeObject(value)); var task = documentClient.CreateDocumentAsync(documentCollection.DocumentsLink, value); task.Wait(); Context.Logger.Info("Document creation result status: {0}", task.Result.StatusCode); } //Ack the tuple if enableAck is set to true in TopologyBuilder. //This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
/// <summary> /// The execute method for incoming tuples /// </summary> /// <param name="tuple">The incoming tuple</param> public void Execute(SCPTuple tuple) { try { //Assuming that the first field of the incoming tuple has the lookup value you are interested in var value = tuple.GetValue(0); var lookupValue = value.ToString(); IEnumerable<object> documents = null; if (value is string) { documents = this.documentClient.CreateDocumentQuery(documentCollection.DocumentsLink). Where(d => d.Id.Equals(value)).AsEnumerable(); } else { Context.Logger.Info("Lookup value is not a string, getting the value for the lookup field in the object."); lookupValue = value.GetType().GetProperty(this.DocumentDbLookupField).GetValue(value).ToString(); string query = "SELECT * FROM ROOT R WHERE R[\"" + this.DocumentDbLookupField + "\"] = \"" + lookupValue + "\""; Context.Logger.Info("DocumentDb Query: {0}", query); documents = this.documentClient.CreateDocumentQuery(documentCollection.DocumentsLink, query).AsEnumerable(); } if (documents.Count() == 0) { Context.Logger.Info("No documents found for lookup field: {0}, lookup value: {1}", this.DocumentDbLookupField, lookupValue); } else { foreach (var document in documents) { //A document is just JSON so we will call a ToString() to set the emitValue as JSON string var emitValue = document.ToString(); Context.Logger.Info("Found document for lookup field: {0}, lookup value: {1}, document: {2}", this.DocumentDbLookupField, lookupValue, emitValue); if (enableAck) { //NOTE: For a Bolt with enableAck we need to emit with anchors - list of tuples //In this scenario we are emitting per tuple so the anchor is only for this tuple this.context.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple>() { tuple }, new Values(emitValue)); } else { this.context.Emit(Constants.DEFAULT_STREAM_ID, new Values(emitValue)); } } } //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
/// <summary> /// The execute method for tuple received /// </summary> /// <param name="tuple"></param> public void Execute(SCPTuple tuple) { try { var values = tuple.GetValues(); var data = string.Empty; if (values.Count == 1) { data = JsonConvert.SerializeObject(values[0]); } else { data = JsonConvert.SerializeObject(values); } eventHubSender.Send(new EventData(Encoding.UTF8.GetBytes(data))); //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }
/// <summary> /// Executes incoming tuples /// </summary> /// <param name="tuple">The first field is treated as rowkey and rest as column values</param> public void Execute(SCPTuple tuple) { try { var isTickTuple = tuple.GetSourceStreamId().Equals(Constants.SYSTEM_TICK_STREAM_ID); //Only add to cache if its not a Tick tuple if (!isTickTuple) { //seqId helps in keeping the incoming tuples in order of their arrival cachedTuples.Add(seqId, tuple); seqId++; } //TODO: You can choose to write into HBase based on cached tuples count or when the tick tuple arrives //To use Tick tuples make sure that you configure topology.tick.tuple.freq.secs on the bolt and also add the stream in the input streams /* Add this section to your SetBolt in TopologyBuilder to trigger Tick tuples addConfigurations(new Dictionary<string, string>() { {"topology.tick.tuple.freq.secs", "5"} }) */ if (cachedTuples.Count >= 1000 || isTickTuple) { WriteToHBase(); //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { //Ack all the tuples in the batch foreach(var cachedTuple in cachedTuples) { this.context.Ack(cachedTuple.Value); } } cachedTuples.Clear(); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); if (enableAck) { Context.Logger.Error("Failing the entire current batch"); //Fail all the tuples in the batch foreach (var cachedTuple in cachedTuples) { this.context.Fail(cachedTuple.Value); } } } }
/// <summary> /// Executes incoming tuples /// </summary> /// <param name="tuple">The first field is treated as rowkey and rest as column names</param> public void Execute(SCPTuple tuple) { try { //TODO: Change the HBase scanning criteria as per your needs //filter = new PrefixFilter(ToBytes(tuple.GetValue(0))) //Or, use a different field for end scan like: endRow = ToBytes(tuple.GetValue(1)) var scannersettings = new Scanner() { startRow = ToBytes(tuple.GetValue(0)), endRow = ToBytes(tuple.GetValue(0)), }; var scannerInfo = HBaseClusterClient.CreateScanner(this.HBaseTableName, scannersettings); CellSet readSet = null; while ((readSet = HBaseClusterClient.ScannerGetNext(scannerInfo)) != null) { Context.Logger.Info("Rows found: {0}", readSet.rows.Count); foreach (var row in readSet.rows) { var emitValues = new List<object>(); //TODO: You can choose to emit the row key along with the values emitValues.Add(Encoding.UTF8.GetString(row.key)); //Add the values from the readSet //TODO: The byte[] from HBase can be any type, make sure you type cast it correctly before emitting //The code below only handles strings emitValues.AddRange(row.values.Select(v => Encoding.UTF8.GetString(v.data))); Context.Logger.Info("Rowkey: {0}, Values: {1}", Encoding.UTF8.GetString(row.key), String.Join(", ", row.values.Select(v => Encoding.UTF8.GetString(v.data)))); if (enableAck) { this.context.Emit(Constants.DEFAULT_STREAM_ID, new List<SCPTuple>() { tuple }, emitValues); } else { this.context.Emit(Constants.DEFAULT_STREAM_ID, emitValues); } } } //Ack the tuple if enableAck is set to true in TopologyBuilder. This is mandatory if the downstream bolt or spout expects an ack. if (enableAck) { this.context.Ack(tuple); } } catch (Exception ex) { Context.Logger.Error("An error occured while executing Tuple Id: {0}. Exception Details:\r\n{1}", tuple.GetTupleId(), ex.ToString()); //Fail the tuple if enableAck is set to true in TopologyBuilder so that the tuple is replayed. if (enableAck) { this.context.Fail(tuple); } } }