diff --git a/conf/backendURLs.json b/conf/backendURLs.json index c6a1e839..8ce651b1 100644 --- a/conf/backendURLs.json +++ b/conf/backendURLs.json @@ -1,9 +1,9 @@ [ - [ - "http://yodaqa.felk.cvut.cz/fuseki-dbp/dbpedia/query", - "http://yodaqa.felk.cvut.cz/fuseki-fb/freebase/query", - "http://yodaqa.felk.cvut.cz/dbp-labels1", - "http://yodaqa.felk.cvut.cz/dbp-labels2", - "http://yodaqa.felk.cvut.cz/apache/solr/" - ] -] + { + "cz.brmlab.yodaqa.dbpediaurl": "http://yodaqa.felk.cvut.cz/fuseki-dbp/dbpedia/query", + "cz.brmlab.yodaqa.freebaseurl": "http://yodaqa.felk.cvut.cz/fuseki-fb/freebase/query", + "cz.brmlab.yodaqa.dbpedialabelurl": "http://yodaqa.felk.cvut.cz/dbp-labels1", + "cz.brmlab.yodaqa.dictionarylabelurl": "http://yodaqa.felk.cvut.cz/dbp-labels2", + "cz.brmlab.yodaqa.solrurl": "http://yodaqa.felk.cvut.cz/apache/solr/" + } +] \ No newline at end of file diff --git a/src/main/java/cz/brmlab/yodaqa/io/web/WebInterface.java b/src/main/java/cz/brmlab/yodaqa/io/web/WebInterface.java index 6da493e7..48d8709d 100644 --- a/src/main/java/cz/brmlab/yodaqa/io/web/WebInterface.java +++ b/src/main/java/cz/brmlab/yodaqa/io/web/WebInterface.java @@ -11,14 +11,12 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Random; -import cz.brmlab.yodaqa.provider.UrlManager; +import cz.brmlab.yodaqa.provider.url.UrlManager; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import spark.QueryParamsMap; import spark.Request; import spark.Response; import spark.Route; @@ -142,7 +140,7 @@ public Object handle(Request request, Response response) { public Object handle(Request request, Response response) { response.type("application/json"); response.header("Access-Control-Allow-Origin", "*"); - return UrlManager.printState(); + return UrlManager.getInstance().printState(); } }); diff --git a/src/main/java/cz/brmlab/yodaqa/pipeline/YodaQA.java b/src/main/java/cz/brmlab/yodaqa/pipeline/YodaQA.java index 14958a9a..e3a86aa7 100644 --- a/src/main/java/cz/brmlab/yodaqa/pipeline/YodaQA.java +++ b/src/main/java/cz/brmlab/yodaqa/pipeline/YodaQA.java @@ -1,6 +1,7 @@ package cz.brmlab.yodaqa.pipeline; -import cz.brmlab.yodaqa.provider.UrlManager; +import cz.brmlab.yodaqa.provider.url.UrlConstants; +import cz.brmlab.yodaqa.provider.url.UrlManager; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.fit.factory.AggregateBuilder; @@ -20,7 +21,6 @@ import cz.brmlab.yodaqa.pipeline.structured.DBpediaOntologyAnswerProducer; import cz.brmlab.yodaqa.pipeline.structured.DBpediaPropertyAnswerProducer; import cz.brmlab.yodaqa.pipeline.structured.FreebaseOntologyAnswerProducer; -import cz.brmlab.yodaqa.pipeline.AnswerHitlistSerialize; import cz.brmlab.yodaqa.provider.IPv6Check; import cz.brmlab.yodaqa.provider.solr.SolrNamedSource; @@ -56,7 +56,7 @@ public class YodaQA /* XXX: extends AggregateBuilder ? */ { //SolrNamedSource.register("guten", "data/guten", null); //SolrNamedSource.register("enwiki", "collection1", "http://127.0.0.1:8983/solr/"); - SolrNamedSource.register("enwiki", "collection1", UrlManager.lookUpUrl(UrlManager.DataBackends.SOLR.ordinal())); + SolrNamedSource.register("enwiki", "collection1", UrlManager.getInstance().getUrl(UrlConstants.SOLR)); } catch (Exception e) { e.printStackTrace(); System.err.println("*** Exception caught during SolrNamedSource initialization. ***"); diff --git a/src/main/java/cz/brmlab/yodaqa/provider/UrlManager.java b/src/main/java/cz/brmlab/yodaqa/provider/UrlManager.java deleted file mode 100644 index f8a83f37..00000000 --- a/src/main/java/cz/brmlab/yodaqa/provider/UrlManager.java +++ /dev/null @@ -1,208 +0,0 @@ -package cz.brmlab.yodaqa.provider; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParseException; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; - -/** - * Provider of various API URLs we depend on. This offers a single place - * for managing the endpoints used, and overriding them with your local - * deployments. - * - * In theory, we support multiple backend sets, but offer no UI to switch - * between these yet. (TODO) - * - * TODO: Change the config file JSON to use a dict map rather than array - * of URLs, use strings (static public String attributes) to refer to - * DataBackends rather than enum so that we can prettify the property - * access code. TODO rename "label1", "label2". - */ -public class UrlManager { - - static { - updateUrlTable(); - } - - public enum DataBackends { - DBPEDIA, FREEBASE, LABEL1, LABEL2, SOLR - } - - private static String[][] urlLookUpTable; - - public static String[][] getUrlLookUpTable() { - return urlLookUpTable; - } - public static void setUrlLookUpTable(String[][] newLookUpTable) { - urlLookUpTable = newLookUpTable; - } - - private static int currentBackend = 0; //Default is 0: ailao.eu, 1: loopback, different if custom tables loaded - public static int getCurrentBackend() { - return currentBackend; - } - public static boolean setCurrentBackend(int currentBackend) { - if (currentBackend < urlLookUpTable.length) { - UrlManager.currentBackend = currentBackend; - return true; - } else { - return false; - } - } - - public static String printState() { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("Currently selected backend: "); - stringBuilder.append(Integer.toString(currentBackend)); - stringBuilder.append("\n\nCurrent Lookup Table:\n"); - for (int i=0; i backends = gson.fromJson(jsonObject.get("offline"), new TypeToken>(){}.getType()); - //JsonParser jsonParser = new JsonParser(); - //JsonElement jsonElement = jsonParser.parse(jsonString); - // JsonArray jsonArray = jsonElement.isJsonArray()?jsonElement.getAsJsonArray():null; - - // ...but we can load it directly - return gson.fromJson(jsonString, String[][].class); - } - - /** - * Reads and parses configuration file - * @return Success state - */ - public static boolean updateUrlTable() { - try{ - String[][] result = parseConfiguration(readConfigurationFile()); - if (result != null) { - urlLookUpTable = result; - return true; - } - return false; - } catch (JsonParseException jpe) { - jpe.printStackTrace(); - return false; - } - } - - /** - * Looks up entire URL set for a backend (DBpedia, Freebase, Label Service 1, Label Service 2 - * and then Solr/enwiki) - * @param id Backend to return all URLs for - * @return All backends in order - */ - public static String[] lookUpUrlSet(int id) { - if(urlLookUpTable != null && id\n" + "PREFIX dbpedia2: \n" + "PREFIX dbpedia: \n" + diff --git a/src/main/java/cz/brmlab/yodaqa/provider/rdf/DBpediaTitles.java b/src/main/java/cz/brmlab/yodaqa/provider/rdf/DBpediaTitles.java index 87625799..998e3424 100644 --- a/src/main/java/cz/brmlab/yodaqa/provider/rdf/DBpediaTitles.java +++ b/src/main/java/cz/brmlab/yodaqa/provider/rdf/DBpediaTitles.java @@ -18,7 +18,8 @@ import com.google.gson.Gson; import com.hp.hpl.jena.rdf.model.Literal; -import cz.brmlab.yodaqa.provider.UrlManager; +import cz.brmlab.yodaqa.provider.url.UrlConstants; +import cz.brmlab.yodaqa.provider.url.UrlManager; import org.slf4j.Logger; /** A wrapper around DBpedia "Titles" dataset that maps titles to @@ -31,8 +32,8 @@ * and disambiguation pages. */ public class DBpediaTitles extends DBpediaLookup { - protected static final String fuzzyLookupUrl = UrlManager.lookUpUrl(UrlManager.DataBackends.LABEL1.ordinal()); - protected static final String crossWikiLookupUrl = UrlManager.lookUpUrl(UrlManager.DataBackends.LABEL2.ordinal()); + protected static final String fuzzyLookupUrl = UrlManager.getInstance().getUrl(UrlConstants.DBPEDIA_LABEL); + protected static final String crossWikiLookupUrl = UrlManager.getInstance().getUrl(UrlConstants.DICTIONARY_LABEL); /** A container of enwiki article metadata. * This must 1:1 map to label-lookup API. */ diff --git a/src/main/java/cz/brmlab/yodaqa/provider/rdf/FreebaseLookup.java b/src/main/java/cz/brmlab/yodaqa/provider/rdf/FreebaseLookup.java index b0d48946..299e46c1 100644 --- a/src/main/java/cz/brmlab/yodaqa/provider/rdf/FreebaseLookup.java +++ b/src/main/java/cz/brmlab/yodaqa/provider/rdf/FreebaseLookup.java @@ -1,12 +1,13 @@ package cz.brmlab.yodaqa.provider.rdf; -import cz.brmlab.yodaqa.provider.UrlManager; +import cz.brmlab.yodaqa.provider.url.UrlConstants; +import cz.brmlab.yodaqa.provider.url.UrlManager; /** This is an abstract base class for accessing Freebase. */ public abstract class FreebaseLookup extends CachedJenaLookup { public FreebaseLookup() { - super(UrlManager.lookUpUrl(UrlManager.DataBackends.FREEBASE.ordinal()), + super(UrlManager.getInstance().getUrl(UrlConstants.FREEBASE), "PREFIX ns: \n" + ""); } diff --git a/src/main/java/cz/brmlab/yodaqa/provider/url/BackendUrlGroup.java b/src/main/java/cz/brmlab/yodaqa/provider/url/BackendUrlGroup.java new file mode 100644 index 00000000..b069dcce --- /dev/null +++ b/src/main/java/cz/brmlab/yodaqa/provider/url/BackendUrlGroup.java @@ -0,0 +1,12 @@ +package cz.brmlab.yodaqa.provider.url; + +import java.util.HashMap; + +/** + * Created by bzhao on 12/21/16. + */ +public class BackendUrlGroup extends HashMap { + public String getUrl(String urlkey) { + return this.get(urlkey); + } +} diff --git a/src/main/java/cz/brmlab/yodaqa/provider/url/UrlConstants.java b/src/main/java/cz/brmlab/yodaqa/provider/url/UrlConstants.java new file mode 100644 index 00000000..4546216e --- /dev/null +++ b/src/main/java/cz/brmlab/yodaqa/provider/url/UrlConstants.java @@ -0,0 +1,16 @@ +package cz.brmlab.yodaqa.provider.url; + +/** + * Created by bzhao on 12/23/16. + * URL related constants, these are used as: + * - keys in the json dict map of backendUrls.conf + * - system property overrides from CLI, + * eg: -Dcz.brmlab.yodaqa.dbpediaurl=http://yodaqa.felk.cvut.cz/fuseki-dbp/dbpedia/query + */ +public class UrlConstants { + public final static String DBPEDIA = "cz.brmlab.yodaqa.dbpediaurl"; + public final static String FREEBASE = "cz.brmlab.yodaqa.freebaseurl"; + public final static String DBPEDIA_LABEL = "cz.brmlab.yodaqa.dbpedialabelurl"; + public final static String DICTIONARY_LABEL = "cz.brmlab.yodaqa.dictionarylabelurl"; + public final static String SOLR = "cz.brmlab.yodaqa.solrurl"; +} diff --git a/src/main/java/cz/brmlab/yodaqa/provider/url/UrlManager.java b/src/main/java/cz/brmlab/yodaqa/provider/url/UrlManager.java new file mode 100644 index 00000000..f2d8f0ee --- /dev/null +++ b/src/main/java/cz/brmlab/yodaqa/provider/url/UrlManager.java @@ -0,0 +1,183 @@ +package cz.brmlab.yodaqa.provider.url; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; +import com.google.gson.reflect.TypeToken; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.List; + +/** + * Provider of various API URLs we depend on. This offers a single place + * for managing the endpoints used, and overriding them with your local + * deployments. + *

+ * In theory, we support multiple backend sets, but offer no UI to switch + * between these yet. (TODO) + *

+ */ +public class UrlManager { + private static UrlManager instance = null; + + public static UrlManager getInstance() { + if (instance == null) { + instance = new UrlManager(); + return instance; + } else { + return instance; + } + } + + private List urlLookUpTable; + private BackendUrlGroup currentBackend; + + private UrlManager() { + updateUrlTable(); + setCurrentBackend(0); //Default is 0: ailao.eu, 1: loopback, different if custom tables loaded + } + + public List getUrlLookUpTable() { + return urlLookUpTable; + } + + public void setUrlLookUpTable(List newLookUpTable) { + urlLookUpTable = newLookUpTable; + } + + public BackendUrlGroup getCurrentBackend() { + return currentBackend; + } + + public boolean setCurrentBackend(int currentBackendIndex) { + if (currentBackendIndex < urlLookUpTable.size()) { + currentBackend = urlLookUpTable.get(currentBackendIndex); + return true; + } else { + return false; + } + } + + public String printState() { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("Currently selected backend: "); + stringBuilder.append(urlLookUpTable.indexOf(currentBackend)); + stringBuilder.append("\n\nCurrent Lookup Table:\n"); + stringBuilder.append(currentBackend.toString()); + stringBuilder.append("\nCurrent properties:"); + stringBuilder.append("System.getProperty(\"cz.brmlab.yodaqa.dbpediaurl\") "); + stringBuilder.append(System.getProperty("cz.brmlab.yodaqa.dbpediaurl")); + stringBuilder.append("\nSystem.getProperty(\"cz.brmlab.yodaqa.freebaseurl\") "); + stringBuilder.append(System.getProperty("cz.brmlab.yodaqa.freebaseurl")); + stringBuilder.append("\nSystem.getProperty(\"cz.brmlab.yodaqa.label1url\") "); + stringBuilder.append(System.getProperty("cz.brmlab.yodaqa.label1url")); + stringBuilder.append("\nSystem.getProperty(\"cz.brmlab.yodaqa.label2url\") "); + stringBuilder.append(System.getProperty("cz.brmlab.yodaqa.label2url")); + stringBuilder.append("\nSystem.getProperty(\"cz.brmlab.yodaqa.solrurl\") "); + stringBuilder.append(System.getProperty("cz.brmlab.yodaqa.solrurl")); + stringBuilder.append("\n\nURL each backend receives:"); + stringBuilder.append("\nDBpedia: "); + stringBuilder.append(currentBackend.getUrl(UrlConstants.DBPEDIA)); + stringBuilder.append("\nFreebase: "); + stringBuilder.append(currentBackend.getUrl(UrlConstants.FREEBASE)); + stringBuilder.append("\nDBPedia Label Service: "); + stringBuilder.append(currentBackend.getUrl(UrlConstants.DBPEDIA_LABEL)); + stringBuilder.append("\nDictionary Wiki Label Service: "); + stringBuilder.append(currentBackend.getUrl(UrlConstants.DICTIONARY_LABEL)); + stringBuilder.append("\nSolr: "); + stringBuilder.append(currentBackend.getUrl(UrlConstants.SOLR)); + return stringBuilder.toString(); + } + + + /** + * Reads configuration file + * + * @return Raw content of configuration file (should be JSON) + */ + private String readConfigurationFile() { + StringBuilder configurationJson = new StringBuilder(); + try (BufferedReader bufferedReader = new BufferedReader(new FileReader("conf/backendURLs.json"))) { + String currentLine; + while ((currentLine = bufferedReader.readLine()) != null) { + configurationJson.append(currentLine); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + return configurationJson.toString(); + } + + /** + * Parses configuration to two-dimensional String array, where each subarray contains + * DBpedia, Freebase, Label Service 1, Label Service 2, Solr/enwiki + * + * @return Two-dimensional array with URLs + */ + private List parseConfiguration(String jsonString) { + + Gson gson = new GsonBuilder().create(); + + // Could get it as list or proceed manually... + // List backends = gson.fromJson(jsonObject.get("offline"), new TypeToken>(){}.getType()); + //JsonParser jsonParser = new JsonParser(); + //JsonElement jsonElement = jsonParser.parse(jsonString); + // JsonArray jsonArray = jsonElement.isJsonArray()?jsonElement.getAsJsonArray():null; + + // ...but we can load it directly + Type type = new TypeToken>() { + }.getType(); + return gson.fromJson(jsonString, type); + } + + /** + * Reads and parses configuration file + * + * @return Success state + */ + private boolean updateUrlTable() { + try { + List result = parseConfiguration(readConfigurationFile()); + if (result != null) { + urlLookUpTable = result; + return true; + } + return false; + } catch (JsonParseException jpe) { + jpe.printStackTrace(); + return false; + } + } + + /** + * Looks up entire URL set for a backend (DBpedia, Freebase, Label Service 1, Label Service 2 + * and then Solr/enwiki) + * + * @param id Backend to return all URLs for + * @return All backends in order + */ + public BackendUrlGroup lookUpUrlGroup(int id) { + if (urlLookUpTable != null && id < urlLookUpTable.size()) { + return urlLookUpTable.get(id); + } + return null; + } + + /** + * Looks up particular URL in current backend, used by cz.brmlab.yodaqa.provider.rdf.FreebaseLookup, + * cz.brmlab.yodaqa.provider.rdf.DBpediaTitles.java cz.brmlab.yodaqa.provider.rdf.DBpediaLookup and + * cz.brmlab.yodaqa.pipeline.YodaQA + * + * @param urlkey: the UrlConstants constant string that maps to a system property or dict map key + * in the config file + * @return URL for that particular backend + */ + public String getUrl(String urlkey) { + String overridingUrl = System.getProperty(urlkey); + return overridingUrl == null ? currentBackend.getUrl(urlkey) : overridingUrl; + } + +}