Add CLI in verigraph.
[parser.git] / verigraph / src / it / polito / verigraph / tosca / converter / yaml / YamlToGraph.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.databind.JsonNode;\r
16 import com.fasterxml.jackson.databind.ObjectMapper;\r
17 import com.fasterxml.jackson.databind.module.SimpleModule;\r
18 \r
19 import it.polito.verigraph.exception.BadRequestException;\r
20 import it.polito.verigraph.model.Configuration;\r
21 import it.polito.verigraph.model.Graph;\r
22 import it.polito.verigraph.model.Neighbour;\r
23 import it.polito.verigraph.model.Node;\r
24 import it.polito.verigraph.tosca.YamlParsingUtils;\r
25 import it.polito.verigraph.tosca.serializer.YamlConfigSerializer;\r
26 import it.polito.verigraph.tosca.yaml.beans.ConfigurationYaml;\r
27 import it.polito.verigraph.tosca.yaml.beans.NodeTemplateYaml;\r
28 import it.polito.verigraph.tosca.yaml.beans.RelationshipTemplateYaml;\r
29 import it.polito.verigraph.tosca.yaml.beans.ServiceTemplateYaml;\r
30 \r
31 public class YamlToGraph {\r
32     public static Graph mapTopologyTemplateYaml(ServiceTemplateYaml yamlServiceTemplate) throws BadRequestException {\r
33         Graph graph = new Graph();\r
34         Map<Long, Node> graphNodes = new HashMap<>();\r
35         Map<String, NodeTemplateYaml> nodes = new HashMap<>();\r
36         Map<String, RelationshipTemplateYaml> relats = new HashMap<>();\r
37 \r
38         nodes = yamlServiceTemplate.getTopology_template().getNode_templates();\r
39 \r
40         for (Map.Entry<String, NodeTemplateYaml> nodeYamlEntry : nodes.entrySet()) {\r
41             Node node = mapNodeTemplateYaml(nodeYamlEntry.getValue());\r
42 \r
43             try {\r
44                 graphNodes.put(Long.valueOf(nodeYamlEntry.getKey()), node);\r
45             } catch (NumberFormatException e) {\r
46                 throw new BadRequestException("The NodeTemplate ID must be a number.");\r
47             }\r
48 \r
49         }\r
50 \r
51         // Add Neighbours to the Nodes of the list\r
52         relats = yamlServiceTemplate.getTopology_template().getRelationship_templates();\r
53         mapRelationshipTemplatesYaml(graphNodes, relats);\r
54 \r
55         // Add Nodes and ID to the graph\r
56         graph.setNodes(graphNodes);\r
57         try {\r
58             graph.setId(Long.valueOf(yamlServiceTemplate.getMetadata().get("template_id")));\r
59         } catch (NumberFormatException ex) {\r
60             throw new BadRequestException("If you want to use this service, the TopologyTemplate ID must be a number.");\r
61         } catch (NullPointerException ex) {} //ID is not mandatory for the user since VeriGraph provides its IDs\r
62 \r
63         return graph;\r
64     }\r
65 \r
66 \r
67     private static Node mapNodeTemplateYaml(NodeTemplateYaml yamlNodeTemplate) {\r
68         Node node = new Node();\r
69 \r
70         String type =  yamlNodeTemplate.getType().replace("verigraph.nodeTypes.", "").toLowerCase();\r
71 \r
72         try {\r
73             node.setName(yamlNodeTemplate.getName());\r
74             Configuration conf = mapConfigurationYaml(yamlNodeTemplate);\r
75             node.setConfiguration(conf);\r
76             node.setFunctional_type(type);\r
77         } catch(NullPointerException ex) {\r
78             throw new BadRequestException("A NodeTemplate has wrong fields representation.");\r
79         }\r
80         return node;\r
81     }\r
82 \r
83 \r
84     private static void mapRelationshipTemplatesYaml(Map<Long, Node> graphNodes, Map<String, RelationshipTemplateYaml> relats) {\r
85         //updated nodes (update = Node + its Neighbours)\r
86         for(Map.Entry<String, RelationshipTemplateYaml> yamlRelationshipTemplate : relats.entrySet()) {\r
87             try {\r
88                 // Retrieve relationship information\r
89                 String target = yamlRelationshipTemplate.getValue().getProperties().get("target_id");\r
90                 String source = yamlRelationshipTemplate.getValue().getProperties().get("source_id");\r
91                 String name = graphNodes.get(Long.valueOf(target)).getName();\r
92 \r
93                 Neighbour neigh = new Neighbour();\r
94                 neigh.setName(name);\r
95                 neigh.setId(Long.valueOf(target));\r
96 \r
97                 //Retrieve the Neighbour map of the source Node and add the Neighbour\r
98                 Node sourceNode = graphNodes.get(Long.valueOf(source));\r
99                 Map<Long,Neighbour> sourceNodeNeighMap = sourceNode.getNeighbours();\r
100                 if(sourceNodeNeighMap.containsKey(neigh.getId()))\r
101                     throw new BadRequestException("The RelationshipTemplate ID must be unique.");\r
102                 else\r
103                     sourceNodeNeighMap.put(neigh.getId(), neigh);\r
104                 sourceNode.setNeighbours(sourceNodeNeighMap);\r
105 \r
106                 //Update the Node list\r
107                 graphNodes.put(Long.valueOf(source), sourceNode);\r
108 \r
109             } catch(NullPointerException | NumberFormatException ex) {\r
110                 throw new BadRequestException("A RelationshipTemplate has wrong fields representation.");\r
111             }\r
112 \r
113         }\r
114 \r
115     }\r
116 \r
117 \r
118     private static Configuration mapConfigurationYaml(NodeTemplateYaml node) {\r
119         Configuration config = new Configuration();\r
120         JsonNode jsonConfiguration = null;\r
121         ObjectMapper mapper = new ObjectMapper();\r
122         SimpleModule module = new SimpleModule();\r
123         module.addSerializer(ConfigurationYaml.class, new YamlConfigSerializer());\r
124         mapper.registerModule(module);\r
125 \r
126         try{\r
127             String stringConfiguration = YamlParsingUtils.obtainConfiguration(node);\r
128             jsonConfiguration = mapper.readTree(stringConfiguration);\r
129             config.setConfiguration(jsonConfiguration);\r
130             config.setDescription("");\r
131             config.setId("");\r
132         } catch (NullPointerException | IOException | BadRequestException e) {\r
133             throw new BadRequestException("Not able to retrieve a valid configuration");\r
134         }\r
135 \r
136         return config;\r
137     }\r
138 }\r