update verigraph
[parser.git] / verigraph / src / it / polito / verigraph / client / VerifyClient.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.client;
10
11 import java.io.File;
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;
18 import java.util.Map;
19
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;
28
29 import com.fasterxml.jackson.core.JsonParseException;
30 import com.fasterxml.jackson.databind.JsonMappingException;
31 import com.fasterxml.jackson.databind.ObjectMapper;
32
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;
38
39 public class VerifyClient {
40
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;
51
52     public VerifyClient(String address) {
53         
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");
65     }
66
67     public void checkResponse(Response response) throws VerifyClientException {
68         int status = response.getStatus();
69
70         // 400
71         if (status == Response.Status.BAD_REQUEST.getStatusCode()) {
72             try {
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);
78             }
79             catch (ProcessingException e) {
80                 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
81                         + e.getMessage());
82             }
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: "
85                         + e.getMessage());
86             }
87         }
88         // 403
89         if (status == Response.Status.FORBIDDEN.getStatusCode()) {
90             try {
91                 ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
92                 String message = errorMessage.getErrorMessage();
93                 throw new VerifyClientException("Forbidden: " + message);
94             }
95             catch (ProcessingException e) {
96                 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
97                         + e.getMessage());
98             }
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: "
101                         + e.getMessage());
102             }
103         }
104         // 404
105         if (status == Response.Status.NOT_FOUND.getStatusCode()) {
106             try {
107                 ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
108                 String message = errorMessage.getErrorMessage();
109                 throw new VerifyClientException("Not found: " + message);
110             }
111             catch (ProcessingException e) {
112                 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
113                         + e.getMessage());
114             }
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: "
117                         + e.getMessage());
118             }
119         }
120         // 500
121         if (status == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
122             try {
123                 ErrorMessage errorMessage = response.readEntity(ErrorMessage.class);
124                 String message = errorMessage.getErrorMessage();
125                 throw new VerifyClientException("Internal server error: " + message);
126             }
127             catch (ProcessingException e) {
128                 throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'ErrorMessage': "
129                         + e.getMessage());
130             }
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: "
133                         + e.getMessage());
134             }
135         }
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");
139     }
140
141     public Response createGraph(Graph graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
142         Response response = graphsTarget.request().post(Entity.json(graph));
143         checkResponse(response);
144         return response;
145     }
146
147     public Response createGraph(String graph) throws VerifyClientException, ResponseProcessingException, ProcessingException {
148         Response response = graphsTarget.request().post(Entity.entity(graph, "application/json"));
149         checkResponse(response);
150         return response;
151     }
152
153     public Response retrieveGraph(long graphId) throws VerifyClientException, ProcessingException {
154         Response response = graphTarget.resolveTemplate("graphId", graphId).request().get();
155         checkResponse(response);
156         return response;
157     }
158
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);
162         return response;
163     }
164
165     public Response deleteGraph(long graphId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
166         Response response = graphTarget.resolveTemplate("graphId", graphId).request().delete();
167         checkResponse(response);
168         return response;
169     }
170
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);
174         return response;
175     }
176
177     public Response retrieveNode(long graphId, long nodeId) throws VerifyClientException, ProcessingException {
178         Response response = nodeTarget.resolveTemplate("graphId", graphId)
179                 .resolveTemplate("nodeId", nodeId)
180                 .request()
181                 .get();
182         checkResponse(response);
183         return response;
184     }
185
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)
189                 .request()
190                 .put(Entity.json(node));
191         checkResponse(response);
192         return response;
193     }
194
195     public Response deleteNode(long graphId, long nodeId) throws VerifyClientException, ResponseProcessingException, ProcessingException {
196         Response response = nodeTarget.resolveTemplate("graphId", graphId)
197                 .resolveTemplate("nodeId", nodeId)
198                 .request()
199                 .delete();
200         checkResponse(response);
201         return response;
202     }
203
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)
207                 .request()
208                 .post(Entity.json(neighbour));
209         checkResponse(response);
210         return response;
211     }
212
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)
217                 .request()
218                 .get();
219         checkResponse(response);
220         return response;
221     }
222
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)
228                 .request()
229                 .put(Entity.json(neighbour));
230         checkResponse(response);
231         return response;
232     }
233
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)
238                 .request()
239                 .delete();
240         checkResponse(response);
241         return response;
242     }
243
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")
249                 .request()
250                 .get();
251         checkResponse(response);
252         try{
253             Verification verification = response.readEntity(Verification.class);
254             return verification;
255         }
256         catch (ProcessingException e) {
257             throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
258                     + e.getMessage());
259         }
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: "
262                     + e.getMessage());
263         }
264     }
265
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")
272                 .request()
273                 .get();
274         checkResponse(response);
275         try{
276             Verification verification = response.readEntity(Verification.class);
277             return verification;
278         }
279         catch (ProcessingException e) {
280             throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
281                     + e.getMessage());
282         }
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: "
285                     + e.getMessage());
286         }
287     }
288
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")
295                 .request()
296                 .get();
297         checkResponse(response);
298         try{
299             Verification verification = response.readEntity(Verification.class);
300             return verification;
301         }
302         catch (ProcessingException e) {
303             throw new VerifyClientException("the content of the message cannot be mapped to an entity of the 'Verification': "
304                     + e.getMessage());
305         }
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: "
308                     + e.getMessage());
309         }
310     }
311
312     @SuppressWarnings("unused")
313     private static String deserializeString(File file) throws IOException {
314         int len;
315         char[] chr = new char[4096];
316         final StringBuffer buffer = new StringBuffer();
317         final FileReader reader = new FileReader(file);
318         try {
319             while ((len = reader.read(chr)) > 0) {
320                 buffer.append(chr, 0, len);
321             }
322         }
323         finally {
324             reader.close();
325         }
326         return buffer.toString();
327     }
328
329     public List<File> getFiles() {
330         List<File> filesList = new ArrayList<File>();
331
332         String folderString = System.getProperty("folder");
333         File folder;
334         if (folderString == null)
335             folder = new File(System.getProperty("user.dir") + "/examples");
336         else
337             folder = new File(folderString);
338
339         System.out.println("Folder set to " + folder.getAbsolutePath());
340
341         File[] files = folder.listFiles(new FilenameFilter() {
342
343             @Override
344             public boolean accept(File dir, String name) {
345                 return name.endsWith(".json");
346             }
347         });
348
349         for (File f : files) {
350             filesList.add(f);
351         }
352
353         return filesList;
354     }
355
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());
363         }
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);
369         return response;
370     }
371
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());
381             }
382         }
383     }
384
385     public Map<String, Graph> addGraphsFromFiles(List<File> files)throws JsonParseException, JsonMappingException, IOException,
386     Exception {
387         Map<String, Graph> graphs = new HashMap<String, Graph>();
388
389         for (File f : files) {
390             Graph graph = addGraphFromFile(f);
391             graphs.put(f.getName(), graph);
392         }
393
394         for (Map.Entry<String, Graph> graph : graphs.entrySet()) {
395             System.out.println(graph.getKey() + " -> graph " + graph.getValue().getId());
396         }
397         System.out.println("Graphs added");
398
399         return graphs;
400     }
401
402     public static void main(String[] args) throws IOException, Exception {
403         System.out.println("Adding graphs");
404
405         VerifyClient verifyClient = new VerifyClient("http://localhost:8080/verigraph/api");
406
407         List<File> files = verifyClient.getFiles();
408         Map<String, Graph> graphs = verifyClient.addGraphsFromFiles(files);
409
410         for (Graph g : graphs.values()) {
411             Response response = verifyClient.retrieveGraph(g.getId());
412             String responseString = response.readEntity(String.class);
413
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());
419         }
420
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());
426
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());
432
433     }
434
435 }