Add CLI in verigraph.
[parser.git] / verigraph / src / it / polito / verigraph / tosca / converter / xml / XmlToGraph.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.xml;\r
10 \r
11 import java.io.IOException;\r
12 import java.util.HashMap;\r
13 import java.util.List;\r
14 import java.util.Map;\r
15 import java.util.stream.Collectors;\r
16 \r
17 import com.fasterxml.jackson.core.JsonProcessingException;\r
18 import com.fasterxml.jackson.databind.ObjectMapper;\r
19 \r
20 import it.polito.verigraph.exception.BadRequestException;\r
21 import it.polito.verigraph.exception.DataNotFoundException;\r
22 import it.polito.verigraph.model.Configuration;\r
23 import it.polito.verigraph.model.Graph;\r
24 import it.polito.verigraph.model.Neighbour;\r
25 import it.polito.verigraph.model.Node;\r
26 import it.polito.verigraph.tosca.MappingUtils;\r
27 import it.polito.verigraph.tosca.XmlParsingUtils;\r
28 import it.polito.tosca.jaxb.Definitions;\r
29 import it.polito.tosca.jaxb.TExtensibleElements;\r
30 import it.polito.tosca.jaxb.TNodeTemplate;\r
31 import it.polito.tosca.jaxb.TRelationshipTemplate;\r
32 import it.polito.tosca.jaxb.TServiceTemplate;\r
33 \r
34 public class XmlToGraph {\r
35     public static Graph mapTopologyTemplate(Definitions definitions) throws DataNotFoundException, BadRequestException {\r
36         Graph graph = new Graph();\r
37         Map<Long, Node> nodes = new HashMap<>();\r
38 \r
39         List<TExtensibleElements> elements = definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation();\r
40 \r
41         // Retrieve the list of ServiceTemplate in Definitions\r
42         List<TServiceTemplate> serviceTemplates = elements.stream().filter(p -> p instanceof TServiceTemplate)\r
43                 .map(obj -> (TServiceTemplate) obj).collect(Collectors.toList());\r
44         if (serviceTemplates.isEmpty())\r
45             throw new DataNotFoundException("There is no ServiceTemplate into the Definitions object");\r
46 \r
47         List<TNodeTemplate> nodeTemplates = XmlParsingUtils.obtainNodeTemplates(serviceTemplates.get(0));\r
48 \r
49         for (TNodeTemplate nodeTemplate : nodeTemplates) {\r
50             Node node = mapNodeTemplate(nodeTemplate);\r
51             nodes.put(Long.valueOf(nodeTemplate.getId()), node);\r
52         }\r
53 \r
54         // Add Neighbour to the Node of the list\r
55         List<TRelationshipTemplate> relationshipTemplates = XmlParsingUtils.obtainRelationshipTemplates(serviceTemplates.get(0));\r
56         mapRelationshipTemplates(nodes, relationshipTemplates);\r
57 \r
58         // Add Nodes and ID to the graph\r
59         graph.setNodes(nodes);\r
60 \r
61         try {\r
62             graph.setId(Long.valueOf(serviceTemplates.get(0).getId()));\r
63         } catch (NumberFormatException ex) {\r
64             throw new BadRequestException("If you want to store your TopologyTemplate on this server, "\r
65                     + "the TopologyTemplate ID must be a number.");\r
66         }\r
67 \r
68         return graph;\r
69     }\r
70 \r
71 \r
72     private static Node mapNodeTemplate(TNodeTemplate nodeTemplate) {\r
73         Node node = new Node();\r
74 \r
75         String toscaType =  nodeTemplate.getType().toString();\r
76         toscaType = toscaType.replace("Type", "").replace("{http://docs.oasis-open.org/tosca/ns/2011/12}", "");\r
77         toscaType = toscaType.toLowerCase();\r
78 \r
79         try {\r
80             node.setId(Long.valueOf(nodeTemplate.getId()));\r
81         } catch(NumberFormatException ex) {\r
82             throw new BadRequestException("The NodeTemplate ID must be a number.");\r
83         }\r
84         try {\r
85             node.setName(nodeTemplate.getName());\r
86             Configuration conf = mapToscaConfiguration(XmlParsingUtils.obtainConfiguration(nodeTemplate));\r
87             node.setConfiguration(conf);\r
88             node.setFunctional_type(toscaType);\r
89         } catch(NullPointerException | IOException ex) {\r
90             throw new BadRequestException("The NodeTemplate id:"+node.getId()+" has wrong fields representation.");\r
91         }\r
92         return node;\r
93     }\r
94 \r
95 \r
96     private static void mapRelationshipTemplates(Map<Long, Node> nodes, List<TRelationshipTemplate> relationshipTemplates) {\r
97         //update of nodes... (update = Node + its Neighbours)\r
98         for(TRelationshipTemplate relationshipTemplate : relationshipTemplates) {\r
99             if (relationshipTemplate != null) {\r
100                 try {\r
101                     if(relationshipTemplate.getSourceElement().getRef() == relationshipTemplate.getTargetElement().getRef())\r
102                         throw new BadRequestException("Source and Target cannot be equal in a Relationship.");\r
103 \r
104                     // Retrieve the target Node name and generate a new Neighbour\r
105                     TNodeTemplate targetNodeTemplate = (TNodeTemplate) relationshipTemplate.getTargetElement().getRef();\r
106                     String neighName = nodes.get(Long.valueOf(targetNodeTemplate.getId())).getName();\r
107                     //this manages invalid/inexistent node ID for target node\r
108                     Neighbour neigh = new Neighbour();\r
109                     neigh.setName(neighName);\r
110                     neigh.setId(Long.valueOf(relationshipTemplate.getId()));\r
111 \r
112                     //Retrieve the Neighbour map of the source Node and add the Neighbour\r
113                     TNodeTemplate sourceNodeTemplate = (TNodeTemplate) relationshipTemplate.getSourceElement().getRef();\r
114                     Node source = nodes.get(Long.valueOf(sourceNodeTemplate.getId()));\r
115                     //this manages invalid/inexistent node ID for source node\r
116                     Map<Long,Neighbour> sourceNodeNeighMap = source.getNeighbours();\r
117                     if(sourceNodeNeighMap.containsKey(neigh.getId()))\r
118                         throw new BadRequestException("The RelationshipTemplate ID must be unique.");\r
119                     else\r
120                         sourceNodeNeighMap.put(neigh.getId(), neigh);\r
121                     source.setNeighbours(sourceNodeNeighMap);\r
122 \r
123                     //Update the Node list\r
124                     nodes.put(Long.valueOf(sourceNodeTemplate.getId()), source);\r
125                 } catch(NullPointerException | NumberFormatException ex) {\r
126                     throw new BadRequestException("A RelationshipTemplate has wrong fields representation.");\r
127                 }\r
128             }\r
129         }\r
130     }\r
131 \r
132     private static Configuration mapToscaConfiguration(it.polito.tosca.jaxb.Configuration configuration)\r
133             throws JsonProcessingException, IOException {\r
134         Configuration conf = new Configuration();\r
135         ObjectMapper mapper = new ObjectMapper();\r
136         String stringConfiguration;\r
137 \r
138         //Retrieve configuration ID (optional)\r
139         if (configuration.getConfID() != null)\r
140             conf.setId(configuration.getConfID());\r
141         else\r
142             conf.setId("");\r
143 \r
144         //Retrieve description (optional)\r
145         if (configuration.getConfDescr() != null)\r
146             conf.setDescription(configuration.getConfDescr());\r
147         else\r
148             conf.setDescription("");\r
149 \r
150         //Retrieve string of configuration\r
151         try {\r
152             stringConfiguration = MappingUtils.obtainStringConfiguration(configuration);\r
153         } catch(IOException ex) {\r
154             conf.setConfiguration(mapper.readTree("[]"));\r
155             System.out.println("[WARNING] Provided default configuration.");\r
156             return conf;\r
157         }\r
158 \r
159         //Retrieve JsonNode from the string of configuration\r
160         try {\r
161             conf.setConfiguration(mapper.readTree(stringConfiguration));\r
162             return conf;\r
163         } catch (IOException e) {\r
164             throw new BadRequestException("NodeTemplate configuration is invalid.");\r
165         }\r
166     }\r
167 }\r