5e9be7f6a58390288f3facfdd58619f9d16e6da5
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / main / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / packagetransformer / OnapAbstractVnfdBuilder.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.packagetransformer;
18
19 import com.google.common.annotations.VisibleForTesting;
20 import com.google.gson.Gson;
21 import com.google.gson.JsonArray;
22 import com.google.gson.JsonElement;
23 import com.google.gson.JsonObject;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.NoSuchElementException;
27 import java.util.Set;
28 import java.util.regex.Pattern;
29 import org.slf4j.Logger;
30 import org.yaml.snakeyaml.Yaml;
31
32 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.child;
33 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.childElement;
34 import static org.slf4j.LoggerFactory.getLogger;
35
36 /**
37  * Generic non ONAP version dependent package conversion
38  */
39 abstract class OnapAbstractVnfdBuilder {
40     public static final String DESCRIPTION = "description";
41     public static final String PROPERTIES = "properties";
42     public static final String REQUIREMENTS = "requirements";
43     private static Logger logger = getLogger(OnapAbstractVnfdBuilder.class);
44
45     @VisibleForTesting
46     static String indent(String content, int prefixSize) {
47         StringBuilder sb = new StringBuilder();
48         for (int i = 0; i < prefixSize; i++) {
49             sb.append("  ");
50         }
51         Pattern pattern = Pattern.compile("^(.*)$", Pattern.MULTILINE);
52         return pattern.matcher(content).replaceAll(sb.toString() + "$1");
53     }
54
55     protected static String getRequirement(JsonArray requirements, String key) {
56         for (int i = 0; i < requirements.size(); i++) {
57             JsonElement requirement = requirements.get(i);
58             Map.Entry<String, JsonElement> next = requirement.getAsJsonObject().entrySet().iterator().next();
59             String s = next.getKey();
60             if (key.equals(s)) {
61                 return next.getValue().getAsString();
62             }
63         }
64         return null;
65     }
66
67     protected JsonElement get(String name, Set<Map.Entry<String, JsonElement>> nodes) {
68         for (Map.Entry<String, JsonElement> node : nodes) {
69             if (name.equals(node.getKey())) {
70                 return node.getValue();
71             }
72         }
73         throw new NoSuchElementException("The VNFD does not have a node called " + name + " but required by an other node");
74     }
75
76     protected String buildEcp(String name, JsonElement ecp, Set<Map.Entry<String, JsonElement>> nodes) {
77         if (ecp.getAsJsonObject().has(REQUIREMENTS)) {
78             String icpName = getRequirement(ecp.getAsJsonObject().get(REQUIREMENTS).getAsJsonArray(), "internal_connection_point");
79             if (icpName != null) {
80                 return buildEcpInternal(name, icpName, nodes);
81             } else {
82                 logger.warn("The {} ecp does not have an internal connection point", name);
83             }
84         } else {
85             logger.warn("The {} ecp does not have an requirements section", name);
86         }
87         return "";
88     }
89
90     private String buildEcpInternal(String ecpName, String icpName, Set<Map.Entry<String, JsonElement>> nodes) {
91         JsonObject icpNode = get(icpName, nodes).getAsJsonObject();
92         if (icpNode.has(REQUIREMENTS)) {
93             String vdu = getRequirement(icpNode.getAsJsonObject().get(REQUIREMENTS).getAsJsonArray(), "virtual_binding");
94             //internal connection point is bound to VDU
95             if (vdu != null) {
96                 return buildVduCpd(ecpName, vdu, child(icpNode, PROPERTIES));
97             } else {
98                 logger.warn("The {} internal connection point of the {} ecp does not have a VDU", icpName, ecpName);
99             }
100         } else {
101             logger.warn("The {} internal connection point of the {} ecp does not have a requirements section", icpName, ecpName);
102         }
103         return "";
104     }
105
106     /**
107      * @param cbamVnfd the CBAM VNFD
108      * @return the converted ONAP VNFD
109      */
110     public String toOnapVnfd(String cbamVnfd) {
111         JsonObject root = new Gson().toJsonTree(new Yaml().load(cbamVnfd)).getAsJsonObject();
112         JsonObject topologyTemplate = child(root, "topology_template");
113         JsonObject substitution_mappings = child(topologyTemplate, "substitution_mappings");
114         Map<String, JsonElement> virtualLinks = new HashMap<>();
115         if (topologyTemplate.has("node_templates")) {
116             Set<Map.Entry<String, JsonElement>> nodeTemplates = child(topologyTemplate, "node_templates").entrySet();
117             StringBuilder body = new StringBuilder();
118             for (Map.Entry<String, JsonElement> node : nodeTemplates) {
119                 String type = childElement(node.getValue().getAsJsonObject(), "type").getAsString();
120                 if ("tosca.nodes.nfv.VDU".equals(type)) {
121                     body.append(buildVdu(node.getKey(), substitution_mappings, node.getValue().getAsJsonObject(), nodeTemplates));
122                 } else if ("tosca.nodes.nfv.VirtualStorage".equals(type)) {
123                     body.append(buildVolume(node.getKey(), node.getValue().getAsJsonObject()));
124                 } else if ("tosca.nodes.nfv.VL".equals(type)) {
125                     virtualLinks.put(node.getKey(), node.getValue());
126                     body.append(buildVl(node.getValue().getAsJsonObject().get(PROPERTIES).getAsJsonObject(), node.getKey()));
127                 } else if ("tosca.nodes.nfv.ICP".equals(type)) {
128                     body.append(buildIcp(node.getKey(), node.getValue().getAsJsonObject()));
129                 } else if ("tosca.nodes.nfv.ECP".equals(type)) {
130                     body.append(buildEcp(node.getKey(), node.getValue(), nodeTemplates));
131                 } else {
132                     logger.warn("The {} type is not converted", type);
133                 }
134             }
135             return buildHeader(topologyTemplate, virtualLinks) + body.toString();
136         }
137         return buildHeader(topologyTemplate, virtualLinks);
138     }
139
140     abstract protected String buildHeader(JsonObject toplogyTemplate, Map<String, JsonElement> virtualLinks);
141
142     abstract protected String buildVduCpd(String name, String vdu, JsonObject properties);
143
144     abstract protected String buildVdu(String name, JsonObject vnf, JsonObject vdu, Set<Map.Entry<String, JsonElement>> nodes);
145
146     abstract protected String buildIcp(String name, JsonObject icp);
147
148     abstract protected String buildVolume(String nodeName, JsonObject volume);
149
150     abstract protected String buildVl(JsonObject vlProperties, String name);
151 }