2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright (C) 2017 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
23 package org.openecomp.appc.dg.dependencymanager.helper;
25 import com.att.eelf.configuration.EELFLogger;
26 import com.att.eelf.configuration.EELFManager;
27 import com.fasterxml.jackson.databind.JsonNode;
28 import com.fasterxml.jackson.databind.ObjectMapper;
29 import com.fasterxml.jackson.databind.node.ObjectNode;
30 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
31 import org.apache.commons.lang3.StringUtils;
32 import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel;
33 import org.openecomp.appc.dg.objects.Node;
34 import org.openecomp.appc.dg.objects.VnfcDependencyModel;
35 import org.openecomp.appc.domainmodel.Vnfc;
37 import java.io.IOException;
41 public class DependencyModelParser {
43 private static final EELFLogger logger = EELFManager.getInstance().getLogger(DependencyModelParser.class);
44 private static Map<String, String> dependencyMap;
45 private static final String PROPERTIES = "properties";
46 private static final String ACTIVE_ACTIVE = "Active-Active";
47 private static final String ACTIVE_PASSIVE = "Active-Passive";
48 private static final String HIGH_AVAILABLITY = "high_availablity";
49 private static final String MANDATORY = "mandatory";
50 private static final String TOPOLOGY_TEMPLATE = "topology_template";
53 Map<String, String> dependencyTypeMappingMap =new HashMap<>();
54 dependencyTypeMappingMap.put("geo-activeactive", ACTIVE_ACTIVE);
55 dependencyTypeMappingMap.put("geo-activestandby", ACTIVE_PASSIVE);
56 dependencyTypeMappingMap.put("local-activeactive", ACTIVE_ACTIVE);
57 dependencyTypeMappingMap.put("local-activestandby", ACTIVE_PASSIVE);
58 dependencyMap = Collections.unmodifiableMap(dependencyTypeMappingMap);
61 public VnfcDependencyModel generateDependencyModel(String vnfModel,String vnfType) {
62 Set<Node<Vnfc>> dependencies = new HashSet<>();
63 ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
65 String resilienceType;
66 String prefix = "org.openecomp.resource.vfc."+vnfType+".abstract.nodes.";
68 ObjectNode root = (ObjectNode) mapper.readTree(vnfModel);
69 logger.debug("VNF Model after parsing: " + root);
71 if(root.get(TOPOLOGY_TEMPLATE) == null || root.get(TOPOLOGY_TEMPLATE).get("node_templates") == null) {
72 throw new InvalidDependencyModel("Dependency model is missing 'topology_template' or 'node_templates' elements");
75 JsonNode topologyTemplateNode = root.get(TOPOLOGY_TEMPLATE);
76 JsonNode nodeTemplateNode = topologyTemplateNode.get("node_templates");
77 Iterator<Map.Entry<String, JsonNode>> itretor = nodeTemplateNode.fields();
78 for (JsonNode yamlNode : nodeTemplateNode) {
79 logger.debug("Processing node: " + yamlNode);
80 String vnfcType = itretor.next().getKey();
81 String type = yamlNode.get("type").textValue();
82 type = type.substring(0,type.lastIndexOf(".")+1);
83 if(type.concat(vnfcType).toLowerCase().startsWith(prefix.concat(vnfcType).toLowerCase())) {
85 if(yamlNode.get(PROPERTIES).findValue(HIGH_AVAILABLITY) == null || yamlNode.get(PROPERTIES).findValue(HIGH_AVAILABLITY).asText().isEmpty()) {
86 resilienceType = ACTIVE_ACTIVE;
88 resilienceType = dependencyMap.get(yamlNode.get(PROPERTIES).findValue(HIGH_AVAILABLITY).textValue());
91 if(yamlNode.get(PROPERTIES).findValue(MANDATORY) == null || yamlNode.get(PROPERTIES).findValue(MANDATORY).asText().isEmpty()) {
94 mandatory = yamlNode.get(PROPERTIES).findValue(MANDATORY).booleanValue();
96 String[] parentList = getDependencyArray(yamlNode);
97 Node<Vnfc> vnfcNode = getNode(dependencies, vnfcType);
98 if (vnfcNode != null) {
99 logger.debug("Dependency node already exists for vnfc Type: " + vnfcType);
100 if (StringUtils.isEmpty(vnfcNode.getChild().getResilienceType())) {
101 logger.debug("Updating resilience type, dependencies and mandatory attribute for VNFC type: " + vnfcType);
102 vnfcNode.getChild().setResilienceType(resilienceType);
103 if (parentList != null && parentList.length > 0) {
104 addDependencies(dependencies, vnfcNode, parentList);
106 vnfcNode.getChild().setMandatory(mandatory);
110 logger.debug("Creating dependency node for : " + vnfcType);
111 vnfcNode = new Node<>(new Vnfc(vnfcType, resilienceType, null, mandatory));
112 if (parentList != null && parentList.length > 0)
113 addDependencies(dependencies, vnfcNode, parentList);
114 logger.debug("Adding VNFC to dependency model : " + vnfcNode);
115 dependencies.add(vnfcNode);
119 } catch (IOException e) {
120 logger.error("Error parsing dependency model : " + vnfModel);
121 logger.error("Error message : " + e);
122 throw new InvalidDependencyModel("Error parsing dependency model. " + e.getMessage());
124 return new VnfcDependencyModel(dependencies);
127 private void addDependencies(Set<Node<Vnfc>> nodes, Node node, String[] parentList) {
128 for (String type : parentList) {
129 String parentType = getVnfcType(type);
130 Node<Vnfc> parentNode = getNode(nodes, parentType);
131 if (parentNode != null) {
132 logger.debug("VNFC already exists for VNFC type: " + parentType + ". Adding it to parent list ");
133 node.addParent(parentNode.getChild());
135 logger.debug("VNFC does not exist for VNFC type: " + parentType + ". Creating new VNFC ");
136 parentNode = new Node<>(new Vnfc(parentType, null));
137 node.addParent(parentNode.getChild());
138 logger.debug("Adding VNFC to dependency model : " + parentNode);
139 nodes.add(parentNode);
144 private String[] getDependencyArray(JsonNode node) {
145 JsonNode requirementsNode = node.get("requirements");
146 List<String> dependencyList = new ArrayList();
147 if(requirementsNode!=null) {
148 for (JsonNode internalNode : requirementsNode) {
149 if (nodeNullCheck(internalNode) &&"tosca.capabilities.Node".equalsIgnoreCase(internalNode.get("capability").asText())
150 && "tosca.relationships.DependsOn".equalsIgnoreCase(internalNode.get("relationship").asText())) {
151 if(internalNode.get("node") != null) {
152 dependencyList.add(internalNode.get("node").asText());
154 throw new InvalidDependencyModel("Error parsing dependency model. " + "Dependent Node not found for "+ node.get("type"));
158 return dependencyList.toArray(new String[0]);
160 return new String[0];
164 private boolean nodeNullCheck(JsonNode internalNode) {
165 return internalNode.get("dependency") != null && internalNode.get("capability") != null && internalNode.get("relationship") != null;
168 private Node<Vnfc> getNode(Set<Node<Vnfc>> nodes, String vnfcType) {
169 Iterator itr = nodes.iterator();
171 while (itr.hasNext()) {
172 node = (Node<Vnfc>) itr.next();
173 if (node.getChild().getVnfcType().equalsIgnoreCase(vnfcType)) {
180 private String getVnfcType(String type) {
181 return type.substring(type.lastIndexOf('.') + 1, type.length());