package storm.applications.bolt; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Queue; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; import static storm.applications.constants.MachineOutlierConstants.*; /** * Summing up all the data instance scores as the stream anomaly score. * @author yexijiang * */ public class SlidingWindowStreamAnomalyScoreBolt extends AbstractBolt { // hold the recent scores for each stream private Map<String, Queue<Double>> slidingWindowMap; private int windowLength; private long previousTimestamp; @Override public void initialize() { windowLength = config.getInt(Conf.ANOMALY_SCORER_WINDOW_LENGTH, 10); slidingWindowMap = new HashMap<>(); previousTimestamp = 0; } @Override public void execute(Tuple input) { long timestamp = input.getLongByField(Field.TIMESTAMP); String id = input.getStringByField(Field.ID); double dataInstanceAnomalyScore = input.getDoubleByField(Field.DATAINST_ANOMALY_SCORE); Queue<Double> slidingWindow = slidingWindowMap.get(id); if (slidingWindow == null) { slidingWindow = new LinkedList<>(); } // update sliding window slidingWindow.add(dataInstanceAnomalyScore); if (slidingWindow.size() > this.windowLength) { slidingWindow.poll(); } slidingWindowMap.put(id, slidingWindow); double sumScore = 0.0; for (double score : slidingWindow) { sumScore += score; } collector.emit(new Values(id, sumScore, timestamp, input.getValue(3), dataInstanceAnomalyScore)); collector.ack(input); } @Override public Fields getDefaultFields() { return new Fields(Field.ID, Field.STREAM_ANOMALY_SCORE, Field.TIMESTAMP, Field.OBSERVATION, Field.CUR_DATAINST_SCORE); } }