package stormapplied.heatmap.topology;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.BasicOutputCollector;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.topology.base.BaseBasicBolt;
import backtype.storm.tuple.Tuple;
import com.google.code.geocoder.model.LatLng;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Persistor extends BaseBasicBolt {
private final Logger logger = LoggerFactory.getLogger(Persistor.class);
private Jedis jedis;
private ObjectMapper objectMapper;
@Override
public void prepare(Map stormConf,
TopologyContext context) {
jedis = new Jedis("localhost");
objectMapper = new ObjectMapper();
}
@Override
public void execute(Tuple tuple,
BasicOutputCollector outputCollector) {
Long timeInterval = tuple.getLongByField("time-interval");
List<LatLng> hz = (List<LatLng>) tuple.getValueByField("hotzones");
List<String> hotzones = asListOfStrings(hz);
try {
String key = "checkins-" + timeInterval;
String value = objectMapper.writeValueAsString(hotzones);
jedis.set(key, value);
} catch (Exception e) {
logger.error("Error persisting for time: " + timeInterval, e);
}
}
private List<String> asListOfStrings(List<LatLng> hotzones) {
List<String> hotzonesStandard = new ArrayList<String>(hotzones.size());
for (LatLng geoCoordinate : hotzones) {
hotzonesStandard.add(geoCoordinate.toUrlValue());
}
return hotzonesStandard;
}
@Override
public void cleanup() {
if (jedis.isConnected()) {
jedis.quit();
}
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
// No output fields to be declared
}
}