update verigraph
[parser.git] / verigraph / src / it / polito / verigraph / resources / GraphResource.java
1 /*******************************************************************************
2  * Copyright (c) 2017 Politecnico di Torino and others.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Apache License, Version 2.0
6  * which accompanies this distribution, and is available at
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *******************************************************************************/
9 package it.polito.verigraph.resources;
10
11 import java.io.IOException;
12 import java.net.URI;
13 import java.util.List;
14 import javax.ws.rs.BeanParam;
15 import javax.ws.rs.Consumes;
16 import javax.ws.rs.DELETE;
17 import javax.ws.rs.GET;
18 import javax.ws.rs.POST;
19 import javax.ws.rs.PUT;
20 import javax.ws.rs.Path;
21 import javax.ws.rs.PathParam;
22 import javax.ws.rs.Produces;
23 import javax.ws.rs.QueryParam;
24 import javax.ws.rs.core.Context;
25 import javax.ws.rs.core.MediaType;
26 import javax.ws.rs.core.Response;
27 import javax.ws.rs.core.UriInfo;
28 import javax.xml.bind.JAXBException;
29 import com.fasterxml.jackson.core.JsonParseException;
30 import com.fasterxml.jackson.core.JsonProcessingException;
31 import com.fasterxml.jackson.databind.JsonMappingException;
32 import io.swagger.annotations.Api;
33 import io.swagger.annotations.ApiOperation;
34 import io.swagger.annotations.ApiParam;
35 import io.swagger.annotations.ApiResponse;
36 import io.swagger.annotations.ApiResponses;
37 import it.polito.neo4j.exceptions.MyInvalidDirectionException;
38 import it.polito.neo4j.exceptions.MyInvalidIdException;
39 import it.polito.neo4j.exceptions.MyNotFoundException;
40 import it.polito.verigraph.model.ErrorMessage;
41 import it.polito.verigraph.model.Graph;
42 import it.polito.verigraph.model.Node;
43 import it.polito.verigraph.model.Verification;
44 import it.polito.verigraph.resources.beans.VerificationBean;
45 import it.polito.verigraph.service.GraphService;
46 import it.polito.verigraph.service.VerificationService;
47
48 @Path("/graphs")
49 @Api(value = "/graphs", description = "Manage graphs")
50 @Consumes(MediaType.APPLICATION_JSON)
51 @Produces(MediaType.APPLICATION_JSON)
52 public class GraphResource {
53     GraphService graphService= new GraphService();
54     VerificationService verificationService= new VerificationService();
55
56     @GET
57     @ApiOperation(httpMethod = "GET",
58     value = "Returns all graphs",
59     notes = "Returns an array of graphs",
60     response = Graph.class,
61     responseContainer = "List")
62     @ApiResponses(value = { @ApiResponse(code = 200,
63     message = "All the graphs have been returned in the message body",
64     response = Graph.class,
65     responseContainer = "List"),
66             @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class)})
67     public List<Graph> getGraphs() throws JsonProcessingException, MyNotFoundException {
68         return graphService.getAllGraphs();
69     }
70
71     @POST
72     @ApiOperation(httpMethod = "POST",
73     value = "Creates a graph",
74     notes = "Creates a signle graph",
75     response = Response.class)
76     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid graph supplied", response = ErrorMessage.class),
77             @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
78             @ApiResponse(code = 201, message = "Graph successfully created", response = Graph.class) })
79     public Response addGraph(@ApiParam(value = "New graph object", required = true) Graph graph,
80             @Context UriInfo uriInfo) throws JAXBException, JsonParseException, JsonMappingException, IOException, MyInvalidIdException {
81         Graph newGraph = graphService.addGraph(graph);
82         String newId = String.valueOf(newGraph.getId());
83         URI uri = uriInfo.getAbsolutePathBuilder().path(newId).build();
84         return Response.created(uri).entity(newGraph).build();
85     }
86
87     @GET
88     @Path("/{graphId}")
89     @ApiOperation(httpMethod = "GET",
90     value = "Returns a graph",
91     notes = "Returns a signle graph",
92     response = Graph.class)
93     @ApiResponses(value = {@ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
94             @ApiResponse(code = 404, message = "Graph not found", response = ErrorMessage.class),
95             @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
96             @ApiResponse(code = 200,
97             message = "The requested graph has been returned in the message body",
98             response = Graph.class) })
99     public Graph getGraph(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
100             @Context UriInfo uriInfo) throws JsonParseException, JsonMappingException, JAXBException, IOException {
101         Graph graph = graphService.getGraph(graphId);
102         graph.addLink(getUriForSelf(uriInfo, graph), "self");
103         graph.addLink(getUriForNodes(uriInfo, graph), "nodes");
104         return graph;
105     }
106
107     @PUT
108     @Path("/{graphId}")
109     @ApiOperation(httpMethod = "PUT", value = "Edits a graph", notes = "Edits a single graph", response = Graph.class)
110     @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid graph object", response = ErrorMessage.class),
111             @ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
112             @ApiResponse(code = 404, message = "Graph not found", response = ErrorMessage.class),
113             @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
114             @ApiResponse(code = 200, message = "Graph edited successfully", response = Graph.class) })
115     public Graph updateGraph(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long id,
116             @ApiParam(value = "Updated graph object", required = true) Graph graph) throws JAXBException, JsonParseException, JsonMappingException, IOException, MyInvalidIdException {
117         graph.setId(id);
118         return graphService.updateGraph(graph);
119     }
120
121     @DELETE
122     @Path("/{graphId}")
123     @ApiOperation(httpMethod = "DELETE", value = "Deletes a graph", notes = "Deletes a signle graph")
124     @ApiResponses(value = {@ApiResponse(code = 403, message = "Invalid graph id", response = ErrorMessage.class),
125             @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),
126             @ApiResponse(code = 204, message = "Graph successfully deleted") })
127     public void deleteGraph(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long id) {
128         graphService.removeGraph(id);
129     }
130
131     @GET
132     @Path("/{graphId}/policy")
133     @ApiOperation(httpMethod = "GET",
134     value = "Verifies a given policy in a graph",
135     notes = "In order to verify a given policy (e.g. 'reachability') all nodes of the desired graph must have a valid configuration.")
136     @ApiResponses(value = {@ApiResponse(code = 403,
137     message = "Invalid graph id or invalid configuration for source and/or destination node",
138     response = ErrorMessage.class),
139             @ApiResponse(code = 404,
140             message = "Graph not found or source node not found or destination node not found or configuration for source and/or destination node not available",
141             response = ErrorMessage.class),
142             @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),})
143     public Verification verifyGraph(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
144             @ApiParam(value = "'source' and 'destination' must refer to names of existing nodes in the same graph, 'type' refers to the required verification between the two (e.g. 'reachability')",
145             required = true) @BeanParam VerificationBean verificationBean) throws MyInvalidDirectionException, JsonParseException, JsonMappingException, JAXBException, IOException {
146
147         return verificationService.verify(graphId, verificationBean);
148     }
149
150     private String getUriForSelf(UriInfo uriInfo, Graph graph) {
151         String uri = uriInfo.getBaseUriBuilder()
152                 .path(GraphResource.class)
153                 .path(Long.toString(graph.getId()))
154                 .build()
155                 .toString();
156         return uri;
157     }
158
159     @GET
160     @Path("/{graphId}/paths")
161     @ApiOperation(httpMethod = "GET",value = "Retrieve all paths between two nodes")
162     @ApiResponses(value = {@ApiResponse(code = 403,
163     message = "Invalid graph id or invalid configuration for source and/or destination node",
164     response = ErrorMessage.class),
165             @ApiResponse(code = 404,
166             message = "Graph not found or source node not found or destination node not found or configuration for source and/or destination node not available",
167             response = ErrorMessage.class),
168             @ApiResponse(code = 500, message = "Internal server error", response = ErrorMessage.class),})
169
170     public List<List<Node>> getPaths(@ApiParam(value = "Graph id", required = true) @PathParam("graphId") long graphId,
171             @ApiParam(value = "'source' must refer to name of existing nodes in the same graph",
172             required = true) @QueryParam("source") String srcName,
173             @ApiParam(value = "'destination' must refer to name of existing nodes in the same graph",
174             required = true)@QueryParam("destination") String dstName) throws MyInvalidDirectionException, JsonParseException, JsonMappingException, JAXBException, IOException {
175
176         return verificationService.getPaths(graphId, srcName, dstName);
177     }
178
179     private String getUriForNodes(UriInfo uriInfo, Graph graph) {
180         String uri = uriInfo.getBaseUriBuilder()
181                 .path(GraphResource.class)
182                 .path(GraphResource.class, "getNodeResource")
183                 // .path(NodeResource.class)
184                 .resolveTemplate("graphId", graph.getId())
185                 .build()
186                 .toString();
187         return uri;
188     }
189
190     @Path("/{graphId}/nodes")
191     public NodeResource getNodeResource() {
192         return new NodeResource();
193     }
194 }