package storm.applications.bolt; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import storm.applications.model.cdr.CallDetailRecord; import static storm.applications.constants.VoIPSTREAMConstants.*; /** * * @author Maycon Viana Bordin <mayconbordin@gmail.com> */ public class ACDBolt extends AbstractScoreBolt { private static final Logger LOG = LoggerFactory.getLogger(ACDBolt.class); private double avg; public ACDBolt() { super("acd"); } @Override public void execute(Tuple input) { Source src = parseComponentId(input.getSourceComponent()); if (src == Source.GACD) { avg = input.getDoubleByField(Field.AVERAGE); } else { CallDetailRecord cdr = (CallDetailRecord) input.getValueByField(Field.RECORD); String number = input.getString(0); long timestamp = input.getLong(1); double rate = input.getDouble(2); String key = String.format("%s:%d", number, timestamp); if (map.containsKey(key)) { Entry e = map.get(key); e.set(src, rate); if (e.isFull()) { // calculate the score for the ratio double ratio = (e.get(Source.CT24)/e.get(Source.ECR24))/avg; double score = score(thresholdMin, thresholdMax, ratio); LOG.debug(String.format("T1=%f; T2=%f; CT24=%f; ECR24=%f; AvgCallDur=%f; Ratio=%f; Score=%f", thresholdMin, thresholdMax, e.get(Source.CT24), e.get(Source.ECR24), avg, ratio, score)); collector.emit(new Values(number, timestamp, score, cdr)); map.remove(key); } else { LOG.warn(String.format("Inconsistent entry: source=%s; %s", input.getSourceComponent(), e.toString())); } } else { Entry e = new Entry(cdr); e.set(src, rate); map.put(key, e); } } } @Override protected Source[] getFields() { return new Source[]{Source.CT24, Source.ECR24}; } }