1 /*******************************************************************************
2 * Copyright (c) 2017 Politecnico di Torino and others.
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.client;
12 import java.io.FileReader;
13 import java.io.FilenameFilter;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.List;
20 import javax.ws.rs.ProcessingException;
21 import javax.ws.rs.client.Client;
22 import javax.ws.rs.client.ClientBuilder;
23 import javax.ws.rs.client.Entity;
24 import javax.ws.rs.client.ResponseProcessingException;
25 import javax.ws.rs.client.WebTarget;
26 import javax.ws.rs.core.Response;
27 import javax.ws.rs.core.Response.Status;
29 import com.fasterxml.jackson.core.JsonParseException;
30 import com.fasterxml.jackson.databind.JsonMappingException;
31 import com.fasterxml.jackson.databind.ObjectMapper;
33 import it.polito.verigraph.model.ErrorMessage;
34 import it.polito.verigraph.model.Graph;
35 import it.polito.verigraph.model.Neighbour;
36 import it.polito.verigraph.model.Node;
37 import it.polito.verigraph.model.Verification;
39 public class VerifyClient {
41 private WebTarget baseTarget;
42 private WebTarget graphsTarget;
43 private WebTarget graphTarget;
44 private WebTarget nodesTarget;
45 private WebTarget nodeTarget;
46 private WebTarget neighboursTarget;
47 private WebTarget neighbourTarget;
48 private WebTarget reachabilityTarget;
49 private WebTarget isolationTarget;
50 private WebTarget traversalTarget;
52 public VerifyClient(String address) {
54 Client client = ClientBuilder.newClient();
55 this.baseTarget = client.target(address);
56 this.graphsTarget = baseTarget.path("graphs");
57 this.graphTarget = graphsTarget.path("/{graphId}");
58 this.nodesTarget = graphTarget.path("/nodes");
59 this.nodeTarget = nodesTarget.path("//{nodeId}");
60 this.neighboursTarget = nodeTarget.path("/neighbours");
61 this.neighbourTarget = neighboursTarget.path("/{neighbourId}");
62 this.reachabilityTarget = graphTarget.path("/policy");
63 this.isolationTarget = graphTarget.path("/policy");
64 this.traversalTarget = graphTarget.path("/policy");
67 public void checkResponse(Response response) throws VerifyClientException {
68 int status = response.getStatus();
71 if (status == Response.Status.BAD_REQUEST.getStatusCode()) {
73 // String responseString = response.readEntity(String.class);
74 // System.out.println(responseString);
75 ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
76 String message = errorMessage.getErrorMessage();
77 throw new VerifyClientException("Bad request: " + message);
79 catch (ProcessingException e) {
80 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
83 catch (IllegalStateException e) {
84 throw new VerifyClientException("the entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
89 if (status == Response.Status.FORBIDDEN.getStatusCode()) {
91 ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
92 String message = errorMessage.getErrorMessage();
93 throw new VerifyClientException("Forbidden: " + message);
95 catch (ProcessingException e) {
96 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
99 catch (IllegalStateException e) {
100 throw new VerifyClientException("the entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
105 if (status == Response.Status.NOT_FOUND.getStatusCode()) {
107 ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
108 String message = errorMessage.getErrorMessage();
109 throw new VerifyClientException("Not found: " + message);
111 catch (ProcessingException e) {
112 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
115 catch (IllegalStateException e) {
116 throw new VerifyClientException("the 'Response' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
121 if (status == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
123 ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
124 String message = errorMessage.getErrorMessage();
125 throw new VerifyClientException("Internal server error: " + message);
127 catch (ProcessingException e) {
128 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
131 catch (IllegalStateException e) {
132 throw new VerifyClientException("the entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
136 if (status != Response.Status.ACCEPTED.getStatusCode() && status != Response.Status.CREATED.getStatusCode()
137 && status != Response.Status.NO_CONTENT.getStatusCode() && status != Response.Status.OK.getStatusCode())
138 throw new VerifyClientException("Unknown error");
141 public Response createGraph(Graph graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
142 Response response = graphsTarget.request().post(Entity.json(graph));
143 checkResponse(response);
147 public Response createGraph(String graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
148 Response response = graphsTarget.request().post(Entity.entity(graph, "application/json"));
149 checkResponse(response);
153 public Response retrieveGraph(long graphId) throws VerifyClientException, ProcessingException {
154 Response response = graphTarget.resolveTemplate("graphId", graphId).request().get();
155 checkResponse(response);
159 public Response updateGraph(long graphId, Graph graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
160 Response response = graphTarget.resolveTemplate("graphId", graphId).request().put(Entity.json(graph));
161 checkResponse(response);
165 public Response deleteGraph(long graphId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
166 Response response = graphTarget.resolveTemplate("graphId", graphId).request().delete();
167 checkResponse(response);
171 public Response createNode(long graphId, Node node) throws VerifyClientException, ResponseProcessingException, ProcessingException {
172 Response response = nodesTarget.resolveTemplate("graphId", graphId).request().post(Entity.json(node));
173 checkResponse(response);
177 public Response retrieveNode(long graphId, long nodeId) throws VerifyClientException, ProcessingException {
178 Response response = nodeTarget.resolveTemplate("graphId", graphId)
179 .resolveTemplate("nodeId", nodeId)
182 checkResponse(response);
186 public Response updateNode(long graphId, long nodeId, Node node) throws VerifyClientException, ResponseProcessingException, ProcessingException {
187 Response response = nodeTarget.resolveTemplate("graphId", graphId)
188 .resolveTemplate("nodeId", nodeId)
190 .put(Entity.json(node));
191 checkResponse(response);
195 public Response deleteNode(long graphId, long nodeId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
196 Response response = nodeTarget.resolveTemplate("graphId", graphId)
197 .resolveTemplate("nodeId", nodeId)
200 checkResponse(response);
204 public Response createNeighbour(long graphId, long nodeId, Neighbour neighbour) throws VerifyClientException, ResponseProcessingException, ProcessingException {
205 Response response = neighboursTarget.resolveTemplate("graphId", graphId)
206 .resolveTemplate("nodeId", nodeId)
208 .post(Entity.json(neighbour));
209 checkResponse(response);
213 public Response retrieveNeighbour(long graphId, long nodeId, long neighbourId) throws VerifyClientException, ProcessingException {
214 Response response = neighbourTarget.resolveTemplate("graphId", graphId)
215 .resolveTemplate("nodeId", nodeId)
216 .resolveTemplate("neighbourId", neighbourId)
219 checkResponse(response);
223 public Response updateNeighbour(long graphId, long nodeId, long neighbourId,
224 Neighbour neighbour) throws VerifyClientException, ResponseProcessingException, ProcessingException {
225 Response response = neighbourTarget.resolveTemplate("graphId", graphId)
226 .resolveTemplate("nodeId", nodeId)
227 .resolveTemplate("neighbourId", neighbourId)
229 .put(Entity.json(neighbour));
230 checkResponse(response);
234 public Response deleteNeighbour(long graphId, long nodeId, long neighbourId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
235 Response response = neighbourTarget.resolveTemplate("graphId", graphId)
236 .resolveTemplate("nodeId", nodeId)
237 .resolveTemplate("neighbourId", neighbourId)
240 checkResponse(response);
244 public Verification getReachability(long graphId, String source, String destination) throws VerifyClientException, ProcessingException{
245 Response response = reachabilityTarget.resolveTemplate("graphId", graphId)
246 .queryParam("source", source)
247 .queryParam("destination", destination)
248 .queryParam("type", "reachability")
251 checkResponse(response);
253 Verification verification = response.readEntity(Verification.class);
256 catch (ProcessingException e) {
257 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
260 catch (IllegalStateException e) {
261 throw new VerifyClientException("the 'Verification' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
266 public Verification getIsolation(long graphId, String source, String destination, String middlebox) throws VerifyClientException, ProcessingException{
267 Response response = isolationTarget.resolveTemplate("graphId", graphId)
268 .queryParam("source", source)
269 .queryParam("destination", destination)
270 .queryParam("middlebox", middlebox)
271 .queryParam("type", "isolation")
274 checkResponse(response);
276 Verification verification = response.readEntity(Verification.class);
279 catch (ProcessingException e) {
280 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
283 catch (IllegalStateException e) {
284 throw new VerifyClientException("the 'Verification' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
289 public Verification getTraversal(long graphId, String source, String destination, String middlebox) throws VerifyClientException, ProcessingException{
290 Response response = traversalTarget.resolveTemplate("graphId", graphId)
291 .queryParam("source", source)
292 .queryParam("destination", destination)
293 .queryParam("middlebox", middlebox)
294 .queryParam("type", "traversal")
297 checkResponse(response);
299 Verification verification = response.readEntity(Verification.class);
302 catch (ProcessingException e) {
303 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
306 catch (IllegalStateException e) {
307 throw new VerifyClientException("the 'Verification' entity is not backed by an input stream or the original entity input stream has already been consumed without buffering the entity data prior consuming: "
312 @SuppressWarnings("unused")
313 private static String deserializeString(File file) throws IOException {
315 char[] chr = new char[4096];
316 final StringBuffer buffer = new StringBuffer();
317 final FileReader reader = new FileReader(file);
319 while ((len = reader.read(chr)) > 0) {
320 buffer.append(chr, 0, len);
326 return buffer.toString();
329 public List<File> getFiles() {
330 List<File> filesList = new ArrayList<File>();
332 String folderString = System.getProperty("folder");
334 if (folderString == null)
335 folder = new File(System.getProperty("user.dir") + "/examples");
337 folder = new File(folderString);
339 System.out.println("Folder set to " + folder.getAbsolutePath());
341 File[] files = folder.listFiles(new FilenameFilter() {
344 public boolean accept(File dir, String name) {
345 return name.endsWith(".json");
349 for (File f : files) {
356 public Graph addGraphFromFile(File file) throws JsonParseException, JsonMappingException, IOException, Exception {
357 System.out.println("Parsing graph of file '" + file.getAbsolutePath() + "'...");
358 Graph graph = new ObjectMapper().readValue(file, Graph.class);
359 Response createGraphResponse = createGraph(graph);
360 if (createGraphResponse.getStatus() != Status.CREATED.getStatusCode()) {
361 throw new Exception("Creation of graph contained in file '"+ file.getAbsolutePath() + "' returned status "
362 + createGraphResponse.getStatus());
364 String responseString = createGraphResponse.readEntity(String.class);
365 System.out.println("Response:");
366 System.out.println(responseString);
367 Graph response = new ObjectMapper().readValue(responseString, Graph.class);
368 printGraph(response);
372 public void printGraph(Graph graph) {
373 System.out.println("Graph " + graph.getId());
374 for (Node n : graph.getNodes().values()) {
375 System.out.println("\tNode " + n.getId());
376 System.out.println("\tName " + n.getName());
377 System.out.println("\tFunctional type: " + n.getFunctional_type());
378 for (Neighbour neighbour : n.getNeighbours().values()) {
379 System.out.println("\t\tNeighbour " + neighbour.getId());
380 System.out.println("\t\tName: " + neighbour.getName());
385 public Map<String, Graph> addGraphsFromFiles(List<File> files)throws JsonParseException, JsonMappingException, IOException,
387 Map<String, Graph> graphs = new HashMap<String, Graph>();
389 for (File f : files) {
390 Graph graph = addGraphFromFile(f);
391 graphs.put(f.getName(), graph);
394 for (Map.Entry<String, Graph> graph : graphs.entrySet()) {
395 System.out.println(graph.getKey() + " -> graph " + graph.getValue().getId());
397 System.out.println("Graphs added");
402 public static void main(String[] args) throws IOException, Exception {
403 System.out.println("Adding graphs");
405 VerifyClient verifyClient = new VerifyClient("http://localhost:8080/verigraph/api");
407 List<File> files = verifyClient.getFiles();
408 Map<String, Graph> graphs = verifyClient.addGraphsFromFiles(files);
410 for (Graph g : graphs.values()) {
411 Response response = verifyClient.retrieveGraph(g.getId());
412 String responseString = response.readEntity(String.class);
414 System.out.println("Response");
415 System.out.println(responseString);
416 Graph graph = new ObjectMapper().readValue(responseString, Graph.class);
417 System.out.println("Read graph " + graph.getId());
418 System.out.println(response.getStatus());
421 Graph graph = graphs.get("budapest_sat.json");
422 System.out.println("graphId set to " + graph.getId());
423 System.out.println("Getting reachability from 'user1' to 'websever' in 'budapest' graph (expecting SAT)...");
424 Verification verification = verifyClient.getReachability(graph.getId(), "user1", "webserver");
425 System.out.println(verification.getResult());
427 graph = graphs.get("budapest_unsat.json");
428 System.out.println("graphId set to " + graph.getId());
429 System.out.println("Getting reachability from 'user1' to 'websever' in 'budapest' graph (expecting UNSAT)...");
430 verification = verifyClient.getReachability(graph.getId(), "user1", "webserver");
431 System.out.println(verification.getResult());