2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.openecomp.sdc.common.errors.CoreException;
25 import org.openecomp.sdc.datatypes.error.ErrorLevel;
26 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
27 import org.openecomp.sdc.heat.datatypes.model.Resource;
28 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
29 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
30 import org.openecomp.sdc.logging.types.LoggerConstants;
31 import org.openecomp.sdc.logging.types.LoggerErrorCode;
32 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
33 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
34 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
35 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
36 import org.openecomp.sdc.tosca.datatypes.ToscaTopologyTemplateElements;
37 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
38 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
39 import org.openecomp.sdc.tosca.services.DataModelUtil;
40 import org.openecomp.sdc.tosca.services.ToscaConstants;
41 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
42 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
43 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
44 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationEntityType;
45 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
46 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
47 import org.openecomp.sdc.translator.services.heattotosca.errors.DuplicateResourceIdsInDifferentFilesErrorBuilder;
48 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
52 import java.util.ArrayList;
53 import java.util.HashMap;
54 import java.util.HashSet;
55 import java.util.List;
57 import java.util.Objects;
58 import java.util.Optional;
60 import java.util.function.Predicate;
61 import java.util.stream.Collectors;
63 public abstract class ResourceTranslationBase {
65 protected static Logger logger = (Logger) LoggerFactory.getLogger(ResourceTranslationBase.class);
66 protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
68 protected abstract void translate(TranslateTo translateTo);
73 * @param heatFileName the heat file name
74 * @param serviceTemplate the service template
75 * @param heatOrchestrationTemplate the heat orchestration template
76 * @param resource the resource
77 * @param resourceId the resource id
78 * @param context the context
79 * @return the translated id if this resource is supported, or empty value if not supported
81 public Optional<String> translateResource(String heatFileName, ServiceTemplate serviceTemplate,
82 HeatOrchestrationTemplate heatOrchestrationTemplate,
83 Resource resource, String resourceId,
84 TranslationContext context) {
86 mdcDataDebugMessage.debugEntryMessage("file, resource", heatFileName, resourceId);
87 Optional<String> translatedId =
88 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
89 context.getTranslatedResources().putIfAbsent(heatFileName, new HashSet<>());
91 if(isResourceWithSameIdAppearsInOtherFiles(heatFileName, resourceId, context)){
92 throw new CoreException(
93 new DuplicateResourceIdsInDifferentFilesErrorBuilder(resourceId).build());
95 if (context.getTranslatedResources().get(heatFileName).contains(resourceId)) {
98 if (!translatedId.isPresent()) {
99 return Optional.empty();
101 logger.debug("Translate- file:" + heatFileName + " resource Id:" + resourceId
102 + " translated resource id:" + translatedId.get());
103 TranslateTo translateTo = new TranslateTo(heatFileName, serviceTemplate,
104 heatOrchestrationTemplate, resource, resourceId, translatedId.get(), context);
105 translate(translateTo);
106 context.getTranslatedResources().get(heatFileName).add(resourceId);
108 if (DataModelUtil.isNodeTemplate(translatedId.get(), serviceTemplate)) {
109 if (!context.getHeatStackGroupMembers().containsKey(heatFileName)) {
110 context.getHeatStackGroupMembers().put(heatFileName, new HashSet<>());
112 context.getHeatStackGroupMembers().get(heatFileName).add(translatedId.get());
113 updateResourceDependency(translateTo);
116 mdcDataDebugMessage.debugExitMessage("file, resource", heatFileName, resourceId);
120 private boolean isResourceWithSameIdAppearsInOtherFiles(String heatFileName,
122 TranslationContext context){
123 Set<String> translatedResourceIdsFromOtherFiles =
124 context.getTranslatedResourceIdsFromOtherFiles(heatFileName);
126 return CollectionUtils.isNotEmpty(translatedResourceIdsFromOtherFiles)
127 && translatedResourceIdsFromOtherFiles.contains(resourceId);
131 * Gets resource translated id.
133 * @param heatFileName the heat file name
134 * @param heatOrchestrationTemplate the heat orchestration template
135 * @param resourceId the resource id
136 * @param context the context
137 * @return the resource translated id
139 public static Optional<String> getResourceTranslatedId(String heatFileName,
140 HeatOrchestrationTemplate
141 heatOrchestrationTemplate,
143 TranslationContext context) {
146 mdcDataDebugMessage.debugEntryMessage(null, null);
148 if (!context.getTranslatedIds().containsKey(heatFileName)) {
149 context.getTranslatedIds().put(heatFileName, new HashMap<>());
152 Map<String, String> translatedIdsPerFile = context.getTranslatedIds().get(heatFileName);
153 String translatedId = translatedIdsPerFile.get(resourceId);
154 if (translatedId != null) {
155 return Optional.of(translatedId);
158 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
159 if (resource == null) {
160 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
161 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
162 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
163 throw new CoreException(
164 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
167 mdcDataDebugMessage.debugExitMessage(null, null);
168 return getTranslatedResourceId(resourceId, heatFileName, resource, heatOrchestrationTemplate,
173 private static Optional<String> getTranslatedResourceId(String resourceId,
176 HeatOrchestrationTemplate heatOrchestrationTemplate,
177 TranslationContext context) {
178 TranslateTo translateTo =
179 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
182 String translatedId =
183 ResourceTranslationFactory.getInstance(resource).generateTranslatedId(translateTo);
185 if (ConsolidationDataUtil.isNodeTemplatePointsToServiceTemplateWithoutNodeTemplates
186 (translatedId, heatFileName, context)) {
187 return Optional.empty();
190 if (translatedId != null) {
191 context.getTranslatedIds().get(heatFileName).put(resourceId, translatedId);
194 return Optional.ofNullable(translatedId);
199 * Gets resource translated element template.
201 * @param heatFileName the heat file name
202 * @param heatOrchestrationTemplate the heat orchestration template
203 * @param resourceId the resource id
204 * @param context the context
205 * @return the resource translated element template
207 public static Optional<ToscaTopologyTemplateElements> getResourceTranslatedElementTemplate(
209 HeatOrchestrationTemplate heatOrchestrationTemplate,
210 String resourceId, TranslationContext context) {
212 mdcDataDebugMessage.debugEntryMessage(null, null);
214 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
215 if (resource == null) {
216 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
217 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
218 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
219 throw new CoreException(
220 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
222 TranslateTo translateTo =
223 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
226 Optional<ToscaTopologyTemplateElements> translatedElementTemplate =
227 ResourceTranslationFactory.getInstance(resource)
228 .getTranslatedToscaTopologyElement(translateTo);
230 mdcDataDebugMessage.debugExitMessage(null, null);
231 return translatedElementTemplate;
234 protected String generateTranslatedId(TranslateTo translateTo) {
235 if (isEssentialRequirementsValid(translateTo)) {
236 return translateTo.getResourceId();
243 protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
244 TranslateTo translateTo) {
245 if (isEssentialRequirementsValid(translateTo)) {
246 return Optional.of(ToscaTopologyTemplateElements.NODE_TEMPLATE);
248 return Optional.empty();
252 protected boolean isEssentialRequirementsValid(TranslateTo translateTo) {
256 private static TranslateTo generateTranslationTo(String heatFileName,
257 ServiceTemplate serviceTemplate,
258 HeatOrchestrationTemplate
259 heatOrchestrationTemplate,
260 Resource resource, String resourceId,
262 TranslationContext context) {
263 TranslateTo to = new TranslateTo();
264 to.setHeatFileName(heatFileName);
265 to.setServiceTemplate(serviceTemplate);
266 to.setHeatOrchestrationTemplate(heatOrchestrationTemplate);
267 to.setResource(resource);
268 to.setResourceId(resourceId);
269 to.setTranslatedId(translatedId);
270 to.setContext(context);
274 private void updateResourceDependency(TranslateTo translateTo) {
276 String heatFileName = translateTo.getHeatFileName();
277 mdcDataDebugMessage.debugEntryMessage("file", heatFileName);
279 Resource resource = translateTo.getResource();
280 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
281 .getHeatOrchestrationTemplate();
282 String translatedId = translateTo.getTranslatedId();
283 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
284 TranslationContext context = translateTo.getContext();
285 if (resource.getDepends_on() == null) {
289 if (resource.getDepends_on() instanceof List) {
290 List<String> dependsOnList = (List<String>) resource.getDepends_on();
291 for (String dependsOnResourceId : dependsOnList) {
292 addDependOnRequirement(dependsOnResourceId, translateTo);
295 String dependsOnResourceId = (String) resource.getDepends_on();
296 addDependOnRequirement(dependsOnResourceId, translateTo);
299 mdcDataDebugMessage.debugExitMessage("file", heatFileName);
302 private void addDependOnRequirement(String dependsOnResourceId, TranslateTo translateTo) {
304 mdcDataDebugMessage.debugEntryMessage(null, null);
305 String nodeTemplateId = translateTo.getTranslatedId();
306 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
307 String heatFileName = translateTo.getHeatFileName();
308 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
309 .getHeatOrchestrationTemplate();
310 TranslationContext context = translateTo.getContext();
311 RequirementAssignment requirementAssignment = new RequirementAssignment();
312 Optional<String> resourceTranslatedId =
313 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, dependsOnResourceId,
316 Optional<ToscaTopologyTemplateElements> resourceTranslatedElementTemplate =
317 getResourceTranslatedElementTemplate(heatFileName, heatOrchestrationTemplate,
318 dependsOnResourceId, context);
320 if (resourceTranslatedId.isPresent()
321 && (resourceTranslatedElementTemplate.isPresent() && resourceTranslatedElementTemplate
322 .get() == ToscaTopologyTemplateElements.NODE_TEMPLATE)) {
323 Resource sourceResource = translateTo.getResource();
324 Resource targetResource = HeatToToscaUtil
325 .getResource(heatOrchestrationTemplate, dependsOnResourceId,
326 translateTo.getHeatFileName());
328 .isValidDependsOnCandidate(heatOrchestrationTemplate, sourceResource, targetResource,
329 ConsolidationEntityType.OTHER, translateTo.getContext())) {
330 requirementAssignment.setNode(resourceTranslatedId.get());
331 requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NODE);
332 requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_DEPENDS_ON);
333 DataModelUtil.addRequirementAssignment(
334 serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId),
335 ToscaConstants.DEPENDS_ON_REQUIREMENT_ID, requirementAssignment);
336 Resource dependsOnResource = targetResource;
337 ConsolidationDataUtil
338 .updateNodesConnectedData(translateTo, dependsOnResourceId, dependsOnResource,
339 sourceResource, nodeTemplateId, ToscaConstants.DEPENDS_ON_REQUIREMENT_ID,
340 requirementAssignment);
343 mdcDataDebugMessage.debugExitMessage(null, null);
346 Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
348 HeatOrchestrationTemplate heatOrchestrationTemplate,
349 String translatedResourceId,
350 TranslateTo translateTo,
351 String heatResourceType) {
352 mdcDataDebugMessage.debugEntryMessage(null, null);
353 List<Map.Entry<String, Resource>> list = heatOrchestrationTemplate.getResources().entrySet()
355 .filter(entry -> getPredicatesForTranslatedIdToResourceId(heatFileName,
356 heatOrchestrationTemplate, translatedResourceId, translateTo.getContext(),
359 .allMatch(p -> p.test(entry)))
360 .collect(Collectors.toList());
361 if (CollectionUtils.isEmpty(list)) {
362 mdcDataDebugMessage.debugExitMessage(null, null);
363 return Optional.empty();
365 mdcDataDebugMessage.debugExitMessage(null, null);
366 return Optional.of(list);
370 private List<Predicate<Map.Entry<String, Resource>>> getPredicatesForTranslatedIdToResourceId(
371 String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
372 String translatedResourceId, TranslationContext context, String heatResourceType) {
373 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
375 entry.getValue().getType().equals(heatResourceType));
377 Optional<String> resourceTranslatedId =
378 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, entry.getKey(), context);
379 return resourceTranslatedId.isPresent()
380 && resourceTranslatedId.get().equals(translatedResourceId);
385 boolean isResourceTypeSupported(Resource resource, List<String> supporteTypes) {
386 return Objects.nonNull(resource) && supporteTypes.contains(resource.getType());