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.ResourceNotFoundInHeatFileErrorBuilder;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
51 import java.util.ArrayList;
52 import java.util.HashMap;
53 import java.util.HashSet;
54 import java.util.List;
56 import java.util.Objects;
57 import java.util.Optional;
58 import java.util.function.Predicate;
59 import java.util.stream.Collectors;
61 public abstract class ResourceTranslationBase {
63 protected static Logger logger = (Logger) LoggerFactory.getLogger(ResourceTranslationBase.class);
64 protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
66 protected abstract void translate(TranslateTo translateTo);
71 * @param heatFileName the heat file name
72 * @param serviceTemplate the service template
73 * @param heatOrchestrationTemplate the heat orchestration template
74 * @param resource the resource
75 * @param resourceId the resource id
76 * @param context the context
77 * @return the translated id if this resource is supported, or empty value if not supported
79 public Optional<String> translateResource(String heatFileName, ServiceTemplate serviceTemplate,
80 HeatOrchestrationTemplate heatOrchestrationTemplate,
81 Resource resource, String resourceId,
82 TranslationContext context) {
84 mdcDataDebugMessage.debugEntryMessage("file, resource", heatFileName, resourceId);
85 Optional<String> translatedId =
86 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
87 context.getTranslatedResources().putIfAbsent(heatFileName, new HashSet<>());
88 if (context.getTranslatedResources().get(heatFileName).contains(resourceId)) {
91 if (!translatedId.isPresent()) {
92 return Optional.empty();
94 logger.debug("Translate- file:" + heatFileName + " resource Id:" + resourceId
95 + " translated resource id:" + translatedId.get());
96 TranslateTo translateTo = new TranslateTo(heatFileName, serviceTemplate,
97 heatOrchestrationTemplate, resource, resourceId, translatedId.get(), context);
98 translate(translateTo);
99 context.getTranslatedResources().get(heatFileName).add(resourceId);
101 if (DataModelUtil.isNodeTemplate(translatedId.get(), serviceTemplate)) {
102 if (!context.getHeatStackGroupMembers().containsKey(heatFileName)) {
103 context.getHeatStackGroupMembers().put(heatFileName, new HashSet<>());
105 context.getHeatStackGroupMembers().get(heatFileName).add(translatedId.get());
106 updateResourceDependency(translateTo);
109 mdcDataDebugMessage.debugExitMessage("file, resource", heatFileName, resourceId);
114 * Gets resource translated id.
116 * @param heatFileName the heat file name
117 * @param heatOrchestrationTemplate the heat orchestration template
118 * @param resourceId the resource id
119 * @param context the context
120 * @return the resource translated id
122 public static Optional<String> getResourceTranslatedId(String heatFileName,
123 HeatOrchestrationTemplate
124 heatOrchestrationTemplate,
126 TranslationContext context) {
129 mdcDataDebugMessage.debugEntryMessage(null, null);
131 if (!context.getTranslatedIds().containsKey(heatFileName)) {
132 context.getTranslatedIds().put(heatFileName, new HashMap<>());
135 Map<String, String> translatedIdsPerFile = context.getTranslatedIds().get(heatFileName);
136 String translatedId = translatedIdsPerFile.get(resourceId);
137 if (translatedId != null) {
138 return Optional.of(translatedId);
141 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
142 if (resource == null) {
143 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
144 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
145 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
146 throw new CoreException(
147 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
150 mdcDataDebugMessage.debugExitMessage(null, null);
151 return getTranslatedResourceId(resourceId, heatFileName, resource, heatOrchestrationTemplate,
156 private static Optional<String> getTranslatedResourceId(String resourceId,
159 HeatOrchestrationTemplate heatOrchestrationTemplate,
160 TranslationContext context) {
161 TranslateTo translateTo =
162 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
165 String translatedId =
166 ResourceTranslationFactory.getInstance(resource).generateTranslatedId(translateTo);
168 if (ConsolidationDataUtil.isNodeTemplatePointsToServiceTemplateWithoutNodeTemplates
169 (translatedId, heatFileName, context)) {
170 return Optional.empty();
173 if (translatedId != null) {
174 context.getTranslatedIds().get(heatFileName).put(resourceId, translatedId);
177 return Optional.ofNullable(translatedId);
182 * Gets resource translated element template.
184 * @param heatFileName the heat file name
185 * @param heatOrchestrationTemplate the heat orchestration template
186 * @param resourceId the resource id
187 * @param context the context
188 * @return the resource translated element template
190 public static Optional<ToscaTopologyTemplateElements> getResourceTranslatedElementTemplate(
192 HeatOrchestrationTemplate heatOrchestrationTemplate,
193 String resourceId, TranslationContext context) {
195 mdcDataDebugMessage.debugEntryMessage(null, null);
197 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
198 if (resource == null) {
199 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
200 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
201 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
202 throw new CoreException(
203 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
205 TranslateTo translateTo =
206 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
209 Optional<ToscaTopologyTemplateElements> translatedElementTemplate =
210 ResourceTranslationFactory.getInstance(resource)
211 .getTranslatedToscaTopologyElement(translateTo);
213 mdcDataDebugMessage.debugExitMessage(null, null);
214 return translatedElementTemplate;
217 protected String generateTranslatedId(TranslateTo translateTo) {
218 if (isEssentialRequirementsValid(translateTo)) {
219 return translateTo.getResourceId();
226 protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
227 TranslateTo translateTo) {
228 if (isEssentialRequirementsValid(translateTo)) {
229 return Optional.of(ToscaTopologyTemplateElements.NODE_TEMPLATE);
231 return Optional.empty();
235 protected boolean isEssentialRequirementsValid(TranslateTo translateTo) {
239 private static TranslateTo generateTranslationTo(String heatFileName,
240 ServiceTemplate serviceTemplate,
241 HeatOrchestrationTemplate
242 heatOrchestrationTemplate,
243 Resource resource, String resourceId,
245 TranslationContext context) {
246 TranslateTo to = new TranslateTo();
247 to.setHeatFileName(heatFileName);
248 to.setServiceTemplate(serviceTemplate);
249 to.setHeatOrchestrationTemplate(heatOrchestrationTemplate);
250 to.setResource(resource);
251 to.setResourceId(resourceId);
252 to.setTranslatedId(translatedId);
253 to.setContext(context);
257 private void updateResourceDependency(TranslateTo translateTo) {
259 String heatFileName = translateTo.getHeatFileName();
260 mdcDataDebugMessage.debugEntryMessage("file", heatFileName);
262 Resource resource = translateTo.getResource();
263 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
264 .getHeatOrchestrationTemplate();
265 String translatedId = translateTo.getTranslatedId();
266 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
267 TranslationContext context = translateTo.getContext();
268 if (resource.getDepends_on() == null) {
272 if (resource.getDepends_on() instanceof List) {
273 List<String> dependsOnList = (List<String>) resource.getDepends_on();
274 for (String dependsOnResourceId : dependsOnList) {
275 addDependOnRequirement(dependsOnResourceId, translateTo);
278 String dependsOnResourceId = (String) resource.getDepends_on();
279 addDependOnRequirement(dependsOnResourceId, translateTo);
282 mdcDataDebugMessage.debugExitMessage("file", heatFileName);
285 private void addDependOnRequirement(String dependsOnResourceId, TranslateTo translateTo) {
287 mdcDataDebugMessage.debugEntryMessage(null, null);
288 String nodeTemplateId = translateTo.getTranslatedId();
289 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
290 String heatFileName = translateTo.getHeatFileName();
291 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
292 .getHeatOrchestrationTemplate();
293 TranslationContext context = translateTo.getContext();
294 RequirementAssignment requirementAssignment = new RequirementAssignment();
295 Optional<String> resourceTranslatedId =
296 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, dependsOnResourceId,
299 Optional<ToscaTopologyTemplateElements> resourceTranslatedElementTemplate =
300 getResourceTranslatedElementTemplate(heatFileName, heatOrchestrationTemplate,
301 dependsOnResourceId, context);
303 if (resourceTranslatedId.isPresent()
304 && (resourceTranslatedElementTemplate.isPresent() && resourceTranslatedElementTemplate
305 .get() == ToscaTopologyTemplateElements.NODE_TEMPLATE)) {
306 Resource sourceResource = translateTo.getResource();
307 Resource targetResource = HeatToToscaUtil
308 .getResource(heatOrchestrationTemplate, dependsOnResourceId,
309 translateTo.getHeatFileName());
311 .isValidDependsOnCandidate(heatOrchestrationTemplate, sourceResource, targetResource,
312 ConsolidationEntityType.OTHER, translateTo.getContext())) {
313 requirementAssignment.setNode(resourceTranslatedId.get());
314 requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NODE);
315 requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_DEPENDS_ON);
316 DataModelUtil.addRequirementAssignment(
317 serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId),
318 ToscaConstants.DEPENDS_ON_REQUIREMENT_ID, requirementAssignment);
319 Resource dependsOnResource = targetResource;
320 ConsolidationDataUtil
321 .updateNodesConnectedData(translateTo, dependsOnResourceId, dependsOnResource,
322 sourceResource, nodeTemplateId, ToscaConstants.DEPENDS_ON_REQUIREMENT_ID,
323 requirementAssignment);
326 mdcDataDebugMessage.debugExitMessage(null, null);
329 Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
331 HeatOrchestrationTemplate heatOrchestrationTemplate,
332 String translatedResourceId,
333 TranslateTo translateTo,
334 String heatResourceType) {
335 mdcDataDebugMessage.debugEntryMessage(null, null);
336 List<Map.Entry<String, Resource>> list = heatOrchestrationTemplate.getResources().entrySet()
338 .filter(entry -> getPredicatesForTranslatedIdToResourceId(heatFileName,
339 heatOrchestrationTemplate, translatedResourceId, translateTo.getContext(),
342 .allMatch(p -> p.test(entry)))
343 .collect(Collectors.toList());
344 if (CollectionUtils.isEmpty(list)) {
345 mdcDataDebugMessage.debugExitMessage(null, null);
346 return Optional.empty();
348 mdcDataDebugMessage.debugExitMessage(null, null);
349 return Optional.of(list);
353 private List<Predicate<Map.Entry<String, Resource>>> getPredicatesForTranslatedIdToResourceId(
354 String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
355 String translatedResourceId, TranslationContext context, String heatResourceType) {
356 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
358 entry.getValue().getType().equals(heatResourceType));
360 Optional<String> resourceTranslatedId =
361 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, entry.getKey(), context);
362 return resourceTranslatedId.isPresent()
363 && resourceTranslatedId.get().equals(translatedResourceId);
368 boolean isResourceTypeSupported(Resource resource, List<String> supporteTypes) {
369 return Objects.nonNull(resource) && supporteTypes.contains(resource.getType());