Rename packages from openecomp to onap.
[sdc.git] / openecomp-be / lib / openecomp-sdc-enrichment-lib / openecomp-sdc-enrichment-impl / src / main / java / org / openecomp / sdc / enrichment / impl / tosca / AbstractSubstituteToscaEnricher.java
1 package org.openecomp.sdc.enrichment.impl.tosca;
2
3 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.HIGH_AVAIL_MODE;
4 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MANDATORY;
5 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MAX_INSTANCES;
6 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MIN_INSTANCES;
7 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VFC_CODE;
8 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VFC_FUNCTION;
9 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VFC_NAMING_CODE;
10 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VM_TYPE_TAG;
11 import static org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType.NATIVE_NODE;
12 import static org.openecomp.sdc.tosca.datatypes.ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE;
13 import static org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType.NATIVE_DEPENDS_ON;
14 import static org.openecomp.sdc.tosca.services.ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME;
15 import static org.openecomp.sdc.translator.services.heattotosca.Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX;
16
17 import org.apache.commons.collections4.CollectionUtils;
18 import org.apache.commons.lang3.StringUtils;
19 import org.openecomp.sdc.datatypes.error.ErrorMessage;
20 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
21 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
22 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
23 import org.onap.sdc.tosca.datatypes.model.NodeType;
24 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
25 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
26 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
27 import org.openecomp.sdc.tosca.services.DataModelUtil;
28 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
29 import org.openecomp.sdc.tosca.services.ToscaConstants;
30 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
31 import org.openecomp.sdc.versioning.dao.types.Version;
32
33 import java.util.ArrayList;
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Objects;
38 import java.util.Optional;
39
40 public class AbstractSubstituteToscaEnricher {
41   private ToscaAnalyzerService toscaAnalyzerService ;
42   private ComponentQuestionnaireData componentQuestionnaireData;
43
44
45   public Map<String,List<ErrorMessage>> enrich(ToscaServiceModel toscaModel, String vspId, Version
46       version) {
47     componentQuestionnaireData = getComponentQuestionnaireData();
48     toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
49
50     Map<String, Map<String, Object>> componentProperties =
51         componentQuestionnaireData.getPropertiesfromCompQuestionnaire(vspId, version);
52
53     final Map<String, List<String>> sourceToTargetDependencies =
54         componentQuestionnaireData.populateDependencies(vspId, version,
55             componentQuestionnaireData.getSourceToTargetComponent());
56
57     Map<String, List<ErrorMessage>> errors = new HashMap<>();
58
59     final ServiceTemplate serviceTemplate = toscaModel.getServiceTemplates()
60         .get(toscaModel.getEntryDefinitionServiceTemplate());
61
62     if (serviceTemplate == null) return errors;
63
64     final Map<String, NodeTemplate> node_templates =
65         serviceTemplate.getTopology_template().getNode_templates();
66     if(node_templates == null) return errors;
67
68     final Map<String, List<String>> componentDisplayNameToNodeTempalteIds =
69         populateAllNodeTemplateIdForComponent(node_templates, serviceTemplate, toscaModel);
70
71     node_templates.keySet()
72         .stream()
73         .forEach(nodeTemplateId -> {
74           final Optional<NodeTemplate> nodeTemplateById =
75               toscaAnalyzerService.getNodeTemplateById(serviceTemplate, nodeTemplateId);
76           final NodeTemplate nodeTemplate =
77               nodeTemplateById.isPresent() ? nodeTemplateById.get() : null;
78
79           if (toscaAnalyzerService.isTypeOf(nodeTemplate, VFC_ABSTRACT_SUBSTITUTE, serviceTemplate,
80               toscaModel)) {
81
82             String componentDisplayName = getComponentDisplayName(nodeTemplateId, nodeTemplate);
83
84             setProperty(nodeTemplate, VM_TYPE_TAG, componentDisplayName);
85
86             if (componentProperties != null && componentProperties.containsKey
87                 (componentDisplayName)) {
88               final String mandatory =
89                   getValueFromQuestionnaireDetails(componentProperties, componentDisplayName,
90                       MANDATORY);
91
92               boolean isServiceTemplateFilterNotExists = false;
93               if (!StringUtils.isEmpty(mandatory)) {
94                 Map innerProps = (Map<String, Object>) nodeTemplate.getProperties()
95                     .get(SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
96
97                 if (innerProps == null) {
98                   innerProps = new HashMap<String, Object>();
99                   isServiceTemplateFilterNotExists = true;
100                 }
101
102                 innerProps.put(MANDATORY, getValue(mandatory));
103
104                 if(isServiceTemplateFilterNotExists)
105                   nodeTemplate.getProperties().put(SERVICE_TEMPLATE_FILTER_PROPERTY_NAME,
106                     innerProps);
107               }
108
109               setProperty(nodeTemplate, HIGH_AVAIL_MODE, getValueFromQuestionnaireDetails
110                   (componentProperties, componentDisplayName, HIGH_AVAIL_MODE));
111
112               setProperty(nodeTemplate, VFC_NAMING_CODE, getValueFromQuestionnaireDetails
113                   (componentProperties, componentDisplayName, VFC_NAMING_CODE));
114
115               setProperty(nodeTemplate, VFC_CODE, getValueFromQuestionnaireDetails
116                   (componentProperties, componentDisplayName, VFC_CODE));
117
118               setProperty(nodeTemplate, VFC_FUNCTION, getValueFromQuestionnaireDetails
119                   (componentProperties, componentDisplayName, VFC_FUNCTION));
120
121               if(componentProperties.get(componentDisplayName).get(MIN_INSTANCES) != null) {
122                 nodeTemplate.getProperties().put(MIN_INSTANCES,
123                     componentProperties.get(componentDisplayName).get(MIN_INSTANCES));
124               }
125
126               if(componentProperties.get(componentDisplayName).get(MAX_INSTANCES) != null) {
127                 nodeTemplate.getProperties().put(MAX_INSTANCES,
128                     componentProperties.get(componentDisplayName).get(MAX_INSTANCES));
129               }
130             }
131
132             enrichRequirements(sourceToTargetDependencies, componentDisplayName, nodeTemplate,
133                 componentDisplayNameToNodeTempalteIds, serviceTemplate, toscaModel);
134           }
135         });
136     return errors;
137   }
138
139   private Map<String,List<String>> populateAllNodeTemplateIdForComponent(Map<String,
140       NodeTemplate> node_templates, ServiceTemplate serviceTemplate, ToscaServiceModel
141       toscaModel) {
142
143
144     Map<String,List<String>> componentDisplayNameToNodeTempalteIds = new HashMap<String,
145         List<String>>();
146
147     //set dependency target
148     node_templates.keySet()
149         .stream()
150         .forEach(nodeTemplateId -> {
151
152           final Optional<NodeTemplate> nodeTemplateById =
153               toscaAnalyzerService.getNodeTemplateById(serviceTemplate, nodeTemplateId);
154           final NodeTemplate nodeTemplate =
155               nodeTemplateById.isPresent() ? nodeTemplateById.get() : null;
156
157           if (toscaAnalyzerService.isTypeOf(nodeTemplate, VFC_ABSTRACT_SUBSTITUTE, serviceTemplate,
158               toscaModel)) {
159
160             String componentDisplayName = getComponentDisplayName(nodeTemplateId, nodeTemplate);
161
162             if (componentDisplayNameToNodeTempalteIds.containsKey(componentDisplayName)) {
163               componentDisplayNameToNodeTempalteIds.get(componentDisplayName).add(nodeTemplateId);
164             } else {
165               List<String> nodeTemplateIds = new ArrayList<String>();
166               nodeTemplateIds.add(nodeTemplateId);
167               componentDisplayNameToNodeTempalteIds.put(componentDisplayName, nodeTemplateIds);
168             }
169
170           }
171         });
172
173     return componentDisplayNameToNodeTempalteIds;
174   }
175
176   private void enrichRequirements(Map<String, List<String>> sourceToTargetDependencies,
177                                   String componentDisplayName, NodeTemplate nodeTemplate,
178                                   Map<String, List<String>> componentDisplayNameToNodeTempalteIds,
179                                   ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
180     final List<String> targets = sourceToTargetDependencies.get(componentDisplayName);
181     if (CollectionUtils.isEmpty(targets)) {
182       return;
183     }
184
185     for (String target : targets) {
186       List<String> targetNodeTemplateIds = componentDisplayNameToNodeTempalteIds.get(target);
187       if (CollectionUtils.isEmpty(targetNodeTemplateIds)) {
188         continue;
189       }
190       for (String targetNodeTemplateId : targetNodeTemplateIds) {
191         Optional<String> dependencyRequirementKey =
192             getDependencyRequirementKey(serviceTemplate, componentDisplayName, nodeTemplate, toscaServiceModel);
193         if (dependencyRequirementKey.isPresent()) {
194           RequirementAssignment requirementAssignment = new RequirementAssignment();
195           requirementAssignment.setCapability(NATIVE_NODE);
196           requirementAssignment.setRelationship(NATIVE_DEPENDS_ON);
197           requirementAssignment.setNode(targetNodeTemplateId);
198           DataModelUtil.addRequirementAssignment(nodeTemplate, dependencyRequirementKey.get(), requirementAssignment);
199         }
200       }
201     }
202   }
203
204   private Optional<String> getDependencyRequirementKey(ServiceTemplate serviceTemplate,
205                                                        String componentDisplayName,
206                                                        NodeTemplate nodeTemplate,
207                                                        ToscaServiceModel toscaServiceModel) {
208     String nodeType = nodeTemplate.getType();
209     NodeType flatNodeType = (NodeType) toscaAnalyzerService
210         .getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeType, serviceTemplate, toscaServiceModel);
211     List<Map<String, RequirementDefinition>> flatNodeTypeRequirements = flatNodeType.getRequirements();
212     if (Objects.isNull(flatNodeTypeRequirements)) {
213       return Optional.empty() ;
214     }
215     for (Map<String, RequirementDefinition> requirementDefinitionMap : flatNodeTypeRequirements) {
216       String requirementKey = requirementDefinitionMap.keySet().iterator().next();
217       String expectedKey = ToscaConstants.DEPENDS_ON_REQUIREMENT_ID + "_" + componentDisplayName;
218       if (requirementKey.equals(expectedKey)) {
219         return Optional.of(requirementKey);
220       }
221     }
222     return Optional.empty();
223   }
224
225   private String getComponentDisplayName(String nodeTemplateId, NodeTemplate nodeTemplate) {
226     String componentDisplayName = null;
227     if (nodeTemplateId.contains(ABSTRACT_NODE_TEMPLATE_ID_PREFIX)) {
228       String removedPrefix = nodeTemplateId.split(ABSTRACT_NODE_TEMPLATE_ID_PREFIX)[1];
229       final String[] removedSuffix = removedPrefix.split("_\\d");
230       componentDisplayName = removedSuffix[0];
231     } else {
232       final String type = nodeTemplate.getType();
233       final String[] splitted = type.split("\\.");
234       componentDisplayName = splitted[splitted.length - 1];
235
236     }
237     return componentDisplayName;
238   }
239
240   private String getValueFromQuestionnaireDetails(
241       Map<String, Map<String, Object>> componentTypetoParams, String componentDisplayName, String
242       propertyName) {
243     return (String) componentTypetoParams.get(componentDisplayName).get(propertyName);
244   }
245
246   private void setProperty(NodeTemplate nodeTemplate, String key, String value) {
247     if (!StringUtils.isEmpty(value)) {
248       //YamlUtil throws IllegalStateException("duplicate key: " + key) if key is already present.
249       // So first removing and then populating same key with new updated value
250       nodeTemplate.getProperties().remove(key);
251       nodeTemplate.getProperties().put(key, value);
252     }
253   }
254
255   private Boolean getValue(String value) {
256     String returnValue = null;
257     switch (value) {
258       case "YES" :
259         return true;
260       case "NO" :
261           return false;
262       default: return null;
263     }
264   }
265
266   private ComponentQuestionnaireData getComponentQuestionnaireData() {
267     if (componentQuestionnaireData == null) {
268       componentQuestionnaireData = new ComponentQuestionnaireData();
269     }
270     return componentQuestionnaireData;
271   }
272 }