/******************************************************************************* * Copyright 2012 University of Southern California * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This code was developed by the Information Integration Group as part * of the Karma project at the Information Sciences Institute of the * University of Southern California. For more information, publications, * and related projects, please see: http://www.isi.edu/integration ******************************************************************************/ package edu.isi.karma.rep.sources; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.eclipse.jetty.http.HttpMethods; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import edu.isi.karma.model.serialization.Repository; import edu.isi.karma.modeling.Test; import edu.isi.karma.util.RandomGUID; import edu.isi.karma.webserver.KarmaException; public class InvocationManager { static Logger logger = Logger.getLogger(InvocationManager.class); private List<URL> requestURLs; private List<String> idList; private List<Invocation> invocations; private Table serviceData; private String urlColumnName; private JsonArray json; private JsonArray jsonUrl; private JsonArray jsonInputs; private JsonArray jsonOutputs; private JsonArray jsonUrlAndInputs; private JsonArray jsonUrlAndOutputs; private JsonArray jsonInputsAndOutputs; public InvocationManager(String urlColumnName, List<String> idList, List<String> requestURLStrings) throws MalformedURLException, KarmaException { this.urlColumnName = (urlColumnName == null || urlColumnName.trim().length() == 0) ? "url" : urlColumnName; this.idList = idList; requestURLs = URLManager.getURLsFromStrings(requestURLStrings); if (requestURLs == null || requestURLs.size() == 0) throw new KarmaException("Cannot model a service without any request example."); this.serviceData = null; this.invocations = new ArrayList<Invocation>(); json = new JsonArray(); jsonUrl = new JsonArray(); jsonInputs = new JsonArray(); jsonOutputs = new JsonArray(); jsonUrlAndInputs = new JsonArray(); jsonUrlAndOutputs = new JsonArray(); jsonInputsAndOutputs = new JsonArray(); invokeAndGetResponse(); } public InvocationManager(String urlColumnName, String requestURLString) throws MalformedURLException, KarmaException { this.urlColumnName = (urlColumnName == null || urlColumnName.trim().length() == 0) ? "url" : urlColumnName; this.idList = new ArrayList<String>(); this.idList.add("1"); List<String> requestURLList = new ArrayList<String>(); requestURLList.add(requestURLString); requestURLs = URLManager.getURLsFromStrings(requestURLList); if (requestURLs == null || requestURLs.size() == 0) throw new KarmaException("Cannot model a service without any request example."); this.serviceData = null; this.invocations = new ArrayList<Invocation>(); json = new JsonArray(); jsonUrl = new JsonArray(); jsonInputs = new JsonArray(); jsonOutputs = new JsonArray(); jsonUrlAndInputs = new JsonArray(); jsonUrlAndOutputs = new JsonArray(); jsonInputsAndOutputs = new JsonArray(); invokeAndGetResponse(); } private void invokeAndGetResponse() { for (int i = 0; i < requestURLs.size(); i++) { URL url = requestURLs.get(i); String requestId = null; if (idList != null) requestId = idList.get(i); Request request = new Request(url); Invocation invocation = new Invocation(requestId, request); logger.info("Invoking the service " + request.getUrl().toString() + " ..."); invocation.invokeAPI(); invocations.add(invocation); } List<Table> invocationData = new ArrayList<Table>(); for (Invocation inv : this.invocations) { populateJsonArraysFromInvocation(inv); invocationData.add(inv.getJointInputAndOutput()); } logger.info("Integrating the results of all invocations ..."); Table result = Table.union(invocationData); logger.info("Integrating finished."); this.serviceData = result; } private void populateJsonArraysFromInvocation(Invocation inv) { try { JsonElement out = new JsonParser().parse(inv.getJsonResponse()); // JsonArray outArray = new JsonArray(); // outArray.add(out); this.jsonOutputs.add(out); JsonObject url = new JsonObject(); url.addProperty(this.urlColumnName, inv.getRequest().getUrl().toString()); // JsonArray urlArray = new JsonArray(); // urlArray.add(url); this.jsonUrl.add(url); JsonObject in = new JsonObject(); for (Attribute att : inv.getRequest().getAttributes()) in.addProperty(att.getName(), att.getValue()); // JsonArray inArray = new JsonArray(); // inArray.add(in); this.jsonInputs.add(in); JsonObject urlAndIn = new JsonObject(); urlAndIn.addProperty(this.urlColumnName, inv.getRequest().getUrl().toString()); for (Attribute att : inv.getRequest().getAttributes()) urlAndIn.addProperty(att.getName(), att.getValue()); this.jsonUrlAndInputs.add(urlAndIn); JsonArray urlAndOut = new JsonArray(); urlAndOut.add(url); urlAndOut.add(out); this.jsonUrlAndOutputs.add(urlAndOut); JsonArray inAndOut = new JsonArray(); inAndOut.add(in); inAndOut.add(out); this.jsonInputsAndOutputs.add(inAndOut); JsonArray all = new JsonArray(); all.add(urlAndIn); all.add(out); this.json.add(all); } catch (Exception e) { logger.debug("Error in parsing json returned by the invocation " + inv.getRequest().getUrl().toString()); } } public String getServiceJson(boolean includeURL, boolean includeInputAttributes, boolean includeOutputAttributes) { if (includeURL && includeInputAttributes && includeOutputAttributes) return this.json.toString(); else if (includeURL && includeInputAttributes) return this.jsonUrlAndInputs.toString(); else if (includeURL && includeOutputAttributes) return this.jsonUrlAndOutputs.toString(); else if (includeInputAttributes && includeOutputAttributes) return this.jsonInputsAndOutputs.toString(); else if (includeURL) return this.jsonUrl.toString(); else if (includeInputAttributes) return this.jsonInputs.toString(); else if (includeOutputAttributes) return this.jsonOutputs.toString(); else return ""; } public Table getServiceData(boolean includeURL, boolean includeInputAttributes, boolean includeOutputAttributes) { if (includeURL && includeInputAttributes && includeOutputAttributes) return this.serviceData; List<Attribute> headers = this.serviceData.getHeaders(); List<List<String>> values = this.serviceData.getValues(); Table newTable = new Table(); List<Attribute> newHeader = new ArrayList<Attribute>(); List<List<String>> newValues = new ArrayList<List<String>>(); List<String> newRowIds = new ArrayList<String>(this.serviceData.getRowIds()); List<Integer> includingColumns = new ArrayList<Integer>(); if (headers != null) { if (includeURL && headers.size() > 0) includingColumns.add(0); for (int i = 1; i < this.serviceData.getHeaders().size(); i++) { if (includeInputAttributes && headers.get(i).getIOType() == IOType.INPUT) includingColumns.add(i); if (includeOutputAttributes && headers.get(i).getIOType() == IOType.OUTPUT) includingColumns.add(i); } } for (Integer colIndex : includingColumns) { newHeader.add(headers.get(colIndex)); } for (List<String> vals : values) { List<String> rowVals = new ArrayList<String>(); for (Integer colIndex : includingColumns) rowVals.add(vals.get(colIndex)); newValues.add(rowVals); } newTable.setHeaders(newHeader); newTable.setValues(newValues); newTable.setRowIds(newRowIds); return newTable; } public Table getServiceData() { return getServiceData(true, true, true); } public String getServiceJson(boolean includeInputAttributes) { if (includeInputAttributes) return getServiceJson(true, true, true); return getServiceJson(false, false, true); } private List<Attribute> getInputAttributes() { List<Attribute> inAttributes = new ArrayList<Attribute>(); Table serviceTable = getServiceData(); for (Attribute p : serviceTable.getHeaders()) { if (p.getIOType().equalsIgnoreCase(IOType.INPUT)) { inAttributes.add(p); } } return inAttributes; } private List<Attribute> getOutputAttributes() { List<Attribute> outAttributes = new ArrayList<Attribute>(); Table serviceTable = getServiceData(); for (Attribute p : serviceTable.getHeaders()) { if (p.getIOType().equalsIgnoreCase(IOType.OUTPUT)) outAttributes.add(p); } return outAttributes; } /** * This method creates a new service model which includes only the * service endpoint, http method, input and output attributes * @return */ public WebService getInitialServiceModel(String serviceName) { String guid = new RandomGUID().toString(); // guid = "E9C3F8D3-F778-5C4B-E089-C1749D50AE1F"; URL sampleUrl = requestURLs.get(0); if (sampleUrl == null) return null; WebService service = null; if (serviceName == null || serviceName.trim().length() == 0) service = new WebService(guid, sampleUrl); else service = new WebService(guid, serviceName, sampleUrl); service.setMethod(HttpMethods.GET); service.setInputAttributes(getInputAttributes()); service.setOutputAttributes(getOutputAttributes()); return service; } public static void main(String[] args) { // String s1 = "http://colo-vm10.isi.edu:8080/DovetailService/GetSampleData?sourceName=KDD-02-B-TOSIG"; String s1 = "http://api.geonames.org/neighbourhood?lat=40.78343&lng=-73.96625&username=karma"; // String s1 = "http://api.geonames.org/postalCodeCountryInfo?username=karma"; // String s2 = "http://api.geonames.org/neighbourhood?lat=40.7&lng=-73.9&username=karma"; // String s3 = "http://api.geonames.org/neighbourhood?lat=40.9&lng=-73.9&username=karma"; List<String> urls = new ArrayList<String>(); urls.add(s1); // urls.add(s2); // urls.add(s3); List<String> ids = new ArrayList<String>(); ids.add("1"); // ids.add("2"); // ids.add("3"); try { InvocationManager sb = new InvocationManager(null, ids, urls); Table tb = sb.getServiceData(false, false, true); // String str = tb.asCSV(); // File f = new File("csv"); // PrintWriter pw = new PrintWriter(f); // pw.write(str); // pw.close(); logger.debug(tb.getPrintInfo()); WebService service = sb.getInitialServiceModel(null); // just for test service.getInputAttributes().get(0).sethNodeId("HN1"); service.getInputAttributes().get(1).sethNodeId("HN2"); service.getOutputAttributes().get(4).sethNodeId("HN3"); service.getOutputAttributes().get(6).sethNodeId("HN4"); service.getOutputAttributes().get(5).sethNodeId("HN5"); service.getOutputAttributes().get(3).sethNodeId("HN6"); service.print(); service.updateModel(Test.getGeoNamesNeighbourhoodTree()); String dir = Repository.Instance().SOURCE_REPOSITORY_DIR; service.getInputModel().writeJenaModelToFile(dir + "model", "N3"); System.out.println(service.getInputModel().getSparql(null)); } catch (Exception e) { e.printStackTrace(); } } }