Add CLI in verigraph.
[parser.git] / verigraph / src / it / polito / verigraph / tosca / ToscaCLI.java
1 /*******************************************************************************\r
2  * Copyright (c) 2018 Politecnico di Torino and others.\r
3  *\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Apache License, Version 2.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.apache.org/licenses/LICENSE-2.0\r
8  *******************************************************************************/\r
9 \r
10 package it.polito.verigraph.tosca;\r
11 \r
12 import java.io.File;\r
13 import java.io.FileNotFoundException;\r
14 import java.io.IOException;\r
15 import java.io.InputStream;\r
16 import java.io.StringReader;\r
17 import java.io.StringWriter;\r
18 import java.util.ArrayList;\r
19 import java.util.List;\r
20 import java.util.NoSuchElementException;\r
21 import java.util.Scanner;\r
22 import java.util.regex.Pattern;\r
23 \r
24 import javax.ws.rs.ProcessingException;\r
25 import javax.ws.rs.client.Client;\r
26 import javax.ws.rs.client.ClientBuilder;\r
27 import javax.ws.rs.client.Entity;\r
28 import javax.ws.rs.client.Invocation.Builder;\r
29 import javax.ws.rs.client.WebTarget;\r
30 import javax.ws.rs.core.MediaType;\r
31 import javax.ws.rs.core.Response;\r
32 import javax.xml.bind.JAXBContext;\r
33 import javax.xml.bind.JAXBException;\r
34 import javax.xml.bind.Marshaller;\r
35 import javax.xml.transform.OutputKeys;\r
36 import javax.xml.transform.Source;\r
37 import javax.xml.transform.Transformer;\r
38 import javax.xml.transform.TransformerFactory;\r
39 import javax.xml.transform.stream.StreamResult;\r
40 import javax.xml.transform.stream.StreamSource;\r
41 \r
42 import com.fasterxml.jackson.annotation.JsonInclude;\r
43 import com.fasterxml.jackson.core.JsonProcessingException;\r
44 import com.fasterxml.jackson.databind.ObjectMapper;\r
45 import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;\r
46 import com.sun.research.ws.wadl.ObjectFactory;\r
47 \r
48 import it.polito.tosca.jaxb.Configuration;\r
49 import it.polito.tosca.jaxb.Definitions;\r
50 import it.polito.tosca.jaxb.TDefinitions;\r
51 import it.polito.verigraph.grpc.GraphGrpc;\r
52 import it.polito.verigraph.grpc.TopologyTemplateGrpc;\r
53 import it.polito.verigraph.grpc.ToscaPolicy;\r
54 import it.polito.verigraph.grpc.client.ToscaClient;\r
55 import it.polito.verigraph.grpc.server.GrpcUtils;\r
56 import it.polito.verigraph.model.Graph;\r
57 import it.polito.verigraph.tosca.converter.grpc.GraphToGrpc;\r
58 import it.polito.verigraph.tosca.converter.grpc.GrpcToGraph;\r
59 import it.polito.verigraph.tosca.converter.grpc.GrpcToXml;\r
60 import it.polito.verigraph.tosca.converter.grpc.GrpcToYaml;\r
61 import it.polito.verigraph.tosca.converter.grpc.XmlToGrpc;\r
62 import it.polito.verigraph.tosca.converter.grpc.YamlToGrpc;\r
63 import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;\r
64 \r
65 \r
66 public class ToscaCLI {\r
67 \r
68     private static final String helper = "./README_CLI.txt";\r
69 \r
70     //Service parameters.\r
71     private String host;\r
72     private int port;\r
73 \r
74     //New media type for yaml rest request\r
75     private static final MediaType yamlMedia = new MediaType("application", "x-yaml");\r
76     private static final String defaultHost = "localhost";\r
77     private static final int defaultRestPort = 8080;\r
78     private static final int defaultGrpcPort = 50051;\r
79 \r
80     //Input validation patterns\r
81     private static final Pattern yamlSource = Pattern.compile(".*\\.yaml$");\r
82     private static final Pattern xmlSource = Pattern.compile(".*\\.xml");\r
83     private static final Pattern jsonSource = Pattern.compile(".*\\.json$");\r
84     private static final Pattern configOpt = Pattern.compile("-use|-format|-port|-host", Pattern.CASE_INSENSITIVE);\r
85     private static final Pattern useOpt = Pattern.compile("grpc|rest", Pattern.CASE_INSENSITIVE);\r
86     private static final Pattern formatOpt = Pattern.compile("yaml|json|xml", Pattern.CASE_INSENSITIVE);\r
87     private static final Pattern policies = Pattern.compile("reachability|isolation|traversal", Pattern.CASE_INSENSITIVE);\r
88 \r
89     //Configuration parameters\r
90     private Boolean useRest;\r
91     private String mediatype;\r
92     private Client restClient;\r
93     private ToscaClient grpcClient;\r
94 \r
95     public ToscaCLI(){\r
96         //Variables representing the client environment\r
97         this.useRest = true;\r
98         this.port = defaultRestPort;\r
99         this.host = defaultHost;\r
100         this.mediatype = MediaType.APPLICATION_XML;\r
101         this.restClient = null;\r
102         this.grpcClient = null;\r
103     }\r
104 \r
105 \r
106     public static void main(String[] args) {\r
107         ToscaCLI myclient = new ToscaCLI();\r
108         try {\r
109             myclient.clientStart();\r
110         } catch (Exception e) {\r
111             System.out.println("-- Unexpected error, service closing.");\r
112         }\r
113         return;\r
114     }\r
115 \r
116     //Build base Uri for REST service\r
117     private String buildBaseUri() {\r
118         return "http://" + this.host + ":" + String.valueOf(this.port) + "/verigraph/api/graphs";\r
119     }\r
120 \r
121     //Function iterating getting user commands.\r
122     public void clientStart(){\r
123         System.out.println("++ Welcome to Verigraph Verification Service...");\r
124         System.out.println("++ Type HELP for instructions on client use...");\r
125 \r
126         Scanner reader = null;\r
127         InputStream input = System.in;\r
128         Scanner scan = new Scanner(System.in);\r
129         String commandline;\r
130 \r
131         while(true) {\r
132             System.out.print("++ Please insert command : ");\r
133             try{\r
134 \r
135                 while(input.available()!=0) input.skip(input.available());\r
136                 commandline = scan.nextLine();\r
137                 reader = new Scanner(commandline);\r
138 \r
139                 switch (reader.next().toUpperCase()) {\r
140                 case "GETALL":\r
141                     if(useRest) this.restGetAll(reader);\r
142                     else this.grpcGetAll(reader);\r
143                     break;\r
144                 case "GET":\r
145                     if(useRest) this.restGet(reader);\r
146                     else this.grpcGet(reader);\r
147                     break;\r
148                 case "CREATE":\r
149                     if(useRest) this.restCreate(reader);\r
150                     else this.grpcCreate(reader);\r
151                     break;\r
152                 case "DELETE":\r
153                     if(useRest) this.restDelete(reader);\r
154                     else grpcDelete(reader);\r
155                     break;\r
156                 case "UPDATE":\r
157                     if(useRest) this.restUpdate(reader);\r
158                     else this.grpcUpdate(reader);\r
159                     break;\r
160                 case "VERIFY":\r
161                     if(useRest) this.restVerify(reader);\r
162                     else this.grpcVerify(reader);\r
163                     break;\r
164                 case "HELP":\r
165                     this.printHelper();\r
166                     break;\r
167                 case "CONFIGURE":\r
168                     this.setConfig(reader);\r
169                     break;\r
170                 case "EXIT":\r
171                     System.out.println("++ Client closing...");\r
172                     scan.close();\r
173                     input.close();\r
174                     reader.close();\r
175                     if(grpcClient != null) this.grpcClient.shutdown();\r
176                     if(restClient != null) this.restClient.close();\r
177                     System.out.println("++ Goodbye!");\r
178                     System.exit(0);\r
179                     break;\r
180                 default:\r
181                     System.out.println("-- Unknown or bad formed command, type HELP to show commands documentation.");\r
182                     break;\r
183                 }\r
184 \r
185             }catch(NoSuchElementException ex) {\r
186                 System.err.println("-- Unrecognized or incorrect command,"\r
187                         + " type help to know how to use the client...");\r
188                 continue;\r
189             }catch(IOException | InterruptedException ex){\r
190                 handleError(ex);\r
191             }finally {\r
192                 reader.close();\r
193             }\r
194         }\r
195 \r
196     }\r
197 \r
198 \r
199     public void printHelper() {\r
200         Scanner filereader = null;\r
201         try {\r
202             File inputfile = new File(helper);\r
203             filereader = new Scanner(inputfile).useDelimiter("\\Z");\r
204             String content = filereader.next();\r
205             if (filereader.ioException() != null) {\r
206                 throw new IOException(filereader.ioException());\r
207             }\r
208             if(content != null) System.out.println(content);\r
209         } catch (IOException e) {\r
210             handleError(e);\r
211         }finally {\r
212             if(filereader != null) filereader.close();\r
213         }\r
214 \r
215     }\r
216 \r
217     public void setConfig(Scanner reader) throws InterruptedException {\r
218         if(!reader.hasNext(configOpt)) {\r
219             System.out.println("-- No or bad formed configuration options provided.");\r
220             return;\r
221         }\r
222         while(reader.hasNext(configOpt)) {\r
223             switch(reader.next().toLowerCase()) {\r
224             case "-use":\r
225                 if(reader.hasNext(useOpt)) {\r
226                     if(reader.next().toLowerCase().equals("rest")) {\r
227                         if(grpcClient != null) {\r
228                             grpcClient.shutdown();\r
229                             grpcClient = null;\r
230                         }\r
231                         this.port = defaultRestPort;\r
232                         restClient = ClientBuilder.newClient();\r
233                         useRest = true;\r
234                     }\r
235                     else {\r
236                         if(restClient != null) {\r
237                             restClient.close();\r
238                             restClient = null;\r
239                         }\r
240                         this.port = defaultGrpcPort;\r
241                         grpcClient = new ToscaClient(host, port);\r
242                         useRest = false;\r
243                     }\r
244                 }else {\r
245                     System.out.println("-- Unrecognized values for option -use, accepted values are: rest, grpc.");\r
246                 }\r
247                 break;\r
248             case "-format":\r
249                 if(reader.hasNext(formatOpt)) {\r
250                     String command = reader.next();\r
251                     if(command.toLowerCase().equals("json")) mediatype = MediaType.APPLICATION_JSON;\r
252                     else if(command.toLowerCase().equals("xml")) mediatype = MediaType.APPLICATION_XML;\r
253                     else if(command.toLowerCase().equals("yaml")) mediatype = "application/x-yaml";\r
254                 }else {\r
255                     System.out.println("-- Unrecognized values for option -format, accepted formats are: json, xml, yaml.");\r
256                 }\r
257                 break;\r
258             case "-host":\r
259                 if(reader.hasNext()) {\r
260                     this.host = reader.next();\r
261                     if(grpcClient != null) {\r
262                         grpcClient.shutdown();\r
263                         grpcClient = new ToscaClient(host, port);\r
264                         System.out.println("++ Host configuration changed restarting grpc client...");\r
265                     }\r
266                 }\r
267                 else {\r
268                     System.out.println("-- Provide a valid hostname.");\r
269                 }\r
270                 break;\r
271             case "-port":\r
272                 if(reader.hasNextInt()) {\r
273                     int newvalue = reader.nextInt();\r
274                     if(0 > newvalue || 65535 < newvalue) {\r
275                         System.out.println("-- The provided port number is not valid, port has not been modified.");\r
276                     }else {\r
277                         this.port = newvalue;\r
278                         if(grpcClient != null) {\r
279                             grpcClient.shutdown();\r
280                             grpcClient = new ToscaClient(host, port);\r
281                             System.out.println("++ Port configuration changed restarting grpc client...");\r
282                         }\r
283                     }\r
284                 }\r
285                 else {\r
286                     System.out.println("-- Provide a port as an integer.");\r
287                 }\r
288                 break;\r
289             default:\r
290                 System.out.println("-- Unrecognized option!");\r
291             }\r
292         }\r
293 \r
294     }\r
295 \r
296     //Utility function used only to print exception message\r
297     public void handleError(Exception e) {\r
298         String errMsg = e.getMessage();\r
299         if(errMsg == null) {\r
300             System.out.println("-- Error: unexpected error occurred.");\r
301         }else {\r
302             System.out.println("-- Error: " + errMsg);\r
303         }\r
304         return;\r
305     }\r
306 \r
307 \r
308     // RESTful service interface CRUD and Verify functions\r
309     public void restGetAll(Scanner reader) {\r
310         try {\r
311             // Build a new client if it does not exist\r
312             if (restClient == null)\r
313                 restClient = ClientBuilder.newClient();\r
314 \r
315             // targeting the graphs resource\r
316             WebTarget target = restClient.target(this.buildBaseUri());\r
317 \r
318             // Performing the request and reading the response\r
319             Response res = target.request(mediatype).get();\r
320             this.readResponseRest("GETALL", res);\r
321 \r
322         }catch(ProcessingException e) {\r
323             System.out.println("-- Error: the provided host address is not valid.");\r
324         }catch (Exception e) {\r
325             handleError(e);\r
326         }\r
327         return;\r
328     }\r
329 \r
330 \r
331     public void restGet(Scanner reader) {\r
332 \r
333         try {\r
334             // Build a new client if it does not exist\r
335             if (restClient == null)\r
336                 restClient = ClientBuilder.newClient();\r
337 \r
338             if (!reader.hasNextLong()) {\r
339                 System.out.println("-- Provide the integer Id for the requested graph.");\r
340                 return;\r
341             }\r
342 \r
343             // Targeting the specified graph resource\r
344             WebTarget target = restClient.target(this.buildBaseUri() + "/" + String.valueOf(reader.nextLong()));\r
345 \r
346             // Performing the request and reading the response\r
347             Response res = target.request(mediatype).get();\r
348             this.readResponseRest("GET", res);\r
349 \r
350         }catch(ProcessingException e) {\r
351             System.out.println("-- Error: the provided host address is not valid.");\r
352         } catch (Exception e) {\r
353             handleError(e);\r
354         }\r
355 \r
356     }\r
357 \r
358 \r
359 \r
360     public void restCreate(Scanner reader) {\r
361 \r
362         try {\r
363             // Getting file content\r
364             String content = readFile(reader);\r
365             if (content == null) {\r
366                 System.out.println("-- The required operation can't be performed.");\r
367                 return;\r
368             }\r
369 \r
370             // Build a new client if it does not exist\r
371             if (restClient == null)\r
372                 restClient = ClientBuilder.newClient();\r
373 \r
374             // Targeting the resource\r
375             WebTarget target = restClient.target(this.buildBaseUri());\r
376 \r
377             // Performing the request and reading the response\r
378             Builder mypost = target.request(mediatype);\r
379             Response res = null;\r
380             switch (mediatype) {\r
381             case MediaType.APPLICATION_JSON:\r
382                 res = mypost.post(Entity.json(content));\r
383                 break;\r
384             case MediaType.APPLICATION_XML:\r
385                 res = mypost.post(Entity.xml(content));\r
386                 break;\r
387             case "application/x-yaml":\r
388                 res = mypost.post(Entity.entity(content, yamlMedia));\r
389                 break;\r
390             }\r
391 \r
392             this.readResponseRest("CREATE", res);\r
393         }catch(ProcessingException e) {\r
394             System.out.println("-- Error: the provided host address is not valid.");\r
395         } catch (Exception e) {\r
396             handleError(e);\r
397         }\r
398 \r
399         return;\r
400     }\r
401 \r
402 \r
403 \r
404     public void restDelete(Scanner reader) {\r
405         try {\r
406             // Build a new client if it does not exist\r
407             if (restClient == null)\r
408                 restClient = ClientBuilder.newClient();\r
409 \r
410             if (!reader.hasNextLong()) {\r
411                 System.out.println("-- Provide the integer Id of the graph you want to delete.");\r
412                 return;\r
413             }\r
414 \r
415             // Targeting the specified graph resource\r
416             WebTarget target = restClient.target(this.buildBaseUri() + "/" + String.valueOf(reader.nextLong()));\r
417 \r
418             // Performing the request and reading the response\r
419             Response res = target.request(mediatype).delete();\r
420             this.readResponseRest("DELETE", res);\r
421         }catch(ProcessingException e) {\r
422             System.out.println("-- Error: the provided host address is not valid.");\r
423         } catch (Exception e) {\r
424             handleError(e);\r
425         }\r
426 \r
427         return;\r
428     }\r
429 \r
430 \r
431     public  void restUpdate(Scanner reader) {\r
432         try {\r
433 \r
434             //Getting the target graph\r
435             if(!reader.hasNextLong()) {\r
436                 System.out.println("-- Please provide a valid id for the graph to be update");\r
437                 return;\r
438             }\r
439 \r
440             // Build a new client if it does not exist\r
441             if (restClient == null)\r
442                 restClient = ClientBuilder.newClient();\r
443 \r
444             // Targeting the resource\r
445             WebTarget target = restClient.target(this.buildBaseUri() + "/" + reader.next());\r
446 \r
447             // Getting file content\r
448             String content = readFile(reader);\r
449             if (content == null) {\r
450                 System.out.println("-- The required operation can't be performed.");\r
451                 return;\r
452             }\r
453 \r
454             // Performing the request and reading the resonse\r
455             Builder myupdate = target.request(mediatype);\r
456             Response res = null;\r
457             switch (mediatype) {\r
458             case MediaType.APPLICATION_JSON:\r
459                 res = myupdate.put(Entity.json(content));\r
460                 break;\r
461             case MediaType.APPLICATION_XML:\r
462                 res = myupdate.put(Entity.xml(content));\r
463                 break;\r
464             case "application/x-yaml":\r
465                 res = myupdate.put(Entity.entity(content, yamlMedia));\r
466                 break;\r
467             }\r
468 \r
469             this.readResponseRest("UPDATE", res);\r
470 \r
471         }catch(ProcessingException e) {\r
472             System.out.println("-- Error: the provided host address is not valid.");\r
473         } catch (Exception e) {\r
474             handleError(e);\r
475         }\r
476 \r
477     }\r
478 \r
479 \r
480     public  void restVerify(Scanner reader) {\r
481         String whichpolicy = null;\r
482         String graphId, source, destination, middlebox = null;\r
483 \r
484         try {\r
485             if(!reader.hasNextLong()) {\r
486                 System.out.println("-- Provide the graph on which you want to perform verification.");\r
487                 return;\r
488             }\r
489             graphId = reader.next();\r
490 \r
491             if (!reader.hasNext(policies)) {\r
492                 System.out.println("-- Provide the requested type of verfication.");\r
493                 return;\r
494             }\r
495             whichpolicy = reader.next().toLowerCase();\r
496 \r
497             try {\r
498                 source = reader.next();\r
499                 destination = reader.next();\r
500                 if(!whichpolicy.equals("reachability")) {\r
501                     middlebox = reader.next();\r
502                 }\r
503             }catch(NoSuchElementException ex) {\r
504                 System.out.println("-- Wrong or missing verification parameters.");\r
505                 return;\r
506             }\r
507 \r
508             // Build a new client if it does not exist\r
509             if (restClient == null)\r
510                 restClient = ClientBuilder.newClient();\r
511 \r
512             // Targeting the resource\r
513             WebTarget target = restClient.target(this.buildBaseUri() + "/" + graphId + "/policy")\r
514                     .queryParam("source", source)\r
515                     .queryParam("destination", destination)\r
516                     .queryParam("type", whichpolicy);\r
517             if(!whichpolicy.equals("reachability")) {\r
518                 target = target.queryParam("middlebox", middlebox);\r
519             }\r
520 \r
521             Response res = target.request(mediatype).get();\r
522             this.readResponseRest("VERIFY", res);\r
523         }catch(ProcessingException e) {\r
524             System.out.println("-- Error: the provided host address is not valid.");\r
525         } catch (Exception e) {\r
526             handleError(e);\r
527         }\r
528 \r
529     }\r
530 \r
531     //gRPC service interface CRUD and Verify functions\r
532     public void grpcGetAll(Scanner reader) {\r
533 \r
534         try {\r
535             if(grpcClient == null)\r
536                 grpcClient = new ToscaClient(host, port);\r
537 \r
538             //Added for backward compatibility with JSON grpc\r
539             if(mediatype == MediaType.APPLICATION_JSON) {\r
540                 List<GraphGrpc> receivedGraphsGrpc = grpcClient.getGraphs();\r
541 \r
542                 if(receivedGraphsGrpc == null) {\r
543                     System.out.println("-- GET Failed : was not possible to perform the required operations.");\r
544                     return;\r
545                 }\r
546                 else if(receivedGraphsGrpc.isEmpty()) {\r
547                     System.out.println("++ GET Success no graph was returned.");\r
548                     return;\r
549                 }\r
550 \r
551                 List<Graph> receivedGraphs = new ArrayList<Graph>();\r
552                 for(GraphGrpc curr : receivedGraphsGrpc) {\r
553                     receivedGraphs.add(GrpcUtils.deriveGraph(curr));\r
554                 }\r
555                 this.marshallToJson(receivedGraphs);\r
556                 return;\r
557             }\r
558 \r
559             //Code for the Tosca compliant implementation\r
560             List<TopologyTemplateGrpc> templates;\r
561             templates =  grpcClient.getTopologyTemplates();\r
562 \r
563             if(templates == null) {\r
564                 System.out.println("-- GET Failed : was not possible to perform the required operations.");\r
565                 return;\r
566             }\r
567             else if(templates.isEmpty()) {\r
568                 System.out.println("++ GET Success no graph was returned.");\r
569                 return;\r
570             }\r
571 \r
572             switch(mediatype) {\r
573             case MediaType.APPLICATION_XML:\r
574                 List<Definitions> receivedDefs = new ArrayList<Definitions>();\r
575                 for(TopologyTemplateGrpc curr : templates) {\r
576                     receivedDefs.add(GrpcToXml.mapGraph(curr));\r
577                 }\r
578                 this.marshallToXml(receivedDefs);\r
579                 break;\r
580 \r
581             case "application/x-yaml":\r
582                 List<ServiceTemplateYaml> receivedTempls = new ArrayList<ServiceTemplateYaml>();\r
583                 for(TopologyTemplateGrpc curr : templates) {\r
584                     receivedTempls.add(GrpcToYaml.mapGraphYaml(curr));\r
585                 }\r
586                 this.marshallToYaml(receivedTempls);\r
587                 break;\r
588 \r
589             }\r
590         } catch (Exception e) {\r
591             handleError(e);\r
592         }\r
593 \r
594     }\r
595 \r
596 \r
597     public void grpcGet(Scanner reader) {\r
598 \r
599         try {\r
600             if (grpcClient == null)\r
601                 grpcClient = new ToscaClient(host, port);\r
602 \r
603             if (!reader.hasNextLong()) {\r
604                 System.out.println("-- Provide the integer Id for the requested graph.");\r
605                 return;\r
606             }\r
607 \r
608             //Added for backward compatibility with JSON grpc\r
609             if(mediatype == MediaType.APPLICATION_JSON) {\r
610                 GraphGrpc graph = grpcClient.getGraph(reader.nextLong());\r
611                 if(graph == null || !graph.getErrorMessage().equals(""));\r
612                 List<Graph> receivedGraphs = new ArrayList<Graph>();\r
613                 receivedGraphs.add(GrpcUtils.deriveGraph(graph));\r
614                 this.marshallToJson(receivedGraphs);\r
615                 return;\r
616             }\r
617 \r
618             //Code for Tosca compliant implementation\r
619             TopologyTemplateGrpc templ = grpcClient.getTopologyTemplate(reader.next());\r
620             if(templ == null || !templ.getErrorMessage().equals("")) {\r
621                 return;\r
622             }\r
623             switch(mediatype) {\r
624             //      case MediaType.APPLICATION_JSON:\r
625             //        Graph obt = GrpcToGraph.deriveGraph(templ);\r
626             //        List<Graph> list = new ArrayList<Graph>();\r
627             //        list.add(obt);\r
628             //        marshallToJson(list);\r
629             //        break;\r
630             case MediaType.APPLICATION_XML:\r
631                 List<Definitions> receivedDefs = new ArrayList<Definitions>();\r
632                 receivedDefs.add(GrpcToXml.mapGraph(templ));\r
633                 this.marshallToXml(receivedDefs);\r
634                 break;\r
635 \r
636             case "application/x-yaml":\r
637                 List<ServiceTemplateYaml> receivedTempls = new ArrayList<ServiceTemplateYaml>();\r
638                 receivedTempls.add(GrpcToYaml.mapGraphYaml(templ));\r
639                 this.marshallToYaml(receivedTempls);\r
640                 break;\r
641             }\r
642 \r
643         } catch (Exception e) {\r
644             handleError(e);\r
645         }\r
646     }\r
647 \r
648     public void grpcCreate(Scanner reader) {\r
649         try {\r
650             if (grpcClient == null)\r
651                 grpcClient = new ToscaClient(host, port);\r
652 \r
653             switch (mediatype) {\r
654             case MediaType.APPLICATION_JSON:\r
655                 if(reader.hasNext(jsonSource)) {\r
656                     ObjectMapper mapper = new ObjectMapper();\r
657                     Graph modelGraph = mapper.readValue(readFile(reader), Graph.class);\r
658                     GraphGrpc graph = GrpcUtils.obtainGraph(modelGraph);\r
659                     grpcClient.createGraph(graph);\r
660                 }else {\r
661                     System.out.println("-- The provided file is not compatible with the current configuration [json].");\r
662                     return;\r
663                 }\r
664                 break;\r
665             case MediaType.APPLICATION_XML:\r
666                 if (reader.hasNext(xmlSource)) {\r
667                     grpcClient.createTopologyTemplate(XmlToGrpc.obtainTopologyTemplateGrpc(reader.next()));\r
668                 } else {\r
669                     System.out.println("-- The provided file is not compatible with the current configuration [xml].");\r
670                     return;\r
671                 }\r
672                 break;\r
673 \r
674             case "application/x-yaml":\r
675                 if (reader.hasNext(yamlSource)) {\r
676                     grpcClient.createTopologyTemplate(YamlToGrpc.obtainTopologyTemplateGrpc(reader.next()));\r
677                 } else {\r
678                     System.out.println("-- The provided file is not compatible with the current configuration [yaml].");\r
679                     return;\r
680                 }\r
681                 break;\r
682             }\r
683 \r
684         } catch (JAXBException je) {\r
685             System.out.println("-- Error while parsing xml : " + je.getMessage());\r
686         } catch (IOException ie) {\r
687             System.out.println("-- Error reading the file : " + ie.getMessage());\r
688         } catch(Exception e) {\r
689             handleError(e);\r
690         }\r
691 \r
692         return;\r
693     }\r
694 \r
695 \r
696     public  void grpcDelete(Scanner reader) {\r
697 \r
698         try {\r
699             if (grpcClient == null)\r
700                 grpcClient = new ToscaClient(host, port);\r
701 \r
702             if (!reader.hasNextLong()) {\r
703                 System.out.println("-- Provide the integer Id of the graph you want to delete.");\r
704                 return;\r
705             }\r
706 \r
707             grpcClient.deleteTopologyTemplate(reader.next());\r
708 \r
709         } catch (Exception e) {\r
710             handleError(e);\r
711         }\r
712 \r
713         return;\r
714     }\r
715 \r
716 \r
717     public  void grpcUpdate(Scanner reader) {\r
718         try {\r
719             if (grpcClient == null)\r
720                 grpcClient = new ToscaClient(host, port);\r
721 \r
722             //Checking if user ha provided the id of the graph to be updated and retrieving it\r
723             if(!reader.hasNextLong()) {\r
724                 System.out.println("-- Please provide a valid id for the graph to be update");\r
725                 return;\r
726             }\r
727             String id = reader.next();\r
728 \r
729             //Reading the file and performing the request according to current configuration\r
730             switch (mediatype) {\r
731             case MediaType.APPLICATION_JSON:\r
732                 if(reader.hasNext(jsonSource)) {\r
733                     ObjectMapper mapper = new ObjectMapper();\r
734                     Graph modelGraph = mapper.readValue(readFile(reader), Graph.class);\r
735                     GraphGrpc graph = GrpcUtils.obtainGraph(modelGraph);\r
736                     grpcClient.updateGraph(new Long(id), graph);\r
737                 }else {\r
738                     System.out.println("-- The provided file is not compatible with the current configuration [json].");\r
739                     return;\r
740                 }\r
741                 break;\r
742             case MediaType.APPLICATION_XML:\r
743                 if (reader.hasNext(xmlSource)) {\r
744                     grpcClient.updateTopologyTemplate(XmlToGrpc.obtainTopologyTemplateGrpc(reader.next()), id);\r
745                 } else {\r
746                     System.out.println("-- The provided file is not compatible with the current configuration.");\r
747                     return;\r
748                 }\r
749                 break;\r
750 \r
751             case "application/x-yaml":\r
752                 if (reader.hasNext(yamlSource)) {\r
753                     grpcClient.updateTopologyTemplate(YamlToGrpc.obtainTopologyTemplateGrpc(reader.next()), id);\r
754                 } else {\r
755                     System.out.println("-- The provided file is not compatible with the current configuration.");\r
756                     return;\r
757                 }\r
758                 break;\r
759             }\r
760         } catch (JAXBException je) {\r
761             System.out.println("-- Error while parsing xml : " + je.getMessage());\r
762         } catch (IOException ie) {\r
763             System.out.println("-- Error reading the file : " + ie.getMessage());\r
764         } catch(Exception e) {\r
765             handleError(e);\r
766         }\r
767     }\r
768 \r
769 \r
770     public  void grpcVerify(Scanner reader) {\r
771         ToscaPolicy.Builder policyBuilder = ToscaPolicy.newBuilder();\r
772         String graphId, whichPolicy, source, destination, middlebox = null;\r
773 \r
774         try {\r
775             if(!reader.hasNextLong()) {\r
776                 System.out.println("-- Provide the graph on which you want to perform verification.");\r
777                 return;\r
778             }\r
779             graphId = reader.next();\r
780 \r
781             if (!reader.hasNext(policies)) {\r
782                 System.out.println("-- Provide the requested type of verfication.");\r
783                 return;\r
784             }\r
785             whichPolicy = reader.next().toLowerCase();\r
786 \r
787             try {\r
788                 source = reader.next();\r
789                 destination = reader.next();\r
790                 if(!whichPolicy.equals("reachability")) {\r
791                     middlebox = reader.next();\r
792                 }\r
793             }catch(NoSuchElementException ex) {\r
794                 System.out.println("-- Wrong or missing verification parameters.");\r
795                 return;\r
796             }\r
797 \r
798             policyBuilder.setIdTopologyTemplate(graphId);\r
799             policyBuilder.setDestination(destination);\r
800             policyBuilder.setSource(source);\r
801             switch(whichPolicy) {\r
802             case "reachability":\r
803                 policyBuilder.setType(ToscaPolicy.PolicyType.forNumber(0));\r
804                 break;\r
805             case "isolation":\r
806                 policyBuilder.setType(ToscaPolicy.PolicyType.forNumber(1));\r
807                 policyBuilder.setMiddlebox(middlebox);\r
808                 break;\r
809             case "traversal":\r
810                 policyBuilder.setType(ToscaPolicy.PolicyType.forNumber(2));\r
811                 policyBuilder.setMiddlebox(middlebox);\r
812                 break;\r
813             }\r
814 \r
815             if (grpcClient == null)\r
816                 grpcClient = new ToscaClient(host, port);\r
817 \r
818             //Sending verification request\r
819             grpcClient.verifyPolicy(policyBuilder.build());\r
820 \r
821         } catch (Exception e) {\r
822             handleError(e);\r
823         }\r
824 \r
825         return;\r
826     }\r
827 \r
828 \r
829     public void readResponseRest(String responseOf, Response res) {\r
830         switch(responseOf) {\r
831         case "GETALL":\r
832             switch (res.getStatus()) {\r
833             case 200:\r
834                 System.out.println("++ GET success :");\r
835                 break;\r
836             case 500:\r
837                 System.out.println("-- GET failed : internal server error.");\r
838                 break;\r
839             default:\r
840                 System.out.println("** Unexpected response");\r
841                 break;\r
842             }\r
843             break;\r
844 \r
845         case "GET":\r
846             switch (res.getStatus()) {\r
847             case 200:\r
848                 System.out.println("++ GET success :");\r
849                 break;\r
850             case 404:\r
851                 System.out.println("-- GET failed : graph not found.");\r
852                 break;\r
853             case 500:\r
854                 System.out.println("-- GET failed : internal server error.");\r
855                 break;\r
856             default:\r
857                 System.out.println("** Unexpected response **");\r
858                 break;\r
859             }\r
860             break;\r
861 \r
862         case "CREATE":\r
863             switch (res.getStatus()) {\r
864             case 201:\r
865                 System.out.println("++ POST success : graph created.");\r
866                 break;\r
867             case 400:\r
868                 System.out.println("-- POST failed : bad request.");\r
869                 break;\r
870             case 500:\r
871                 System.out.println("-- POST failed : internal server error.");\r
872                 break;\r
873             default:\r
874                 System.out.println("** Unexpected response **");\r
875                 break;\r
876             }\r
877             break;\r
878         case "DELETE":\r
879             switch (res.getStatus()) {\r
880             case 204:\r
881                 System.out.println("++ DELETE success : graph deleted.");\r
882                 break;\r
883             case 403:\r
884                 System.out.println("-- DELETE failed : invalid graph ID.");\r
885                 break;\r
886             case 404:\r
887                 System.out.println("-- DELETE failed : invalid graph id.");\r
888                 break;\r
889             case 500:\r
890                 System.out.println("-- DELETE failed : internal server error.");\r
891                 break;\r
892             default:\r
893                 System.out.println("** Unexpected response **");\r
894                 break;\r
895             }\r
896             break;\r
897         case "UPDATE":\r
898             switch (res.getStatus()) {\r
899             case 200:\r
900                 System.out.println("++ PUT success : graph correctly updated.");\r
901                 break;\r
902             case 400:\r
903                 System.out.println("-- PUT failed : invalid graph object.");\r
904                 break;\r
905             case 403:\r
906                 System.out.println("-- PUT failed : invalid graph ID.");\r
907                 break;\r
908             case 404:\r
909                 System.out.println("-- PUT failed : graph not found.");\r
910                 break;\r
911             case 500:\r
912                 System.out.println("-- PUT failed : internal server error.");\r
913                 break;\r
914             default:\r
915                 System.out.println("** Unexpected response **");\r
916                 break;\r
917             }\r
918             break;\r
919 \r
920         default:\r
921 \r
922         }\r
923 \r
924         //In case of errors we do not read the message body\r
925         if(res.hasEntity() && res.getStatus() <= 300) {\r
926             String responseBody = prettyFormat(res.readEntity(String.class));\r
927             if(responseBody != null) System.out.println(responseBody);\r
928         }\r
929         else {\r
930             System.out.println("++ No content in the message body");\r
931         }\r
932 \r
933         return;\r
934     }\r
935 \r
936 \r
937     public void marshallToXml(List<Definitions> defs) {\r
938         try {\r
939             JAXBContext jc = JAXBContext.newInstance(ObjectFactory.class, TDefinitions.class, Configuration.class);\r
940             Marshaller m = jc.createMarshaller();\r
941             m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);\r
942             for (Definitions def : defs) {\r
943                 // To be tested, in case of problems def must be converted to a JAXBElement\r
944                 m.marshal(def, System.out);\r
945                 System.out.println("\n");\r
946             }\r
947 \r
948         } catch (JAXBException je) {\r
949             System.out.println("-- Error while marshalling : " + je.getMessage());\r
950         }\r
951         return;\r
952     }\r
953 \r
954     public void marshallToYaml(List<ServiceTemplateYaml> templates) {\r
955         try {\r
956             YAMLMapper mapper = new YAMLMapper();\r
957             mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);\r
958             for (ServiceTemplateYaml templ : templates) {\r
959                 System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(templ));\r
960                 System.out.println("\n");\r
961             }\r
962 \r
963         } catch (JsonProcessingException je) {\r
964             System.out.println("-- Error while marshalling : " + je.getMessage());\r
965 \r
966         }\r
967         return;\r
968     }\r
969 \r
970     public void marshallToJson(List<Graph> templates) {\r
971         try {\r
972             ObjectMapper mapper = new ObjectMapper();\r
973             //mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);\r
974             for (Graph templ : templates) {\r
975                 System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(templ));\r
976                 System.out.println("\n");\r
977             }\r
978 \r
979         } catch (JsonProcessingException je) {\r
980             System.out.println("-- Error while marshalling : " + je.getMessage());\r
981 \r
982         }\r
983         return;\r
984     }\r
985 \r
986 \r
987     // Reads the whole file into a string and performs a minimum validation on file type\r
988     public String readFile(Scanner reader) {\r
989 \r
990         String content = null;\r
991         Scanner filereader = null;\r
992         if ((mediatype.equals("application/x-yaml") && reader.hasNext(yamlSource))\r
993                 || (mediatype.equals(MediaType.APPLICATION_XML) && reader.hasNext(xmlSource))\r
994                 || (mediatype.equals(MediaType.APPLICATION_JSON) && reader.hasNext(jsonSource))) {\r
995             try {\r
996                 File inputfile = new File(reader.next());\r
997                 filereader = new Scanner(inputfile).useDelimiter("\\Z");\r
998                 content = filereader.next();\r
999                 if (filereader.ioException() != null) {\r
1000                     throw new IOException(filereader.ioException());\r
1001                 } else {\r
1002                     System.out.println("++ File correctly read.");\r
1003                 }\r
1004             } catch (FileNotFoundException ex) {\r
1005                 System.out.println("-- Error : the provided file does not exist!");\r
1006             }catch (IOException ex) {\r
1007                 System.out.println("-- Error : an error occurred reading the input file!");\r
1008             }catch (Exception e) {\r
1009                 handleError(e);\r
1010             }finally {\r
1011                 if(filereader != null) filereader.close();\r
1012             }\r
1013 \r
1014         } else {\r
1015             System.out.println("-- Error : the file provided in input does not match with the current client configuration.");\r
1016         }\r
1017 \r
1018         return content;\r
1019     }\r
1020 \r
1021 \r
1022     public String prettyFormat(String input) {\r
1023         String formattedString = null;\r
1024 \r
1025         try {\r
1026             switch(mediatype) {\r
1027             case MediaType.APPLICATION_XML:\r
1028                 Source xmlInput = new StreamSource(new StringReader(input));\r
1029                 StringWriter stringWriter = new StringWriter();\r
1030                 StreamResult xmlOutput = new StreamResult(stringWriter);\r
1031                 TransformerFactory transformerFactory = TransformerFactory.newInstance();\r
1032                 transformerFactory.setAttribute("indent-number", 2);\r
1033                 Transformer transformer = transformerFactory.newTransformer();\r
1034                 transformer.setOutputProperty(OutputKeys.INDENT, "yes");\r
1035                 transformer.transform(xmlInput, xmlOutput);\r
1036                 formattedString = xmlOutput.getWriter().toString();\r
1037                 break;\r
1038             case MediaType.APPLICATION_JSON:\r
1039                 ObjectMapper mapper = new ObjectMapper();\r
1040                 Object jsonObj = mapper.readValue(input, Object.class);\r
1041                 formattedString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObj);\r
1042                 break;\r
1043             case "application/x-yaml":\r
1044                 formattedString = input;\r
1045                 break;\r
1046             }\r
1047         } catch (Exception e) {\r
1048             formattedString = e.getCause().toString();\r
1049         }\r
1050 \r
1051         return formattedString;\r
1052     }\r
1053 \r
1054 \r
1055 }\r