package org.vertexium.examples; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.webapp.WebAppContext; import org.json.JSONArray; import org.json.JSONObject; import org.vertexium.*; import org.vertexium.accumulo.AccumuloAuthorizations; import org.vertexium.accumulo.AccumuloGraph; import org.vertexium.examples.dataset.BabyNamesDataset; import org.vertexium.examples.dataset.Dataset; import org.vertexium.examples.dataset.GeoNamesDataset; import org.vertexium.examples.dataset.ImdbDataset; import org.vertexium.util.IterableUtils; import org.vertexium.util.MapUtils; import org.vertexium.util.VertexiumLogger; import org.vertexium.util.VertexiumLoggerFactory; import javax.servlet.Servlet; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Properties; public abstract class ExampleBase { protected static final VertexiumLogger LOGGER = VertexiumLoggerFactory.getLogger(ExampleBase.class); private static final String VISIBILITIES[] = new String[]{"a", "b", "c", "d"}; private Dataset dataset; @Parameter(names = "-port", description = "Port to run server on") private int port = 7777; @Parameter(names = "-clear", description = "Clear before running") private boolean clear = false; @Parameter(names = "-dataset", description = "Name of the dataset") private String datasetName = null; @Parameter(names = "-count", description = "Number of vertices to create") private int verticesToCreate = 3000; private Server server; private Graph graph; protected void run(String[] args) throws Exception { new JCommander(this, args); this.server = runJetty(port); this.graph = openGraph(getGraphConfig()); if (datasetName == null) { throw new RuntimeException("must specify a dataset"); } else if (datasetName.equals("GeoNamesDataset")) { dataset = new GeoNamesDataset(); } else if (datasetName.equals("BabyNamesDataset")) { dataset = new BabyNamesDataset(); } else if (datasetName.equals("ImdbDataset")) { dataset = new ImdbDataset(); } else { throw new RuntimeException("Unknown dataset name"); } clearGraph(this.graph); populateData(); } protected void clearGraph(Graph graph) { if (!clear) { int count = IterableUtils.count(graph.getVertices(createAuthorizations(VISIBILITIES))); if (count >= verticesToCreate) { LOGGER.debug("skipping clear graph. data already exists. count: %d", count); return; } } LOGGER.debug("clearing vertices"); graph.truncate(); } protected void populateData() throws IOException { if (IterableUtils.count(getGraph().getVertices(createAuthorizations(VISIBILITIES))) >= verticesToCreate) { LOGGER.debug("skipping create data. data already exists"); return; } addAuthorizations(); populateVertices(); } private void populateVertices() throws IOException { dataset.load(getGraph(), verticesToCreate, VISIBILITIES, createAuthorizations()); } private void addAuthorizations() { for (String v : VISIBILITIES) { addAuthorizationToUser(v); } } protected void stop() throws Exception { stopJetty(); stopGraph(); } protected static Authorizations createAuthorizations(String... auths) { if (auths.length == 1 && auths[0].length() == 0) { return new AccumuloAuthorizations(); } return new AccumuloAuthorizations(auths); } protected void addAuthorizationToUser(String visibilityString) { LOGGER.debug("adding auth %s", visibilityString); if (getGraph() instanceof AccumuloGraph) { try { org.apache.accumulo.core.client.Connector connector = ((AccumuloGraph) getGraph()).getConnector(); String principal = ((AccumuloGraph) getGraph()).getConnector().whoami(); org.apache.accumulo.core.security.Authorizations authorizations = connector.securityOperations().getUserAuthorizations(principal); if (authorizations.contains(visibilityString)) { return; } String[] newAuthorizations = new String[authorizations.getAuthorizations().size() + 1]; int i; for (i = 0; i < authorizations.getAuthorizations().size(); i++) { newAuthorizations[i] = new String(authorizations.getAuthorizations().get(i)); } newAuthorizations[i] = visibilityString; connector.securityOperations().changeUserAuthorizations(principal, new org.apache.accumulo.core.security.Authorizations(newAuthorizations)); } catch (Exception ex) { throw new RuntimeException("Could not add auths", ex); } } else { throw new RuntimeException("Unhandled graph type to add authorizations: " + getGraph().getClass().getName()); } } protected Graph openGraph(Map graphConfig) throws IOException { return new GraphFactory().createGraph(graphConfig); } private Map getGraphConfig() throws IOException { Properties config = new Properties(); InputStream in = new FileInputStream("config.properties"); try { config.load(in); } finally { in.close(); } return MapUtils.getAllWithPrefix(config, "graph"); } protected void stopGraph() { this.graph.shutdown(); } protected Server runJetty(int httpPort) throws Exception { WebAppContext webAppContext = new WebAppContext(); webAppContext.setContextPath("/"); webAppContext.addServlet(getServletClass(), "/*"); webAppContext.setWar("./src/main/webapp/"); ContextHandlerCollection contexts = new ContextHandlerCollection(); contexts.setHandlers(new Handler[]{webAppContext}); Server server = new Server(port); server.setHandler(contexts); server.start(); LOGGER.info("Listening http://localhost:%d", httpPort); return server; } protected abstract Class<? extends Servlet> getServletClass(); protected void stopJetty() throws Exception { server.stop(); } public Graph getGraph() { return graph; } public Server getServer() { return server; } public static JSONArray verticesToJson(Iterable<Vertex> vertices) { JSONArray json = new JSONArray(); for (Vertex v : vertices) { json.put(vertexToJson(v)); } return json; } public static JSONObject vertexToJson(Vertex vertex) { JSONObject json = new JSONObject(); json.put("id", vertex.getId()); JSONArray propertiesJson = new JSONArray(); for (Property property : vertex.getProperties()) { propertiesJson.put(propertyYoJson(property)); } json.put("properties", propertiesJson); return json; } public static JSONObject propertyYoJson(Property property) { JSONObject json = new JSONObject(); json.put("key", property.getKey()); json.put("name", property.getName()); json.put("metadata", propertyMetadataToJson(property.getMetadata())); json.put("visibility", property.getVisibility().toString()); json.put("value", property.getValue().toString()); return json; } public static JSONObject propertyMetadataToJson(Metadata metadata) { JSONObject json = new JSONObject(); for (Metadata.Entry entry : metadata.entrySet()) { json.put(entry.getKey(), entry.getValue()); } return json; } }