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.xml;
\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
17 import com.fasterxml.jackson.core.JsonProcessingException;
\r
18 import com.fasterxml.jackson.databind.ObjectMapper;
\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
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
39 List<TExtensibleElements> elements = definitions.getServiceTemplateOrNodeTypeOrNodeTypeImplementation();
\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
47 List<TNodeTemplate> nodeTemplates = XmlParsingUtils.obtainNodeTemplates(serviceTemplates.get(0));
\r
49 for (TNodeTemplate nodeTemplate : nodeTemplates) {
\r
50 Node node = mapNodeTemplate(nodeTemplate);
\r
51 nodes.put(Long.valueOf(nodeTemplate.getId()), node);
\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
58 // Add Nodes and ID to the graph
\r
59 graph.setNodes(nodes);
\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
72 private static Node mapNodeTemplate(TNodeTemplate nodeTemplate) {
\r
73 Node node = new Node();
\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
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
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
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
101 if(relationshipTemplate.getSourceElement().getRef() == relationshipTemplate.getTargetElement().getRef())
\r
102 throw new BadRequestException("Source and Target cannot be equal in a Relationship.");
\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
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
120 sourceNodeNeighMap.put(neigh.getId(), neigh);
\r
121 source.setNeighbours(sourceNodeNeighMap);
\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
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
138 //Retrieve configuration ID (optional)
\r
139 if (configuration.getConfID() != null)
\r
140 conf.setId(configuration.getConfID());
\r
144 //Retrieve description (optional)
\r
145 if (configuration.getConfDescr() != null)
\r
146 conf.setDescription(configuration.getConfDescr());
\r
148 conf.setDescription("");
\r
150 //Retrieve string of configuration
\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
159 //Retrieve JsonNode from the string of configuration
\r
161 conf.setConfiguration(mapper.readTree(stringConfiguration));
\r
163 } catch (IOException e) {
\r
164 throw new BadRequestException("NodeTemplate configuration is invalid.");
\r