package com.heb.storm.risk;
import static backtype.storm.utils.Utils.tuple;
import java.util.HashMap;
import java.util.Map;
import org.mortbay.log.Log;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.BasicOutputCollector;
import backtype.storm.topology.IBasicBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import com.heb.finance.analytics.model.RiskSensitivity;
import com.heb.storm.risk.cql.CassandraCqlBolt;
@SuppressWarnings("serial")
public class RiskNameAggregator implements IBasicBolt {
// String will contain <hier, map<<sens, double>>>
private Map<String, Map<String, Double>> aggregatesByRiskType;
private long count = 0;
@SuppressWarnings("rawtypes")
public void prepare(Map stormConf, TopologyContext context) {
this.aggregatesByRiskType = new HashMap<String, Map<String, Double>>();
}
public void execute(Tuple input, BasicOutputCollector collector) {
RiskSensitivity riskSensitivity = (RiskSensitivity) input.getValues().get(0);
if (++count % 1000 == 0) {
Log.info("Processed " + count);
}
String hier = riskSensitivity.getPath();
String subHier = riskSensitivity.getName();
//Populate the maps
addHierValue(riskSensitivity, hier);
// First process the new value
collector.emit(tuple(CassandraCqlBolt.AGGREGATE, hier, riskSensitivity.getName(), riskSensitivity.getValue().doubleValue()));
// Process all levels of the hierarchy
while (hier.contains(RiskSensitivity.SEPARATOR)) {
subHier = hier.substring(hier.lastIndexOf(RiskSensitivity.SEPARATOR) + 1);
hier = hier.substring(0, hier.lastIndexOf(RiskSensitivity.SEPARATOR));
double aggregate = addHierValue(riskSensitivity, hier);
collector.emit(tuple(CassandraCqlBolt.AGGREGATE, hier, riskSensitivity.getName(), aggregate));
}
}
private double addHierValue(RiskSensitivity riskSensitivity, String hier) {
double aggregate = 0;
Map<String, Map<String, Double>> subHierMap;
Map<String, Double> riskSensitivities;
// Check for the hierarchy path
if (this.aggregatesByRiskType.containsKey(hier)) {
riskSensitivities = aggregatesByRiskType.get(hier);
// Check for the name
if (riskSensitivities.containsKey(riskSensitivity.getName())) {
Double originalValue = riskSensitivities.get(riskSensitivity.getName());
aggregate = riskSensitivity.getValue().doubleValue() + originalValue.doubleValue();
riskSensitivities.put(riskSensitivity.getName(), aggregate);
} else {
riskSensitivities.put(riskSensitivity.getName(), riskSensitivity.getValue().doubleValue());
}
} else {
// Create new maps to hold values
riskSensitivities = new HashMap<String, Double>();
aggregate = riskSensitivity.getValue().doubleValue();
riskSensitivities.put(riskSensitivity.getName(), aggregate);
this.aggregatesByRiskType.put(hier, riskSensitivities);
}
return aggregate;
}
public void cleanup() {
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("Type", "hierarchy_path", "risk_sensitivity", "aggregate"));
}
@Override
public Map<String, Object> getComponentConfiguration() {
return null;
}
}