package storm.applications.bolt;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import java.util.*;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import storm.applications.constants.SentimentAnalysisConstants.Conf;
import storm.applications.constants.SentimentAnalysisConstants.Field;
import storm.applications.model.sentiment.SentimentClassifier;
import storm.applications.model.sentiment.SentimentClassifierFactory;
import storm.applications.model.sentiment.SentimentResult;
/**
* Breaks each tweet into words and calculates the sentiment of each tweet and associates the sentiment value to the State
* and logs the same to the console and also logs to the file.
* https://github.com/voltas/real-time-sentiment-analytic
*
* @author Saurabh Dubey <147am@gmail.com>
*/
public class CalculateSentimentBolt extends AbstractBolt {
private static final Logger LOG = LoggerFactory.getLogger(CalculateSentimentBolt.class);
private static final DateTimeFormatter datetimeFormatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss Z yyyy")
.withLocale(Locale.ENGLISH);
private SentimentClassifier classifier;
@Override
public void initialize() {
String classifierType = config.getString(Conf.CLASSIFIER_TYPE, SentimentClassifierFactory.BASIC);
classifier = SentimentClassifierFactory.create(classifierType, config);
}
@Override
public Fields getDefaultFields() {
return new Fields(Field.ID, Field.TEXT, Field.TIMESTAMP, Field.SENTIMENT, Field.SCORE);
}
@Override
public void execute(Tuple input) {
Map tweet = (Map) input.getValueByField(Field.TWEET);
if (!tweet.containsKey("id_str") || !tweet.containsKey("text") || !tweet.containsKey("created_at"))
return;
String tweetId = (String) tweet.get("id_str");
String text = (String) tweet.get("text");
DateTime timestamp = datetimeFormatter.parseDateTime((String) tweet.get("created_at"));
SentimentResult result = classifier.classify(text);
collector.emit(input, new Values(tweetId, text, timestamp, result.getSentiment().toString(), result.getScore()));
collector.ack(input);
}
}