Package org.neo4j.community.console

Source Code of org.neo4j.community.console.ConsoleService

package org.neo4j.community.console;

import com.google.gson.Gson;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.neo4j.rest.graphdb.RestAPIFacade;
import org.slf4j.Logger;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.rest.graphdb.RestAPI;
import org.neo4j.rest.graphdb.query.RestCypherQueryEngine;
import org.neo4j.rest.graphdb.util.QueryResult;
import spark.Request;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.Map;
import java.util.Scanner;

import static org.neo4j.helpers.collection.MapUtil.map;

/**
* @author mh
* @since 30.05.12
*/
public class ConsoleService {

    private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(ConsoleService.class);

    static final String DEFAULT_GRAPH_CYPHER =
        "create " +
        "(Neo:Crew {name:'Neo'}), " +
        "(Morpheus:Crew {name: 'Morpheus'}), " +
        "(Trinity:Crew {name: 'Trinity'}), " +
        "(Cypher:Crew:Matrix {name: 'Cypher'}), " +
        "(Smith:Matrix {name: 'Agent Smith'}), " +
        "(Architect:Matrix {name:'The Architect'}),\n" +
        "(Neo)-[:KNOWS]->(Morpheus), " +
        "(Neo)-[:LOVES]->(Trinity), " +
        "(Morpheus)-[:KNOWS]->(Trinity),\n" +
        "(Morpheus)-[:KNOWS]->(Cypher), " +
        "(Cypher)-[:KNOWS]->(Smith), " +
        "(Smith)-[:CODED_BY]->(Architect)";

    static final String DEFAULT_QUERY = "match (n:Crew)-[r:KNOWS*]-m where n.name='Neo' return n as Neo,r,m";

    private GraphStorage storage;

    public ConsoleService() {
        createGraphStorage();
    }

    private void createGraphStorage() {
        try {
        System.setProperty("org.neo4j.rest.read_timeout","5");
        System.setProperty("org.neo4j.rest.connect_timeout","10");
        String restUrlVar = System.getenv("NEO4J_REST_URL_VAR");
        if (restUrlVar == null ) restUrlVar = "NEO4J_URL";
        String restUrl = System.getenv(restUrlVar);

        String login = null, password = null;
        if (restUrl!=null) {
            login = System.getenv("NEO4J_LOGIN");
            password = System.getenv("NEO4J_PASSWORD");
            if (login == null) {
                try {
                    URL url = new URL(restUrl);
                    String userInfo = url.getUserInfo();
                    if (userInfo != null) {
                        login = userInfo.split(":")[0];
                        password = userInfo.split(":")[1];
                    }
                } catch (MalformedURLException e) {
                    throw new RuntimeException("Invalid Neo4j-Server-URL " + restUrl);
                }
            }

            if (!restUrl.contains("/db/data")) restUrl += "/db/data";
            final RestAPI api = new RestAPIFacade(restUrl, login, password);
            storage = new RestGraphStorage(api);
            log("Graph Storage " + restUrl + " login " + login + " " + password + " " + storage);
        }
        } catch(Exception e) {
            LOG.error("Error creating graph storage",e);
        }
        if (storage == null) {
            storage = new MemoryGraphStorage();
        }
        log("Graph Storage " + storage);
    }

    private void log(String msg) {
        LOG.warn(msg);
    }

    // split init and query on ";\n"
    public Map<String, Object> execute(Neo4jService service, String init, String query, String version,Map<String,Object> requestParams,Map<String,Object> queryParams) {
        if (version!=null) service.setVersion(version);
        boolean initial = init != null;
        if (dontInitialize(service) || init==null || init.equalsIgnoreCase("none")) init=null;
        if (query == null || query.equalsIgnoreCase("none")) query=null;
        final Map<String, Object> data = map("init", init, "query", query,"version",service.getVersion());
        long start = System.currentTimeMillis(), time = start;
        try {
            time = trace("service", time);
            if (init!=null) {
                final URL url = service.toUrl(init);
                if (url!=null) {
                    initFromUrl(service, url, "start n=node(*) match n-[r?]->() return n,r");
                    data.put("graph",service.exportToGeoff());
                } else if (service.isMutatingQuery(init)) {
                    for (String q : splitQuery(init)) {
                        service.initCypherQuery(q,queryParams);
                    }
                    data.put("graph",service.exportToGeoff());
                } else {
                    final Map<String,Object> graph = service.mergeGeoff(init);

                    data.put("graph", service.exportToJson(graph));
                }
            }
            if (initial) {
                service.setInitialized();
            }
            time = trace("graph", time);
            CypherQueryExecutor.CypherResult result = null;
            if (query!=null) {
                for (String q : splitQuery(query)) {
                    result = service.cypherQuery(q,queryParams);
                }
                data.put("result", result.getText());
                data.put("json", result.getJson());
                data.put("plan", result.getPlan().toString());
                data.put("columns", result.getColumns());
                data.put("stats", result.getQueryStatistics());
                String pretty = service.prettify(query);
                if (pretty!=null) data.put("query",pretty);
            }
            time = trace("cypher", time);
            if (!noViz(requestParams)) {
                data.put("visualization", service.cypherQueryViz(result));
            }
            trace("viz", time);
        } catch (Exception e) {
            e.printStackTrace();
            data.put("error", e.toString());
        }
        time = trace("all", start);
        data.put("time", time-start);
        return data;
    }

    private boolean noViz(Map<String, Object> params) {
        return "none".equals(params.get("viz"));
    }

    private String[] splitQuery(String allQueries) {
        return allQueries.split(";\n");
    }

    private boolean dontInitialize(Neo4jService service) {
        return !service.doesOwnDatabase() || service.isInitialized();
    }

    protected long trace(String msg, long time) {
        long now = System.currentTimeMillis();
        log("## " + msg + " took: " + (now - time) + " ms.");
        return now;
    }


    public String shortenUrl(String uri) {
        try {
            final InputStream stream = (InputStream) new URL("http://tinyurl.com/api-create.php?url=" + URLEncoder.encode(uri, "UTF-8")).getContent();
            final String shortUrl = new Scanner(stream).useDelimiter("\\z").next();
            stream.close();
            return shortUrl;
        } catch (IOException ioe) {
            return null;
        }
    }

    public Map<String, Object> execute(Neo4jService service, GraphInfo info, Map<String, Object> params, Map<String, Object> queryParams) {
        final Map<String, Object> result = this.execute(service, info.getInit(), info.getQuery(), info.getVersion(),params,queryParams);
        result.put("message",info.getMessage());
        return result;
    }

    protected String param(Map input, String param, String defaultValue) {
        if (input==null) return defaultValue;
        String data = (String) input.get(param);
        if (data == null || data.isEmpty()) {
            data = defaultValue;
        } else {
            log(param+": "+data);
        }
        return data;
    }

    public Map<String, Object> init(Neo4jService service, Map<String,Object> input) {
        input.put("init",param(input,"init",DEFAULT_GRAPH_CYPHER));
        input.put("query",param(input,"query",DEFAULT_QUERY));
        return execute(service, GraphInfo.from(input), input, (Map)input.get("queryParams"));
    }

    protected String baseUri(HttpServletRequest request, String query, final String path) {
        final String requestURI = request.getRequestURL().toString();
        try {
            final URI uri = new URI(requestURI);
            return new URI(uri.getScheme(),null,uri.getHost(),uri.getPort(), path,query,null).toString();
        } catch (URISyntaxException e) {
            throw new RuntimeException("Error parsing URI from "+requestURI+" query "+query);
        }
    }

    protected String encodeParam(String param, String value) {
        if (value==null || value.trim().isEmpty()) return "";
        try {
            return param + "=" + URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return param + "=" + URLEncoder.encode(value);
        }
    }
    public String createInitialUri(Request request, GraphInfo info) {
        return baseUri( request.raw(),
                                encodeParam("init",  info.getInit()) +
                                encodeParam("query", info.getQuery()) +
                                encodeParam("version", info.getVersion()) +
                                encodeParam("message", info.getMessage()) +
                                encodeParam("no_root", info.hasRoot() ? null : "true"),
                                null);
    }

    Map<String, Object> init(Neo4jService service, String id, Map<String,Object> params) {
        final GraphInfo info = storage.find(id);
        Map<String, Object> result;
        if (info!=null) {
            result = execute(service, info.getInit(), info.getQuery(), info.getVersion(), params,(Map)params.get("queryParams"));
            result.put("message",info.getMessage());
        } else {
            result = init(service, params);
            result.put("error","Graph not found for id " + id+ " rendering default");
        }
        return result;
    }

    public Object share(Request request, Map input) {
        final GraphInfo info = GraphInfo.from(input);
        try {
            if (storage!=null) return storage.create(info).getId();
        } catch(Exception e) {
            log("Error storing shared data "+info);
            e.printStackTrace();
        }
        final String uri = createInitialUri(request, info);
        return shortenUrl(uri);
    }

    public void initFromUrl(Neo4jService service, URL url, final String query) {
        if (!service.doesOwnDatabase()) return;
        final String urlString = url.toString().replaceAll("/cypher/?$", "");
        final RestAPI restApi = new RestAPIFacade(urlString);
        final QueryResult<Map<String,Object>> cypherResult = new RestCypherQueryEngine(restApi).query(query, null);
        final SubGraph graph = new SubGraph();
        for (Map<String, Object> row : cypherResult) {
            for (Object value : row.values()) {
                addResultValue(graph, value);
            }
        }
        service.importGraph(graph);
    }

    private void addResultValue(SubGraph subGraph, Object value) {
        if (value instanceof Node) {
            subGraph.add((Node)value);
        }
        if (value instanceof Relationship) {
            subGraph.add((Relationship)value);
        }
        if (value instanceof Iterable) {
            for (Object inner : (Iterable)value) {
                addResultValue(subGraph,inner);
            }
        }
    }

    private <T> T post(URL url, Map<String, Object> data, Class<T> resultType) {
        try {
            final HttpClient client = clientFor(url);
            final PostMethod post = new PostMethod(url.toString());
            post.setDoAuthentication(true);
            post.setRequestHeader("Accept", "application/json;stream=true");
            final Gson gson = new Gson();
            final String postData = gson.toJson(data);
            post.setRequestEntity(new StringRequestEntity(postData, "application/json", "UTF-8"));
            final int status = client.executeMethod(post);
            if (status != 200) throw new RuntimeException("Return Status Code "+post.getStatusCode()+" "+post.getStatusLine());
            return gson.fromJson(post.getResponseBodyAsString(), resultType);
        } catch (Exception e) {
            throw new RuntimeException("Error executing request to "+url+" with "+data+":" + e.getMessage());
        }
    }

    private HttpClient clientFor(URL url) {
        final HttpClient client = new HttpClient();
        final String userInfo = url.getUserInfo();
        if (userInfo != null) {
            final String[] usernamePassword = userInfo.split(":");
            client.getState().setCredentials(new AuthScope(url.getHost(), url.getPort()), new UsernamePasswordCredentials(usernamePassword[0], usernamePassword[1]));
        }
        return client;
    }
    public void initFromUrl2(Neo4jService service, URL url, final String query) {
        final Map cypherResult = post(url, map("query", query), Map.class);
        SubGraph graph=SubGraph.fromRaw(cypherResult, false);
        service.importGraph(graph);

    }
}
TOP

Related Classes of org.neo4j.community.console.ConsoleService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.