package edu.isi.karma.storm.bolt; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Map; import org.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import backtype.storm.task.OutputCollector; import backtype.storm.task.TopologyContext; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.topology.base.BaseRichBolt; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; import edu.isi.karma.kr2rml.writer.JSONKR2RMLRDFWriter; import edu.isi.karma.kr2rml.writer.KR2RMLRDFWriter; import edu.isi.karma.rdf.BaseKarma; import edu.isi.karma.rdf.RDFGeneratorRequest; import edu.isi.karma.storm.strategy.KarmaHomeStrategy; public class KarmaBolt extends BaseRichBolt { private static Logger LOG = LoggerFactory.getLogger(KarmaBolt.class); protected BaseKarma karma; /** * */ private static final long serialVersionUID = 1L; private OutputCollector outputCollector; @SuppressWarnings("rawtypes") private Map localConfig; private KarmaHomeStrategy karmaHomeStrategy; @SuppressWarnings("rawtypes") public KarmaBolt(Map localConfig, KarmaHomeStrategy karmaHomeStrategy) { this.localConfig = localConfig; this.karmaHomeStrategy = karmaHomeStrategy; } @Override public void execute(Tuple tuple) { long start = System.currentTimeMillis(); StringWriter sw = new StringWriter(); KR2RMLRDFWriter outWriter = configureRDFWriter(sw); try { RDFGeneratorRequest request = new RDFGeneratorRequest("model", tuple.getStringByField("id")); request.addWriter(outWriter); request.setInputData(tuple.getStringByField("text")); request.setDataType(karma.getInputType()); karma.getGenerator().generateRDF(request); String results = sw.toString(); if (!results.equals("[\n\n]\n")) { writeRDF(tuple, results); } } catch (Exception e) { LOG.error("Unable to generate RDF: " + e.getMessage()); } finally{ outputCollector.ack(tuple); } LOG.debug("id: "+ tuple.getStringByField("id") + " " + (System.currentTimeMillis() - start)); } protected KR2RMLRDFWriter configureRDFWriter(StringWriter sw) { PrintWriter pw = new PrintWriter(sw); KR2RMLRDFWriter outWriter = new JSONKR2RMLRDFWriter(pw, karma.getBaseURI()); return outWriter; } protected void writeRDF(Tuple tuple, String results) throws IOException, InterruptedException { JSONArray generatedObjects = new JSONArray(results); for(int i = 0; i < generatedObjects.length(); i++) { outputCollector.emit(tuple, new Values(generatedObjects.getJSONObject(i).getString("@id"), generatedObjects.getJSONObject(i).toString(), karma.getModel().toString() )); } } @SuppressWarnings("rawtypes") @Override public void prepare(Map globalConfig, TopologyContext arg1, OutputCollector outputCollector) { this.outputCollector = outputCollector; String karmaHomeDirectory = null; if(karmaHomeStrategy != null){ karmaHomeStrategy.prepare(globalConfig); karmaHomeDirectory = karmaHomeStrategy.getKarmaHomeDirectory(); } karma = new BaseKarma(); karma.setup(karmaHomeDirectory, (String)localConfig.get("karma.input.type"), (String)localConfig.get("model.uri"), (String)localConfig.get("model.file"), (String)localConfig.get("model.content"), (String)localConfig.get("base.uri"), (String)localConfig.get("context.uri"), (String)localConfig.get("context.content"), (String)localConfig.get("rdf.generation.root"), (String)localConfig.get("rdf.generation.selection")); } @Override public void declareOutputFields(OutputFieldsDeclarer outputFields) { outputFields.declare(new Fields("id", "json", "model")); } @Override public void cleanup() { super.cleanup(); this.karmaHomeStrategy.cleanup(); } }