1 /*******************************************************************************
\r
2 * Copyright (c) 2018 Politecnico di Torino and others.
\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
11 import java.io.IOException;
\r
12 import java.util.HashMap;
\r
13 import java.util.Map;
\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
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
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
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
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
78 nodeTemplate = mapNodeYaml(node);
\r
79 } catch (IOException e) {
\r
80 throw new BadRequestException("Error while mapping a Node in Yaml object.");
\r
82 topologyTemplate.getNode_templates().put(String.valueOf(node.getId()), nodeTemplate);
\r
83 //shall we catch NumberFormatException?
\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
98 serviceTemplate.getMetadata().put("template_id", String.valueOf(graph.getId()));
\r
99 serviceTemplate.setTopology_template(topologyTemplate);
\r
100 return serviceTemplate;
\r
104 private static NodeTemplateYaml mapNodeYaml(Node node) throws JsonParseException, JsonMappingException, IOException {
\r
106 ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
\r
107 JsonNode configNode = node.getConfiguration().getConfiguration();
\r
108 SimpleModule module = new SimpleModule();
\r
110 //Passing the configuration type to the Deserializer context
\r
111 module.addDeserializer(ConfigurationYaml.class, new YamlConfigurationDeserializer());
\r
112 mapper.registerModule(module);
\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
121 FunctionalTypes nodeType = FunctionalTypes.valueOf(node.getFunctional_type().toUpperCase());
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
259 private static RelationshipTemplateYaml mapRelationshipYaml(Node sourceNode, Neighbour neigh) {
\r
260 RelationshipTemplateYaml relationship = new RelationshipTemplateYaml();
\r
261 relationship.setProperties(new HashMap<String,String>());
\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
268 return relationship;
\r