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 org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.lang3.StringUtils;
21 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
22 import org.onap.sdc.tosca.datatypes.model.NodeType;
23 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
24 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
25 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
26 import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
27 import org.openecomp.sdc.datatypes.error.ErrorMessage;
28 import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes;
29 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
30 import org.openecomp.sdc.tosca.services.DataModelUtil;
31 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
32 import org.openecomp.sdc.tosca.services.ToscaConstants;
33 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
34 import org.openecomp.sdc.versioning.dao.types.Version;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.List;
40 import java.util.Objects;
41 import java.util.Optional;
43 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.HIGH_AVAIL_MODE;
44 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MANDATORY;
45 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MAX_INSTANCES;
46 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.MIN_INSTANCES;
47 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.NFC_FUNCTION;
48 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.NFC_NAMING_CODE;
49 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VFC_CODE;
50 import static org.openecomp.sdc.enrichment.impl.util.EnrichmentConstants.VM_TYPE_TAG;
51 import static org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType.NATIVE_NODE;
52 import static org.openecomp.sdc.tosca.datatypes.ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE;
53 import static org.openecomp.sdc.tosca.datatypes.ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE;
54 import static org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType.NATIVE_DEPENDS_ON;
55 import static org.openecomp.sdc.tosca.services.ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME;
56 import static org.openecomp.sdc.translator.services.heattotosca.Constants.VNF_NODE_TEMPLATE_ID_SUFFIX;
58 public class AbstractSubstituteToscaEnricher {
60 private ToscaAnalyzerService toscaAnalyzerService;
61 private ComponentQuestionnaireData componentQuestionnaireData;
64 public Map<String, List<ErrorMessage>> enrich(ToscaServiceModel toscaModel, String vspId, Version version) {
65 componentQuestionnaireData = getComponentQuestionnaireData();
66 toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
68 Map<String, Map<String, Object>> componentProperties =
69 componentQuestionnaireData.getPropertiesfromCompQuestionnaire(vspId, version);
71 final Map<String, List<String>> sourceToTargetDependencies = componentQuestionnaireData
72 .populateDependencies(vspId, version,
73 componentQuestionnaireData
74 .getSourceToTargetComponent());
75 Map<String, List<ErrorMessage>> errors = new HashMap<>();
77 final ServiceTemplate serviceTemplate =
78 toscaModel.getServiceTemplates().get(toscaModel.getEntryDefinitionServiceTemplate());
80 if (serviceTemplate == null) {
84 final TopologyTemplate topologyTemplate = serviceTemplate.getTopology_template();
85 if (topologyTemplate == null) {
89 final Map<String, NodeTemplate> nodeTemplates = serviceTemplate.getTopology_template().getNode_templates();
90 if (nodeTemplates == null) {
94 final Map<String, List<String>> componentDisplayNameToNodeTemplateIds =
95 populateAllNodeTemplateIdForComponent(nodeTemplates, serviceTemplate, toscaModel);
97 nodeTemplates.keySet().forEach(nodeTemplateId -> {
98 final NodeTemplate nodeTemplate =
99 toscaAnalyzerService.getNodeTemplateById(serviceTemplate, nodeTemplateId).orElse(null);
101 if (nodeTemplate != null && toscaAnalyzerService.isTypeOf(nodeTemplate, VFC_ABSTRACT_SUBSTITUTE,
102 serviceTemplate, toscaModel)) {
104 String componentDisplayName = getComponentDisplayName(nodeTemplateId, nodeTemplate);
106 enrichProperties(nodeTemplate, componentDisplayName, componentProperties);
108 enrichRequirements(sourceToTargetDependencies, componentDisplayName, nodeTemplate,
109 componentDisplayNameToNodeTemplateIds, serviceTemplate, toscaModel);
115 private void enrichProperties(NodeTemplate nodeTemplate, String componentDisplayName,
116 Map<String, Map<String, Object>> componentProperties) {
117 setProperty(nodeTemplate, VM_TYPE_TAG, componentDisplayName);
119 if (componentProperties != null && componentProperties.containsKey(componentDisplayName)) {
120 final String mandatory =
121 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName, MANDATORY);
123 boolean isServiceTemplateFilterNotExists = false;
124 if (!StringUtils.isEmpty(mandatory)) {
125 Map<String, Object> innerProps = (Map<String, Object>) nodeTemplate.getProperties()
126 .get(SERVICE_TEMPLATE_FILTER_PROPERTY_NAME);
128 if (innerProps == null) {
129 innerProps = new HashMap<>();
130 isServiceTemplateFilterNotExists = true;
132 Optional<Boolean> mandatoryValue = getValue(mandatory);
133 if (mandatoryValue.isPresent()) {
134 innerProps.put(MANDATORY, mandatoryValue.get());
137 if (isServiceTemplateFilterNotExists) {
138 nodeTemplate.getProperties().put(SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
142 setProperty(nodeTemplate, HIGH_AVAIL_MODE,
143 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName,
146 setProperty(nodeTemplate, NFC_NAMING_CODE,
147 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName,
150 setProperty(nodeTemplate, VFC_CODE,
151 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName, VFC_CODE));
153 setProperty(nodeTemplate, NFC_FUNCTION,
154 getValueFromQuestionnaireDetails(componentProperties, componentDisplayName, NFC_FUNCTION));
156 if (componentProperties.get(componentDisplayName).get(MIN_INSTANCES) != null) {
157 nodeTemplate.getProperties().put(MIN_INSTANCES,
158 componentProperties.get(componentDisplayName).get(MIN_INSTANCES));
161 if (componentProperties.get(componentDisplayName).get(MAX_INSTANCES) != null) {
162 nodeTemplate.getProperties().put(MAX_INSTANCES,
163 componentProperties.get(componentDisplayName).get(MAX_INSTANCES));
168 private Map<String, List<String>> populateAllNodeTemplateIdForComponent(Map<String, NodeTemplate> nodeTemplates,
169 ServiceTemplate serviceTemplate,
170 ToscaServiceModel toscaModel) {
173 Map<String, List<String>> componentDisplayNameToNodeTempalteIds = new HashMap<>();
175 //set dependency target
176 nodeTemplates.keySet().forEach(nodeTemplateId -> {
177 final NodeTemplate nodeTemplate =
178 toscaAnalyzerService.getNodeTemplateById(serviceTemplate, nodeTemplateId).orElse(null);
180 if (nodeTemplate != null &&
181 toscaAnalyzerService.isTypeOf(nodeTemplate, VFC_ABSTRACT_SUBSTITUTE, serviceTemplate, toscaModel)) {
183 String componentDisplayName = getComponentDisplayName(nodeTemplateId, nodeTemplate);
185 if (componentDisplayNameToNodeTempalteIds.containsKey(componentDisplayName)) {
186 componentDisplayNameToNodeTempalteIds.get(componentDisplayName).add(nodeTemplateId);
188 List<String> nodeTemplateIds = new ArrayList<>();
189 nodeTemplateIds.add(nodeTemplateId);
190 componentDisplayNameToNodeTempalteIds.put(componentDisplayName, nodeTemplateIds);
196 return componentDisplayNameToNodeTempalteIds;
199 private void enrichRequirements(Map<String, List<String>> sourceToTargetDependencies, String componentDisplayName,
200 NodeTemplate nodeTemplate,
201 Map<String, List<String>> componentDisplayNameToNodeTempalteIds,
202 ServiceTemplate serviceTemplate, ToscaServiceModel toscaServiceModel) {
203 final List<String> targets = sourceToTargetDependencies.get(componentDisplayName);
204 if (CollectionUtils.isEmpty(targets)) {
208 for (String target : targets) {
209 List<String> targetNodeTemplateIds = componentDisplayNameToNodeTempalteIds.get(target);
210 if (CollectionUtils.isEmpty(targetNodeTemplateIds)) {
213 for (String targetNodeTemplateId : targetNodeTemplateIds) {
214 Optional<String> dependencyRequirementKey =
215 getDependencyRequirementKey(serviceTemplate, componentDisplayName, nodeTemplate,
217 if (dependencyRequirementKey.isPresent()) {
218 RequirementAssignment requirementAssignment = new RequirementAssignment();
219 requirementAssignment.setCapability(NATIVE_NODE);
220 requirementAssignment.setRelationship(NATIVE_DEPENDS_ON);
221 requirementAssignment.setNode(targetNodeTemplateId);
222 DataModelUtil.addRequirementAssignment(nodeTemplate, dependencyRequirementKey.get(),
223 requirementAssignment);
229 private Optional<String> getDependencyRequirementKey(ServiceTemplate serviceTemplate, String componentDisplayName,
230 NodeTemplate nodeTemplate,
231 ToscaServiceModel toscaServiceModel) {
232 String nodeType = nodeTemplate.getType();
233 NodeType flatNodeType = (NodeType) toscaAnalyzerService.getFlatEntity(ToscaElementTypes.NODE_TYPE, nodeType,
234 serviceTemplate, toscaServiceModel).getFlatEntity();
235 List<Map<String, RequirementDefinition>> flatNodeTypeRequirements = flatNodeType.getRequirements();
236 if (Objects.isNull(flatNodeTypeRequirements)) {
237 return Optional.empty();
239 for (Map<String, RequirementDefinition> requirementDefinitionMap : flatNodeTypeRequirements) {
240 String requirementKey = requirementDefinitionMap.keySet().iterator().next();
241 String expectedKey = ToscaConstants.DEPENDS_ON_REQUIREMENT_ID + "_" + componentDisplayName;
242 if (requirementKey.equals(expectedKey)) {
243 return Optional.of(requirementKey);
246 return Optional.empty();
249 private String getComponentDisplayName(String nodeTemplateId, NodeTemplate nodeTemplate) {
250 String componentDisplayName;
251 final String type = nodeTemplate.getType();
252 if (MULTIDEPLOYMENTFLAVOR_NODE_TYPE.equals(type)) {
253 componentDisplayName = nodeTemplateId.substring(0, nodeTemplateId.lastIndexOf(VNF_NODE_TEMPLATE_ID_SUFFIX));
255 String vmType = DataModelUtil.getNamespaceSuffix(type);
256 final String[] removedSuffix = vmType.split("_\\d+");
257 componentDisplayName = removedSuffix[0];
259 return componentDisplayName;
262 private String getValueFromQuestionnaireDetails(Map<String, Map<String, Object>> componentTypetoParams,
263 String componentDisplayName, String propertyName) {
264 return (String) componentTypetoParams.get(componentDisplayName).get(propertyName);
267 private void setProperty(NodeTemplate nodeTemplate, String key, String value) {
268 if (!StringUtils.isEmpty(value)) {
269 //YamlUtil throws IllegalStateException("duplicate key: " + key) if key is already present.
270 // So first removing and then populating same key with new updated value
271 nodeTemplate.getProperties().remove(key);
272 nodeTemplate.getProperties().put(key, value);
276 private Optional<Boolean> getValue(String value) {
279 return Optional.of(Boolean.TRUE);
281 return Optional.of(Boolean.FALSE);
283 return Optional.empty();
287 private ComponentQuestionnaireData getComponentQuestionnaireData() {
288 if (componentQuestionnaireData == null) {
289 componentQuestionnaireData = new ComponentQuestionnaireData();
291 return componentQuestionnaireData;