2 * Copyright © 2016-2018 European Support Limited
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.openecomp.sdc.enrichment.impl.tosca;
19 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.HIGH_AVAIL_MODE;
20 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MANDATORY;
21 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MAX_INSTANCES;
22 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MIN_INSTANCES;
23 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VFC_CODE;
24 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.NFC_FUNCTION;
25 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.NFC_NAMING_CODE;
26 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VM_TYPE_TAG;
27 import static org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType.NATIVE_NODE;
28 import static org.openecomp.sdc.tosca.datatypes.ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE;
29 import static org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType.NATIVE_DEPENDS_ON;
30 import static org.openecomp.sdc.tosca.services.ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME;
31 import static org.openecomp.sdc.translator.services.heattotosca.Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX;
33 import org.apache.commons.collections4.CollectionUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.openecomp.sdc.datatypes.error.ErrorMessage;
36 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
37 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
38 import org.onap.sdc.tosca.datatypes.model.NodeType;
39 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
40 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
41 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
42 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
43 import org.openecomp.sdc.tosca.services.DataModelUtil;
44 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
45 import org.openecomp.sdc.tosca.services.ToscaConstants;
46 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
48 import java.util.ArrayList;
49 import java.util.HashMap;
50 import java.util.List;
52 import java.util.Objects;
53 import java.util.Optional;
55 import org.openecomp.sdc.versioning.dao.types.Version;
57 public class AbstractSubstituteToscaEnricher {
59 private ToscaAnalyzerService toscaAnalyzerService;
60 private ComponentQuestionnaireData componentQuestionnaireData;
63 public Map<String, List<ErrorMessage>> enrich(ToscaServiceModel toscaModel, String vspId, Version version) {
64 componentQuestionnaireData = getComponentQuestionnaireData();
65 toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
67 Map<String, Map<String, Object>> componentProperties =
68 componentQuestionnaireData.getPropertiesfromCompQuestionnaire(vspId, version);
70 final Map<String, List<String>> sourceToTargetDependencies = componentQuestionnaireData
71 .populateDependencies(vspId, version,
72 componentQuestionnaireData
73 .getSourceToTargetComponent());
74 Map<String, List<ErrorMessage>> errors = new HashMap<>();
76 final ServiceTemplate serviceTemplate =
77 toscaModel.getServiceTemplates().get(toscaModel.getEntryDefinitionServiceTemplate());
79 if (serviceTemplate == null) {
83 final Map<String, NodeTemplate> node_templates = serviceTemplate.getTopology_template().getNode_templates();
84 if (node_templates == null) {
88 final Map<String, List<String>> componentDisplayNameToNodeTempalteIds =
89 populateAllNodeTemplateIdForComponent(node_templates, serviceTemplate, toscaModel);
91 node_templates.keySet().stream().forEach(nodeTemplateId -> {
92 final Optional<NodeTemplate> nodeTemplateById =
93 toscaAnalyzerService.getNodeTemplateById(serviceTemplate, nodeTemplateId);
94 final NodeTemplate nodeTemplate = nodeTemplateById.isPresent() ? nodeTemplateById.get() : null;
96 if (toscaAnalyzerService.isTypeOf(nodeTemplate, VFC_ABSTRACT_SUBSTITUTE, serviceTemplate, toscaModel)) {
98 String componentDisplayName = getComponentDisplayName(nodeTemplateId, nodeTemplate);
100 setProperty(nodeTemplate, VM_TYPE_TAG, componentDisplayName);
102 if (componentProperties != null && componentProperties.containsKey(componentDisplayName)) {
103 final String mandatory =
104 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName, MANDATORY);
106 boolean isServiceTemplateFilterNotExists = false;
107 if (!StringUtils.isEmpty(mandatory)) {
108 Map innerProps = (Map<String, Object>) nodeTemplate.getProperties()
109 .get(SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
111 if (innerProps == null) {
112 innerProps = new HashMap<String, Object>();
113 isServiceTemplateFilterNotExists = true;
116 innerProps.put(MANDATORY, getValue(mandatory));
118 if (isServiceTemplateFilterNotExists) {
119 nodeTemplate.getProperties().put(SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
123 setProperty(nodeTemplate, HIGH_AVAIL_MODE,
124 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName,
127 setProperty(nodeTemplate, NFC_NAMING_CODE,
128 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName,
131 setProperty(nodeTemplate, VFC_CODE,
132 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName, VFC_CODE));
134 setProperty(nodeTemplate, NFC_FUNCTION,
135 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName, NFC_FUNCTION));
137 if (componentProperties.get(componentDisplayName).get(MIN_INSTANCES) != null) {
138 nodeTemplate.getProperties().put(MIN_INSTANCES,
139 componentProperties.get(componentDisplayName).get(MIN_INSTANCES));
142 if (componentProperties.get(componentDisplayName).get(MAX_INSTANCES) != null) {
143 nodeTemplate.getProperties().put(MAX_INSTANCES,
144 componentProperties.get(componentDisplayName).get(MAX_INSTANCES));
148 enrichRequirements(sourceToTargetDependencies, componentDisplayName, nodeTemplate,
149 componentDisplayNameToNodeTempalteIds, serviceTemplate, toscaModel);
155 private Map<String, List<String>> populateAllNodeTemplateIdForComponent(Map<String, NodeTemplate> node_templates,
156 ServiceTemplate serviceTemplate,
157 ToscaServiceModel toscaModel) {
160 Map<String, List<String>> componentDisplayNameToNodeTempalteIds = new HashMap<>();
162 //set dependency target
163 node_templates.keySet().stream().forEach(nodeTemplateId -> {
165 final Optional<NodeTemplate> nodeTemplateById =
166 toscaAnalyzerService.getNodeTemplateById(serviceTemplate, nodeTemplateId);
167 final NodeTemplate nodeTemplate = nodeTemplateById.isPresent() ? nodeTemplateById.get() : null;
169 if (toscaAnalyzerService.isTypeOf(nodeTemplate, VFC_ABSTRACT_SUBSTITUTE, serviceTemplate, toscaModel)) {
171 String componentDisplayName = getComponentDisplayName(nodeTemplateId, nodeTemplate);
173 if (componentDisplayNameToNodeTempalteIds.containsKey(componentDisplayName)) {
174 componentDisplayNameToNodeTempalteIds.get(componentDisplayName).add(nodeTemplateId);
176 List<String> nodeTemplateIds = new ArrayList<>();
177 nodeTemplateIds.add(nodeTemplateId);
178 componentDisplayNameToNodeTempalteIds.put(componentDisplayName, nodeTemplateIds);
184 return componentDisplayNameToNodeTempalteIds;
187 private void enrichRequirements(Map<String, List<String>> sourceToTargetDependencies, String componentDisplayName,
188 NodeTemplate nodeTemplate,
189 Map<String, List<String>> componentDisplayNameToNodeTempalteIds,
190 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
191 final List<String> targets = sourceToTargetDependencies.get(componentDisplayName);
192 if (CollectionUtils.isEmpty(targets)) {
196 for (String target : targets) {
197 List<String> targetNodeTemplateIds = componentDisplayNameToNodeTempalteIds.get(target);
198 if (CollectionUtils.isEmpty(targetNodeTemplateIds)) {
201 for (String targetNodeTemplateId : targetNodeTemplateIds) {
202 Optional<String> dependencyRequirementKey =
203 getDependencyRequirementKey(serviceTemplate, componentDisplayName, nodeTemplate,
205 if (dependencyRequirementKey.isPresent()) {
206 RequirementAssignment requirementAssignment = new RequirementAssignment();
207 requirementAssignment.setCapability(NATIVE_NODE);
208 requirementAssignment.setRelationship(NATIVE_DEPENDS_ON);
209 requirementAssignment.setNode(targetNodeTemplateId);
210 DataModelUtil.addRequirementAssignment(nodeTemplate, dependencyRequirementKey.get(),
211 requirementAssignment);
217 private Optional<String> getDependencyRequirementKey(ServiceTemplate serviceTemplate, String componentDisplayName,
218 NodeTemplate nodeTemplate,
219 ToscaServiceModel toscaServiceModel) {
220 String nodeType = nodeTemplate.getType();
221 NodeType flatNodeType = (NodeType) toscaAnalyzerService.getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeType,
222 serviceTemplate, toscaServiceModel).getFlatEntity();
223 List<Map<String, RequirementDefinition>> flatNodeTypeRequirements = flatNodeType.getRequirements();
224 if (Objects.isNull(flatNodeTypeRequirements)) {
225 return Optional.empty();
227 for (Map<String, RequirementDefinition> requirementDefinitionMap : flatNodeTypeRequirements) {
228 String requirementKey = requirementDefinitionMap.keySet().iterator().next();
229 String expectedKey = ToscaConstants.DEPENDS_ON_REQUIREMENT_ID + "_" + componentDisplayName;
230 if (requirementKey.equals(expectedKey)) {
231 return Optional.of(requirementKey);
234 return Optional.empty();
237 private String getComponentDisplayName(String nodeTemplateId, NodeTemplate nodeTemplate) {
238 String componentDisplayName;
239 if (nodeTemplateId.contains(ABSTRACT_NODE_TEMPLATE_ID_PREFIX)) {
240 String removedPrefix = nodeTemplateId.split(ABSTRACT_NODE_TEMPLATE_ID_PREFIX)[1];
241 final String[] removedSuffix = removedPrefix.split("_\\d");
242 componentDisplayName = removedSuffix[0];
244 final String type = nodeTemplate.getType();
245 final String[] splitted = type.split("\\.");
246 componentDisplayName = splitted[splitted.length - 1];
249 return componentDisplayName;
252 private String getValueFromQuestionnaireDetails(Map<String, Map<String, Object>> componentTypetoParams,
253 String componentDisplayName, String propertyName) {
254 return (String) componentTypetoParams.get(componentDisplayName).get(propertyName);
257 private void setProperty(NodeTemplate nodeTemplate, String key, String value) {
258 if (!StringUtils.isEmpty(value)) {
259 //YamlUtil throws IllegalStateException("duplicate key: " + key) if key is already present.
260 // So first removing and then populating same key with new updated value
261 nodeTemplate.getProperties().remove(key);
262 nodeTemplate.getProperties().put(key, value);
266 private Boolean getValue(String value) {
267 String returnValue = null;
278 private ComponentQuestionnaireData getComponentQuestionnaireData() {
279 if (componentQuestionnaireData == null) {
280 componentQuestionnaireData = new ComponentQuestionnaireData();
282 return componentQuestionnaireData;