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.common.errors.ErrorCode;
26 import org.openecomp.sdc.datatypes.error.ErrorLevel;
27 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
28 import org.openecomp.sdc.heat.datatypes.model.Resource;
29 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
30 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
31 import org.openecomp.sdc.logging.types.LoggerConstants;
32 import org.openecomp.sdc.logging.types.LoggerErrorCode;
33 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
34 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
35 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
36 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
37 import org.openecomp.sdc.tosca.datatypes.ToscaTopologyTemplateElements;
38 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
39 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
40 import org.openecomp.sdc.tosca.services.DataModelUtil;
41 import org.openecomp.sdc.tosca.services.ToscaConstants;
42 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
43 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
44 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
45 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationEntityType;
46 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
47 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
48 import org.openecomp.sdc.translator.services.heattotosca.errors.DuplicateResourceIdsInDifferentFilesErrorBuilder;
49 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
53 import java.util.ArrayList;
54 import java.util.HashMap;
55 import java.util.HashSet;
56 import java.util.List;
58 import java.util.Objects;
59 import java.util.Optional;
61 import java.util.function.Predicate;
62 import java.util.stream.Collectors;
64 public abstract class ResourceTranslationBase {
66 protected static Logger logger = (Logger) LoggerFactory.getLogger(ResourceTranslationBase.class);
67 protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
69 protected abstract void translate(TranslateTo translateTo);
74 * @param heatFileName the heat file name
75 * @param serviceTemplate the service template
76 * @param heatOrchestrationTemplate the heat orchestration template
77 * @param resource the resource
78 * @param resourceId the resource id
79 * @param context the context
80 * @return the translated id if this resource is supported, or empty value if not supported
82 public Optional<String> translateResource(String heatFileName, ServiceTemplate serviceTemplate,
83 HeatOrchestrationTemplate heatOrchestrationTemplate,
84 Resource resource, String resourceId,
85 TranslationContext context) {
87 mdcDataDebugMessage.debugEntryMessage("file, resource", heatFileName, resourceId);
88 Optional<String> translatedId =
89 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
90 context.getTranslatedResources().putIfAbsent(heatFileName, new HashSet<>());
92 if(isResourceWithSameIdAppearsInOtherFiles(heatFileName, resourceId, context)){
93 throw new CoreException(
94 new DuplicateResourceIdsInDifferentFilesErrorBuilder(resourceId).build());
96 if (context.getTranslatedResources().get(heatFileName).contains(resourceId)) {
99 if (!translatedId.isPresent()) {
100 return Optional.empty();
102 logger.debug("Translate- file:" + heatFileName + " resource Id:" + resourceId
103 + " translated resource id:" + translatedId.get());
104 TranslateTo translateTo = new TranslateTo(heatFileName, serviceTemplate,
105 heatOrchestrationTemplate, resource, resourceId, translatedId.get(), context);
106 translate(translateTo);
107 context.getTranslatedResources().get(heatFileName).add(resourceId);
109 if (DataModelUtil.isNodeTemplate(translatedId.get(), serviceTemplate)) {
110 if (!context.getHeatStackGroupMembers().containsKey(heatFileName)) {
111 context.getHeatStackGroupMembers().put(heatFileName, new HashSet<>());
113 context.getHeatStackGroupMembers().get(heatFileName).add(translatedId.get());
114 updateResourceDependency(translateTo);
117 mdcDataDebugMessage.debugExitMessage("file, resource", heatFileName, resourceId);
121 private boolean isResourceWithSameIdAppearsInOtherFiles(String heatFileName,
123 TranslationContext context){
124 Set<String> translatedResourceIdsFromOtherFiles =
125 context.getTranslatedResourceIdsFromOtherFiles(heatFileName);
127 return CollectionUtils.isNotEmpty(translatedResourceIdsFromOtherFiles)
128 && translatedResourceIdsFromOtherFiles.contains(resourceId);
132 * Gets resource translated id.
134 * @param heatFileName the heat file name
135 * @param heatOrchestrationTemplate the heat orchestration template
136 * @param resourceId the resource id
137 * @param context the context
138 * @return the resource translated id
140 public static Optional<String> getResourceTranslatedId(String heatFileName,
141 HeatOrchestrationTemplate
142 heatOrchestrationTemplate,
144 TranslationContext context) {
147 mdcDataDebugMessage.debugEntryMessage(null, null);
149 if (!context.getTranslatedIds().containsKey(heatFileName)) {
150 context.getTranslatedIds().put(heatFileName, new HashMap<>());
153 Map<String, String> translatedIdsPerFile = context.getTranslatedIds().get(heatFileName);
154 String translatedId = translatedIdsPerFile.get(resourceId);
155 if (translatedId != null) {
156 return Optional.of(translatedId);
159 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
160 if (resource == null) {
161 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
162 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
163 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
164 throw new CoreException(
165 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
168 mdcDataDebugMessage.debugExitMessage(null, null);
169 return getTranslatedResourceId(resourceId, heatFileName, resource, heatOrchestrationTemplate,
174 private static Optional<String> getTranslatedResourceId(String resourceId,
177 HeatOrchestrationTemplate heatOrchestrationTemplate,
178 TranslationContext context) {
179 TranslateTo translateTo =
180 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
183 String translatedId =
184 ResourceTranslationFactory.getInstance(resource).generateTranslatedId(translateTo);
186 if (ConsolidationDataUtil.isNodeTemplatePointsToServiceTemplateWithoutNodeTemplates
187 (translatedId, heatFileName, context)) {
188 return Optional.empty();
191 if (translatedId != null) {
192 context.getTranslatedIds().get(heatFileName).put(resourceId, translatedId);
195 return Optional.ofNullable(translatedId);
200 * Gets resource translated element template.
202 * @param heatFileName the heat file name
203 * @param heatOrchestrationTemplate the heat orchestration template
204 * @param resourceId the resource id
205 * @param context the context
206 * @return the resource translated element template
208 public static Optional<ToscaTopologyTemplateElements> getResourceTranslatedElementTemplate(
210 HeatOrchestrationTemplate heatOrchestrationTemplate,
211 String resourceId, TranslationContext context) {
213 mdcDataDebugMessage.debugEntryMessage(null, null);
215 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
216 if (resource == null) {
217 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
218 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
219 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
220 throw new CoreException(
221 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
223 TranslateTo translateTo =
224 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
227 Optional<ToscaTopologyTemplateElements> translatedElementTemplate =
228 ResourceTranslationFactory.getInstance(resource)
229 .getTranslatedToscaTopologyElement(translateTo);
231 mdcDataDebugMessage.debugExitMessage(null, null);
232 return translatedElementTemplate;
235 protected String generateTranslatedId(TranslateTo translateTo) {
236 if (isEssentialRequirementsValid(translateTo)) {
237 return translateTo.getResourceId();
244 protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
245 TranslateTo translateTo) {
246 if (isEssentialRequirementsValid(translateTo)) {
247 return Optional.of(ToscaTopologyTemplateElements.NODE_TEMPLATE);
249 return Optional.empty();
253 protected boolean isEssentialRequirementsValid(TranslateTo translateTo) {
257 private static TranslateTo generateTranslationTo(String heatFileName,
258 ServiceTemplate serviceTemplate,
259 HeatOrchestrationTemplate
260 heatOrchestrationTemplate,
261 Resource resource, String resourceId,
263 TranslationContext context) {
264 TranslateTo to = new TranslateTo();
265 to.setHeatFileName(heatFileName);
266 to.setServiceTemplate(serviceTemplate);
267 to.setHeatOrchestrationTemplate(heatOrchestrationTemplate);
268 to.setResource(resource);
269 to.setResourceId(resourceId);
270 to.setTranslatedId(translatedId);
271 to.setContext(context);
275 private void updateResourceDependency(TranslateTo translateTo) {
277 String heatFileName = translateTo.getHeatFileName();
278 mdcDataDebugMessage.debugEntryMessage("file", heatFileName);
280 Resource resource = translateTo.getResource();
281 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
282 .getHeatOrchestrationTemplate();
283 String translatedId = translateTo.getTranslatedId();
284 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
285 TranslationContext context = translateTo.getContext();
286 if (resource.getDepends_on() == null) {
290 if (resource.getDepends_on() instanceof List) {
291 List<String> dependsOnList = (List<String>) resource.getDepends_on();
292 for (String dependsOnResourceId : dependsOnList) {
293 addDependOnRequirement(dependsOnResourceId, translateTo);
296 String dependsOnResourceId = (String) resource.getDepends_on();
297 addDependOnRequirement(dependsOnResourceId, translateTo);
300 mdcDataDebugMessage.debugExitMessage("file", heatFileName);
303 private void addDependOnRequirement(String dependsOnResourceId, TranslateTo translateTo) {
305 mdcDataDebugMessage.debugEntryMessage(null, null);
306 String nodeTemplateId = translateTo.getTranslatedId();
307 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
308 String heatFileName = translateTo.getHeatFileName();
309 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
310 .getHeatOrchestrationTemplate();
311 TranslationContext context = translateTo.getContext();
312 RequirementAssignment requirementAssignment = new RequirementAssignment();
313 Optional<String> resourceTranslatedId =
314 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, dependsOnResourceId,
317 Optional<ToscaTopologyTemplateElements> resourceTranslatedElementTemplate =
318 getResourceTranslatedElementTemplate(heatFileName, heatOrchestrationTemplate,
319 dependsOnResourceId, context);
321 if (resourceTranslatedId.isPresent()
322 && (resourceTranslatedElementTemplate.isPresent() && resourceTranslatedElementTemplate
323 .get() == ToscaTopologyTemplateElements.NODE_TEMPLATE)) {
324 Resource sourceResource = translateTo.getResource();
325 Resource targetResource = HeatToToscaUtil
326 .getResource(heatOrchestrationTemplate, dependsOnResourceId,
327 translateTo.getHeatFileName());
329 .isValidDependsOnCandidate(heatOrchestrationTemplate, sourceResource, targetResource,
330 ConsolidationEntityType.OTHER, translateTo.getContext())) {
331 requirementAssignment.setNode(resourceTranslatedId.get());
332 requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NODE);
333 requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_DEPENDS_ON);
334 DataModelUtil.addRequirementAssignment(
335 serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId),
336 ToscaConstants.DEPENDS_ON_REQUIREMENT_ID, requirementAssignment);
337 Resource dependsOnResource = targetResource;
338 ConsolidationDataUtil
339 .updateNodesConnectedData(translateTo, dependsOnResourceId, dependsOnResource,
340 sourceResource, nodeTemplateId, ToscaConstants.DEPENDS_ON_REQUIREMENT_ID,
341 requirementAssignment);
344 mdcDataDebugMessage.debugExitMessage(null, null);
347 Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
349 HeatOrchestrationTemplate heatOrchestrationTemplate,
350 String translatedResourceId,
351 TranslateTo translateTo,
352 String heatResourceType) {
353 mdcDataDebugMessage.debugEntryMessage(null, null);
354 List<Map.Entry<String, Resource>> list = heatOrchestrationTemplate.getResources().entrySet()
356 .filter(entry -> getPredicatesForTranslatedIdToResourceId(heatFileName,
357 heatOrchestrationTemplate, translatedResourceId, translateTo.getContext(),
360 .allMatch(p -> p.test(entry)))
361 .collect(Collectors.toList());
362 if (CollectionUtils.isEmpty(list)) {
363 mdcDataDebugMessage.debugExitMessage(null, null);
364 return Optional.empty();
366 mdcDataDebugMessage.debugExitMessage(null, null);
367 return Optional.of(list);
371 private List<Predicate<Map.Entry<String, Resource>>> getPredicatesForTranslatedIdToResourceId(
372 String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
373 String translatedResourceId, TranslationContext context, String heatResourceType) {
374 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
376 entry.getValue().getType().equals(heatResourceType));
378 Optional<String> resourceTranslatedId =
379 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, entry.getKey(), context);
380 return resourceTranslatedId.isPresent()
381 && resourceTranslatedId.get().equals(translatedResourceId);
386 boolean isResourceTypeSupported(Resource resource, List<String> supporteTypes) {
387 return Objects.nonNull(resource) && supporteTypes.contains(resource.getType());