Package org.lab41.dendrite.web.controller

Source Code of org.lab41.dendrite.web.controller.GraphController

package org.lab41.dendrite.web.controller;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import org.lab41.dendrite.metagraph.DendriteGraph;
import org.lab41.dendrite.metagraph.DendriteGraphTx;
import org.lab41.dendrite.metagraph.MetaGraphTx;
import org.lab41.dendrite.metagraph.NotFound;
import org.lab41.dendrite.metagraph.models.GraphMetadata;
import org.lab41.dendrite.metagraph.models.ProjectMetadata;
import org.lab41.dendrite.metagraph.models.UserMetadata;
import org.lab41.dendrite.services.MetaGraphService;
import org.lab41.dendrite.web.requests.CreateGraphRequest;
import org.lab41.dendrite.web.responses.GetGraphResponse;
import org.lab41.dendrite.web.responses.GetGraphsResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;

import javax.validation.Valid;
import java.security.Principal;
import java.util.*;

@Controller
@RequestMapping("/api")
public class GraphController extends AbstractController {

    @Autowired
    MetaGraphService metaGraphService;

    // Note this doesn't use @PreAuthorize on purpose because it'll only show the user's graphs.
    @RequestMapping(value = "/graphs", method = RequestMethod.GET)
    @ResponseBody
    public GetGraphsResponse getGraphs(Principal principal) {

        // This needs to be a read/write transaction as we might make a user.
        MetaGraphTx tx = metaGraphService.buildTransaction().start();
        List<GetGraphResponse> graphs = new ArrayList<>();

        try {
            UserMetadata userMetadata = tx.getOrCreateUser(principal);

            for (ProjectMetadata projectMetadata : userMetadata.getProjects()) {
                for (GraphMetadata graphMetadata : projectMetadata.getGraphs()) {
                    graphs.add(new GetGraphResponse(graphMetadata));
                }
            }
        } catch (Throwable t) {
            tx.rollback();
            throw t;
        }

        // Commit must come after all graph access.
        tx.commit();

        return new GetGraphsResponse(graphs);
    }

    @PreAuthorize("hasPermission(#graphId, 'graph', 'admin')")
    @RequestMapping(value = "/graphs/{graphId}", method = RequestMethod.GET)
    @ResponseBody
    public GetGraphResponse getGraph(@PathVariable String graphId) throws NotFound {

        MetaGraphTx tx = metaGraphService.buildTransaction().readOnly().start();

        try {
            GraphMetadata graphMetadata = tx.getGraph(graphId);
            if (graphMetadata == null) {
                throw new NotFound(GraphMetadata.class, graphId);
            }

            // FIXME: Temporary hack to force loading the graph until the UI can handle it occurring asynchronously.
            metaGraphService.getDendriteGraph(graphMetadata.getId());

            return new GetGraphResponse(graphMetadata);
        } finally {
            tx.commit();
        }
    }

    @PreAuthorize("hasPermission(#graphId, 'graph', 'admin')")
    @RequestMapping(value = "/graphs/{graphId}/random", method = RequestMethod.GET)
    public ResponseEntity<Map<String, Object>> getRandom(@PathVariable String graphId) throws NotFound {

        Map<String, Object> response = new HashMap<>();
        MetaGraphTx tx = metaGraphService.buildTransaction().readOnly().start();

        try {
            GraphMetadata graphMetadata = tx.getGraph(graphId);
            if (graphMetadata == null) {
                throw new NotFound(GraphMetadata.class, graphId);
            }

            DendriteGraph graph = metaGraphService.getDendriteGraph(graphId);

            DendriteGraphTx dendriteGraphTx = graph.buildTransaction().readOnly().start();

            try {
                Map<Object, Object> verticesMap = new HashMap<>();
                Map<Object, Object> edgesMap = new HashMap<>();

                for (Vertex vertex : dendriteGraphTx.query().limit(300).vertices()) {
                    addVertex(verticesMap, vertex);
                }

                for (Edge edge : dendriteGraphTx.query().limit(300).edges()) {
                    addEdge(verticesMap, edgesMap, edge);
                }

                response.put("vertices", new ArrayList<>(verticesMap.values()));
                response.put("edges", new ArrayList<>(edgesMap.values()));
            } finally {
                dendriteGraphTx.commit();
            }

            return new ResponseEntity<>(response, HttpStatus.OK);
        } finally {
            tx.commit();
        }
    }

    private void addVertex(Map<Object, Object> verticesMap, Vertex vertex) {
        if (!verticesMap.containsKey(vertex.getId())) {
            Map<String, Object> vertexMap = new HashMap<>();
            verticesMap.put(vertex.getId(), vertexMap);

            vertexMap.put("_id", vertex.getId().toString());
            vertexMap.put("_type", "vertex");

            // Include the name so we can have a nice tooltip.
            Object value = vertex.getProperty("name");
            if (value != null) {
                vertexMap.put("name", value);
            }
        }
    }

    private void addEdge(Map<Object, Object> verticesMap, Map<Object, Object> edgesMap, Edge edge) {
        if (!edgesMap.containsKey(edge.getId())) {
            Map<String, Object> edgeMap = new HashMap<>();
            edgesMap.put(edge.getId(), edgeMap);

            Vertex inV = edge.getVertex(Direction.IN);
            Vertex outV = edge.getVertex(Direction.OUT);

            edgeMap.put("_id", edge.getId().toString());
            edgeMap.put("_type", "edge");
            edgeMap.put("_inV", inV.getId().toString());
            edgeMap.put("_outV", outV.getId().toString());

            addVertex(verticesMap, inV);
            addVertex(verticesMap, outV);
        }
    }

    @PreAuthorize("hasPermission(#graphId, 'graph', 'admin')")
    @RequestMapping(value = "/graphs/{graphId}", method = RequestMethod.DELETE)
    public ResponseEntity<Map<String, Object>> deleteGraph(@PathVariable String graphId) throws NotFound {

        Map<String, Object> response = new HashMap<>();
        MetaGraphTx tx = metaGraphService.newTransaction();

        try {
            GraphMetadata graphMetadata = tx.getGraph(graphId);
            if (graphMetadata == null) {
                throw new NotFound(GraphMetadata.class, graphId);
            }

            try {
                tx.deleteGraph(graphMetadata);
            } catch (Exception e) {
                response.put("status", "error");
                response.put("msg", e.toString());
                tx.rollback();
                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
            }

            response.put("msg", "deleted");

            return new ResponseEntity<>(response, HttpStatus.OK);
        } finally {
            tx.commit();
        }
    }

    @PreAuthorize("hasPermission(#projectId, 'project', 'admin')")
    @RequestMapping(value = "/projects/{projectId}/graphs", method = RequestMethod.GET)
    @ResponseBody
    public GetGraphsResponse getGraphs(@PathVariable String projectId) throws NotFound {

        MetaGraphTx tx = metaGraphService.buildTransaction().readOnly().start();

        try {
            ProjectMetadata projectMetadata = tx.getProject(projectId);
            if (projectMetadata == null) {
                throw new NotFound(ProjectMetadata.class, projectId);
            }

            List<GetGraphResponse> graphs = new ArrayList<>();
            for (GraphMetadata graphMetadata : projectMetadata.getGraphs()) {
                graphs.add(new GetGraphResponse(graphMetadata));
            }

            return new GetGraphsResponse(graphs);
        } finally {
            tx.commit();
        }
    }

    @PreAuthorize("hasPermission(#projectId, 'project', 'admin')")
    @RequestMapping(value = "/projects/{projectId}/graphs", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<GetGraphResponse> createGraph(@PathVariable String projectId,
                                                        @Valid @RequestBody CreateGraphRequest item,
                                                        BindingResult result,
                                                        UriComponentsBuilder builder) throws BindingException, NotFound {

        if (result.hasErrors()) {
            throw new BindingException(result);
        }

        MetaGraphTx tx = metaGraphService.newTransaction();
        GetGraphResponse getGraphResponse;
        HttpHeaders headers = new HttpHeaders();

        try {
            ProjectMetadata projectMetadata = tx.getProject(projectId);
            if (projectMetadata == null) {
                throw new NotFound(ProjectMetadata.class, projectId);
            }

            GraphMetadata graphMetadata = tx.createGraph(projectMetadata);
            graphMetadata.setProperties(item.getProperties());

            headers.setLocation(builder.path("/graphs/{graphId}").buildAndExpand(projectMetadata.getId()).toUri());

            getGraphResponse = new GetGraphResponse(graphMetadata);
        } catch (Throwable t) {
            tx.rollback();
            throw t;
        }

        tx.commit();

        return new ResponseEntity<>(getGraphResponse, headers, HttpStatus.CREATED);
    }

    @PreAuthorize("hasPermission(#projectId, 'project', 'admin')")
    @RequestMapping(value = "/projects/{projectId}/current-graph", method = RequestMethod.GET)
    @ResponseBody
    public GetGraphResponse getCurrentGraph(@PathVariable String projectId) throws NotFound {

        MetaGraphTx tx = metaGraphService.buildTransaction().readOnly().start();

        try {
            ProjectMetadata projectMetadata = tx.getProject(projectId);
            if (projectMetadata == null) {
                throw new NotFound(ProjectMetadata.class, projectId);
            }

            GraphMetadata graphMetadata = projectMetadata.getCurrentGraph();

            // FIXME: Temporary hack to force loading the graph until the UI can handle it occurring asynchronously.
            metaGraphService.getDendriteGraph(graphMetadata.getId());

            return new GetGraphResponse(graphMetadata);
        } finally {
            tx.commit();
        }
    }
}
TOP

Related Classes of org.lab41.dendrite.web.controller.GraphController

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.