Add CLI in verigraph.
[parser.git] / verigraph / src / it / polito / verigraph / tosca / converter / yaml / GraphToYaml.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 package it.polito.verigraph.tosca.converter.yaml;\r
10 \r
11 import java.io.IOException;\r
12 import java.util.HashMap;\r
13 import java.util.Map;\r
14 \r
15 import com.fasterxml.jackson.core.JsonParseException;\r
16 import com.fasterxml.jackson.databind.InjectableValues;\r
17 import com.fasterxml.jackson.databind.JsonMappingException;\r
18 import com.fasterxml.jackson.databind.JsonNode;\r
19 import com.fasterxml.jackson.databind.ObjectMapper;\r
20 import com.fasterxml.jackson.databind.module.SimpleModule;\r
21 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;\r
22 \r
23 import it.polito.neo4j.jaxb.FunctionalTypes;\r
24 import it.polito.verigraph.exception.BadRequestException;\r
25 import it.polito.verigraph.model.Graph;\r
26 import it.polito.verigraph.model.Neighbour;\r
27 import it.polito.verigraph.model.Node;\r
28 import it.polito.verigraph.tosca.deserializer.YamlConfigurationDeserializer;\r
29 import it.polito.verigraph.tosca.yaml.beans.AntispamConfigurationYaml;\r
30 import it.polito.verigraph.tosca.yaml.beans.AntispamNode;\r
31 import it.polito.verigraph.tosca.yaml.beans.CacheConfigurationYaml;\r
32 import it.polito.verigraph.tosca.yaml.beans.CacheNode;\r
33 import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;\r
34 import it.polito.verigraph.tosca.yaml.beans.DpiConfigurationYaml;\r
35 import it.polito.verigraph.tosca.yaml.beans.DpiNode;\r
36 import it.polito.verigraph.tosca.yaml.beans.EndhostConfigurationYaml;\r
37 import it.polito.verigraph.tosca.yaml.beans.EndhostNode;\r
38 import it.polito.verigraph.tosca.yaml.beans.EndpointConfigurationYaml;\r
39 import it.polito.verigraph.tosca.yaml.beans.EndpointNode;\r
40 import it.polito.verigraph.tosca.yaml.beans.FieldModifierConfigurationYaml;\r
41 import it.polito.verigraph.tosca.yaml.beans.FieldModifierNode;\r
42 import it.polito.verigraph.tosca.yaml.beans.FirewallConfigurationYaml;\r
43 import it.polito.verigraph.tosca.yaml.beans.FirewallNode;\r
44 import it.polito.verigraph.tosca.yaml.beans.MailClientConfigurationYaml;\r
45 import it.polito.verigraph.tosca.yaml.beans.MailClientNode;\r
46 import it.polito.verigraph.tosca.yaml.beans.MailServerConfigurationYaml;\r
47 import it.polito.verigraph.tosca.yaml.beans.MailServerNode;\r
48 import it.polito.verigraph.tosca.yaml.beans.NatConfigurationYaml;\r
49 import it.polito.verigraph.tosca.yaml.beans.NatNode;\r
50 import it.polito.verigraph.tosca.yaml.beans.NodeTemplateYaml;\r
51 import it.polito.verigraph.tosca.yaml.beans.RelationshipTemplateYaml;\r
52 import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;\r
53 import it.polito.verigraph.tosca.yaml.beans.TopologyTemplateYaml;\r
54 import it.polito.verigraph.tosca.yaml.beans.VpnAccessConfigurationYaml;\r
55 import it.polito.verigraph.tosca.yaml.beans.VpnAccessNode;\r
56 import it.polito.verigraph.tosca.yaml.beans.VpnExitConfigurationYaml;\r
57 import it.polito.verigraph.tosca.yaml.beans.VpnExitNode;\r
58 import it.polito.verigraph.tosca.yaml.beans.WebClientConfigurationYaml;\r
59 import it.polito.verigraph.tosca.yaml.beans.WebClientNode;\r
60 import it.polito.verigraph.tosca.yaml.beans.WebServerConfigurationYaml;\r
61 import it.polito.verigraph.tosca.yaml.beans.WebServerNode;\r
62 \r
63 public class GraphToYaml {\r
64     public static ServiceTemplateYaml mapGraphYaml(Graph graph) {\r
65         ServiceTemplateYaml serviceTemplate = new ServiceTemplateYaml();\r
66         TopologyTemplateYaml topologyTemplate = new TopologyTemplateYaml();\r
67 \r
68         topologyTemplate.setNode_templates(new HashMap<String,NodeTemplateYaml>());\r
69         topologyTemplate.setRelationship_templates(new HashMap<String,RelationshipTemplateYaml>());\r
70         serviceTemplate.setMetadata(new HashMap<String,String>());\r
71 \r
72         //Neighbour does not have a neighbourID!\r
73         //RelationshipTemplate does, so it is an incremental number for each node\r
74         long i = 0; //This counter will act as a fake incremental id of relationships\r
75         for(Node node : graph.getNodes().values()) {\r
76             NodeTemplateYaml nodeTemplate;\r
77             try {\r
78                 nodeTemplate = mapNodeYaml(node);\r
79             } catch (IOException e) {\r
80                 throw new BadRequestException("Error while mapping a Node in Yaml object.");\r
81             }\r
82             topologyTemplate.getNode_templates().put(String.valueOf(node.getId()), nodeTemplate);\r
83             //shall we catch NumberFormatException?\r
84 \r
85             Map<Long,Neighbour> neighMap = node.getNeighbours();\r
86             for (Map.Entry<Long, Neighbour> myentry : neighMap.entrySet()) {\r
87                 Neighbour neigh = myentry.getValue();\r
88                 if (graph.getNodes().containsKey(neigh.getId())) {\r
89                     // I have to check that because if I'm mapping a path (and not a graph)\r
90                     //I could have as neighbour a node which is not in the path\r
91                     RelationshipTemplateYaml relat = mapRelationshipYaml(node, neigh);\r
92                     topologyTemplate.getRelationship_templates().put(String.valueOf(i), relat);\r
93                     i++;\r
94                 }\r
95             }\r
96         }\r
97 \r
98         serviceTemplate.getMetadata().put("template_id", String.valueOf(graph.getId()));\r
99         serviceTemplate.setTopology_template(topologyTemplate);\r
100         return serviceTemplate;\r
101     }\r
102 \r
103 \r
104     private static NodeTemplateYaml mapNodeYaml(Node node) throws JsonParseException, JsonMappingException, IOException {\r
105 \r
106         ObjectMapper mapper = new ObjectMapper(new YAMLFactory());\r
107         JsonNode configNode = node.getConfiguration().getConfiguration();\r
108         SimpleModule module = new SimpleModule();\r
109 \r
110         //Passing the configuration type to the Deserializer context\r
111         module.addDeserializer(ConfigurationYaml.class, new YamlConfigurationDeserializer());\r
112         mapper.registerModule(module);\r
113 \r
114         //Here we use the custom deserializer to convert the JsonNode into a Yaml bean\r
115         //The injectable value allows to provide an additional info to the deserializer that will be able to\r
116         //know that it is parsing a certain type of Configuration.\r
117         ConfigurationYaml yamlConfig = mapper\r
118                 .reader(new InjectableValues.Std().addValue("type", node.getFunctional_type().toLowerCase()))\r
119                 .forType(ConfigurationYaml.class).readValue(configNode);\r
120 \r
121         FunctionalTypes nodeType = FunctionalTypes.valueOf(node.getFunctional_type().toUpperCase());\r
122         switch(nodeType) {\r
123         case ANTISPAM:\r
124             AntispamNode antispamNode = new AntispamNode();\r
125             antispamNode.setName(node.getName());\r
126             antispamNode.setType("verigraph.nodeTypes." +\r
127                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
128                     node.getFunctional_type().substring(1));\r
129             antispamNode.setProperties((AntispamConfigurationYaml) yamlConfig);\r
130             return antispamNode;\r
131 \r
132         case CACHE:\r
133             CacheNode cacheNode = new CacheNode();\r
134             cacheNode.setName(node.getName());\r
135             cacheNode.setType("verigraph.nodeTypes." +\r
136                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
137                     node.getFunctional_type().substring(1));\r
138             cacheNode.setProperties((CacheConfigurationYaml) yamlConfig);\r
139             return cacheNode;\r
140 \r
141         case DPI:\r
142             DpiNode dpiNode = new DpiNode();\r
143             dpiNode.setName(node.getName());\r
144             dpiNode.setType("verigraph.nodeTypes." +\r
145                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
146                     node.getFunctional_type().substring(1));\r
147             dpiNode.setProperties((DpiConfigurationYaml) yamlConfig);\r
148             return dpiNode;\r
149 \r
150         case ENDHOST:\r
151             EndhostNode endhostNode = new EndhostNode();\r
152             endhostNode.setName(node.getName());\r
153             endhostNode.setType("verigraph.nodeTypes." +\r
154                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
155                     node.getFunctional_type().substring(1));\r
156             endhostNode.setProperties((EndhostConfigurationYaml) yamlConfig);\r
157             return endhostNode;\r
158 \r
159         case ENDPOINT:\r
160             EndpointNode endpointNode = new EndpointNode();\r
161             endpointNode.setName(node.getName());\r
162             endpointNode.setType("verigraph.nodeTypes." +\r
163                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
164                     node.getFunctional_type().substring(1));\r
165             endpointNode.setProperties((EndpointConfigurationYaml) yamlConfig);\r
166             return endpointNode;\r
167 \r
168         case FIELDMODIFIER:\r
169             FieldModifierNode fieldmodifierNode = new FieldModifierNode();\r
170             fieldmodifierNode.setName(node.getName());\r
171             fieldmodifierNode.setType("verigraph.nodeTypes." +\r
172                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
173                     node.getFunctional_type().substring(1));\r
174             fieldmodifierNode.setProperties((FieldModifierConfigurationYaml) yamlConfig);\r
175             return fieldmodifierNode;\r
176 \r
177         case FIREWALL:\r
178             FirewallNode firewallNode = new FirewallNode();\r
179             firewallNode.setName(node.getName());\r
180             firewallNode.setType("verigraph.nodeTypes." +\r
181                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
182                     node.getFunctional_type().substring(1));\r
183             firewallNode.setProperties((FirewallConfigurationYaml) yamlConfig);\r
184             return firewallNode;\r
185 \r
186         case MAILCLIENT:\r
187             MailClientNode mailclientNode = new MailClientNode();\r
188             mailclientNode.setName(node.getName());\r
189             mailclientNode.setType("verigraph.nodeTypes." +\r
190                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
191                     node.getFunctional_type().substring(1));\r
192             mailclientNode.setProperties((MailClientConfigurationYaml) yamlConfig);\r
193             return mailclientNode;\r
194 \r
195         case MAILSERVER:\r
196             MailServerNode mailserverNode = new MailServerNode();\r
197             mailserverNode.setName(node.getName());\r
198             mailserverNode.setType("verigraph.nodeTypes." +\r
199                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
200                     node.getFunctional_type().substring(1));\r
201             mailserverNode.setProperties((MailServerConfigurationYaml) yamlConfig);\r
202             return mailserverNode;\r
203 \r
204         case NAT:\r
205             NatNode natNode = new NatNode();\r
206             natNode.setName(node.getName());\r
207             natNode.setType("verigraph.nodeTypes." +\r
208                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
209                     node.getFunctional_type().substring(1));\r
210             natNode.setProperties((NatConfigurationYaml) yamlConfig);\r
211             return natNode;\r
212 \r
213         case VPNACCESS:\r
214             VpnAccessNode vpnaccessNode = new VpnAccessNode();\r
215             vpnaccessNode.setName(node.getName());\r
216             vpnaccessNode.setType("verigraph.nodeTypes." +\r
217                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
218                     node.getFunctional_type().substring(1));\r
219             vpnaccessNode.setProperties((VpnAccessConfigurationYaml) yamlConfig);\r
220             return vpnaccessNode;\r
221 \r
222         case VPNEXIT:\r
223             VpnExitNode vpnexitNode = new VpnExitNode();\r
224             vpnexitNode.setName(node.getName());\r
225             vpnexitNode.setType("verigraph.nodeTypes." +\r
226                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
227                     node.getFunctional_type().substring(1));\r
228             vpnexitNode.setProperties((VpnExitConfigurationYaml) yamlConfig);\r
229             return vpnexitNode;\r
230 \r
231         case WEBCLIENT:\r
232             WebClientNode webclientNode = new WebClientNode();\r
233             webclientNode.setName(node.getName());\r
234             webclientNode.setType("verigraph.nodeTypes." +\r
235                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
236                     node.getFunctional_type().substring(1));\r
237             webclientNode.setProperties((WebClientConfigurationYaml) yamlConfig);\r
238             return webclientNode;\r
239 \r
240         case WEBSERVER:\r
241             WebServerNode webserverNode = new WebServerNode();\r
242             webserverNode.setName(node.getName());\r
243             webserverNode.setType("verigraph.nodeTypes." +\r
244                     node.getFunctional_type().substring(0, 1).toUpperCase() +\r
245                     node.getFunctional_type().substring(1));\r
246             webserverNode.setProperties((WebServerConfigurationYaml) yamlConfig);\r
247             return webserverNode;\r
248 \r
249         default:\r
250             FieldModifierNode defaultNode = new FieldModifierNode();\r
251             defaultNode.setName(node.getName());\r
252             defaultNode.setType("verigraph.nodeTypes.Fieldmodifier");\r
253             defaultNode.setProperties(new FieldModifierConfigurationYaml());\r
254             return defaultNode;\r
255         }\r
256 \r
257     }\r
258 \r
259     private static RelationshipTemplateYaml mapRelationshipYaml(Node sourceNode, Neighbour neigh) {\r
260         RelationshipTemplateYaml relationship = new RelationshipTemplateYaml();\r
261         relationship.setProperties(new HashMap<String,String>());\r
262 \r
263         relationship.setType("verigraph.relationshipType.generic");\r
264         relationship.getProperties().put("source_id", String.valueOf(sourceNode.getId())); //to be catched?\r
265         relationship.getProperties().put("target_id", String.valueOf(neigh.getId()));\r
266         relationship.getProperties().put("name", sourceNode.getName()+"to"+neigh.getName());\r
267 \r
268         return relationship;\r
269     }\r
270 }\r