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.databind.JsonNode;
\r
16 import com.fasterxml.jackson.databind.ObjectMapper;
\r
17 import com.fasterxml.jackson.databind.module.SimpleModule;
\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
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
38 nodes = yamlServiceTemplate.getTopology_template().getNode_templates();
\r
40 for (Map.Entry<String, NodeTemplateYaml> nodeYamlEntry : nodes.entrySet()) {
\r
41 Node node = mapNodeTemplateYaml(nodeYamlEntry.getValue());
\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
51 // Add Neighbours to the Nodes of the list
\r
52 relats = yamlServiceTemplate.getTopology_template().getRelationship_templates();
\r
53 mapRelationshipTemplatesYaml(graphNodes, relats);
\r
55 // Add Nodes and ID to the graph
\r
56 graph.setNodes(graphNodes);
\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
67 private static Node mapNodeTemplateYaml(NodeTemplateYaml yamlNodeTemplate) {
\r
68 Node node = new Node();
\r
70 String type = yamlNodeTemplate.getType().replace("verigraph.nodeTypes.", "").toLowerCase();
\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
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
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
93 Neighbour neigh = new Neighbour();
\r
94 neigh.setName(name);
\r
95 neigh.setId(Long.valueOf(target));
\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
103 sourceNodeNeighMap.put(neigh.getId(), neigh);
\r
104 sourceNode.setNeighbours(sourceNodeNeighMap);
\r
106 //Update the Node list
\r
107 graphNodes.put(Long.valueOf(source), sourceNode);
\r
109 } catch(NullPointerException | NumberFormatException ex) {
\r
110 throw new BadRequestException("A RelationshipTemplate has wrong fields representation.");
\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
127 String stringConfiguration = YamlParsingUtils.obtainConfiguration(node);
\r
128 jsonConfiguration = mapper.readTree(stringConfiguration);
\r
129 config.setConfiguration(jsonConfiguration);
\r
130 config.setDescription("");
\r
132 } catch (NullPointerException | IOException | BadRequestException e) {
\r
133 throw new BadRequestException("Not able to retrieve a valid configuration");
\r