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.MdcDataErrorMessage;
29 import org.openecomp.sdc.logging.types.LoggerConstants;
30 import org.openecomp.sdc.logging.types.LoggerErrorCode;
31 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
32 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
33 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
34 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
35 import org.openecomp.sdc.tosca.datatypes.ToscaTopologyTemplateElements;
36 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
37 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
38 import org.openecomp.sdc.tosca.services.DataModelUtil;
39 import org.openecomp.sdc.tosca.services.ToscaConstants;
40 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
41 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
42 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
43 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationEntityType;
44 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
45 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
46 import org.openecomp.sdc.translator.services.heattotosca.errors.DuplicateResourceIdsInDifferentFilesErrorBuilder;
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;
59 import java.util.function.Predicate;
60 import java.util.stream.Collectors;
62 public abstract class ResourceTranslationBase {
64 protected static Logger logger = (Logger) LoggerFactory.getLogger(ResourceTranslationBase.class);
65 protected abstract void translate(TranslateTo translateTo);
70 * @param heatFileName the heat file name
71 * @param serviceTemplate the service template
72 * @param heatOrchestrationTemplate the heat orchestration template
73 * @param resource the resource
74 * @param resourceId the resource id
75 * @param context the context
76 * @return the translated id if this resource is supported, or empty value if not supported
78 public Optional<String> translateResource(String heatFileName, ServiceTemplate serviceTemplate,
79 HeatOrchestrationTemplate heatOrchestrationTemplate,
80 Resource resource, String resourceId,
81 TranslationContext context) {
82 Optional<String> translatedId =
83 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
84 context.getTranslatedResources().putIfAbsent(heatFileName, new HashSet<>());
86 if(isResourceWithSameIdAppearsInOtherFiles(heatFileName, resourceId, context)){
87 throw new CoreException(
88 new DuplicateResourceIdsInDifferentFilesErrorBuilder(resourceId).build());
90 if (context.getTranslatedResources().get(heatFileName).contains(resourceId)) {
93 if (!translatedId.isPresent()) {
94 return Optional.empty();
96 logger.debug("Translate- file:" + heatFileName + " resource Id:" + resourceId
97 + " translated resource id:" + translatedId.get());
98 TranslateTo translateTo = new TranslateTo(heatFileName, serviceTemplate,
99 heatOrchestrationTemplate, resource, resourceId, translatedId.get(), context);
100 translate(translateTo);
101 context.getTranslatedResources().get(heatFileName).add(resourceId);
103 if (DataModelUtil.isNodeTemplate(translatedId.get(), serviceTemplate)) {
104 if (!context.getHeatStackGroupMembers().containsKey(heatFileName)) {
105 context.getHeatStackGroupMembers().put(heatFileName, new HashSet<>());
107 context.getHeatStackGroupMembers().get(heatFileName).add(translatedId.get());
108 updateResourceDependency(translateTo);
113 private boolean isResourceWithSameIdAppearsInOtherFiles(String heatFileName,
115 TranslationContext context){
116 Set<String> translatedResourceIdsFromOtherFiles =
117 context.getTranslatedResourceIdsFromOtherFiles(heatFileName);
119 return CollectionUtils.isNotEmpty(translatedResourceIdsFromOtherFiles)
120 && translatedResourceIdsFromOtherFiles.contains(resourceId);
124 * Gets resource translated id.
126 * @param heatFileName the heat file name
127 * @param heatOrchestrationTemplate the heat orchestration template
128 * @param resourceId the resource id
129 * @param context the context
130 * @return the resource translated id
132 public static Optional<String> getResourceTranslatedId(String heatFileName,
133 HeatOrchestrationTemplate
134 heatOrchestrationTemplate,
136 TranslationContext context) {
137 if (!context.getTranslatedIds().containsKey(heatFileName)) {
138 context.getTranslatedIds().put(heatFileName, new HashMap<>());
141 Map<String, String> translatedIdsPerFile = context.getTranslatedIds().get(heatFileName);
142 String translatedId = translatedIdsPerFile.get(resourceId);
143 if (translatedId != null) {
144 return Optional.of(translatedId);
147 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
148 if (resource == null) {
149 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
150 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
151 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
152 throw new CoreException(
153 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
155 return getTranslatedResourceId(resourceId, heatFileName, resource, heatOrchestrationTemplate,
160 private static Optional<String> getTranslatedResourceId(String resourceId,
163 HeatOrchestrationTemplate heatOrchestrationTemplate,
164 TranslationContext context) {
165 TranslateTo translateTo =
166 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
169 String translatedId =
170 ResourceTranslationFactory.getInstance(resource).generateTranslatedId(translateTo);
172 if (ConsolidationDataUtil.isNodeTemplatePointsToServiceTemplateWithoutNodeTemplates
173 (translatedId, heatFileName, context)) {
174 return Optional.empty();
177 if (translatedId != null) {
178 context.getTranslatedIds().get(heatFileName).put(resourceId, translatedId);
181 return Optional.ofNullable(translatedId);
186 * Gets resource translated element template.
188 * @param heatFileName the heat file name
189 * @param heatOrchestrationTemplate the heat orchestration template
190 * @param resourceId the resource id
191 * @param context the context
192 * @return the resource translated element template
194 public static Optional<ToscaTopologyTemplateElements> getResourceTranslatedElementTemplate(
196 HeatOrchestrationTemplate heatOrchestrationTemplate,
197 String resourceId, TranslationContext context) {
198 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
199 if (resource == null) {
200 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
201 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
202 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
203 throw new CoreException(
204 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
206 TranslateTo translateTo =
207 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
210 Optional<ToscaTopologyTemplateElements> translatedElementTemplate =
211 ResourceTranslationFactory.getInstance(resource)
212 .getTranslatedToscaTopologyElement(translateTo);
213 return translatedElementTemplate;
216 protected String generateTranslatedId(TranslateTo translateTo) {
217 if (isEssentialRequirementsValid(translateTo)) {
218 return translateTo.getResourceId();
225 protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
226 TranslateTo translateTo) {
227 if (isEssentialRequirementsValid(translateTo)) {
228 return Optional.of(ToscaTopologyTemplateElements.NODE_TEMPLATE);
230 return Optional.empty();
234 protected boolean isEssentialRequirementsValid(TranslateTo translateTo) {
238 private static TranslateTo generateTranslationTo(String heatFileName,
239 ServiceTemplate serviceTemplate,
240 HeatOrchestrationTemplate
241 heatOrchestrationTemplate,
242 Resource resource, String resourceId,
244 TranslationContext context) {
245 TranslateTo to = new TranslateTo();
246 to.setHeatFileName(heatFileName);
247 to.setServiceTemplate(serviceTemplate);
248 to.setHeatOrchestrationTemplate(heatOrchestrationTemplate);
249 to.setResource(resource);
250 to.setResourceId(resourceId);
251 to.setTranslatedId(translatedId);
252 to.setContext(context);
256 private void updateResourceDependency(TranslateTo translateTo) {
258 String heatFileName = translateTo.getHeatFileName();
259 Resource resource = translateTo.getResource();
260 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
261 .getHeatOrchestrationTemplate();
262 String translatedId = translateTo.getTranslatedId();
263 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
264 TranslationContext context = translateTo.getContext();
265 if (resource.getDepends_on() == null) {
269 if (resource.getDepends_on() instanceof List) {
270 List<String> dependsOnList = (List<String>) resource.getDepends_on();
271 for (String dependsOnResourceId : dependsOnList) {
272 addDependOnRequirement(dependsOnResourceId, translateTo);
275 String dependsOnResourceId = (String) resource.getDepends_on();
276 addDependOnRequirement(dependsOnResourceId, translateTo);
280 private void addDependOnRequirement(String dependsOnResourceId, TranslateTo translateTo) {
281 String nodeTemplateId = translateTo.getTranslatedId();
282 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
283 String heatFileName = translateTo.getHeatFileName();
284 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
285 .getHeatOrchestrationTemplate();
286 TranslationContext context = translateTo.getContext();
287 RequirementAssignment requirementAssignment = new RequirementAssignment();
288 Optional<String> resourceTranslatedId =
289 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, dependsOnResourceId,
292 Optional<ToscaTopologyTemplateElements> resourceTranslatedElementTemplate =
293 getResourceTranslatedElementTemplate(heatFileName, heatOrchestrationTemplate,
294 dependsOnResourceId, context);
296 if (resourceTranslatedId.isPresent()
297 && (resourceTranslatedElementTemplate.isPresent() && resourceTranslatedElementTemplate
298 .get() == ToscaTopologyTemplateElements.NODE_TEMPLATE)) {
299 Resource sourceResource = translateTo.getResource();
300 Resource targetResource = HeatToToscaUtil
301 .getResource(heatOrchestrationTemplate, dependsOnResourceId,
302 translateTo.getHeatFileName());
304 .isValidDependsOnCandidate(heatOrchestrationTemplate, sourceResource, targetResource,
305 ConsolidationEntityType.OTHER, translateTo.getContext())) {
306 requirementAssignment.setNode(resourceTranslatedId.get());
307 requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NODE);
308 requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_DEPENDS_ON);
309 DataModelUtil.addRequirementAssignment(
310 serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId),
311 ToscaConstants.DEPENDS_ON_REQUIREMENT_ID, requirementAssignment);
312 Resource dependsOnResource = targetResource;
313 ConsolidationDataUtil
314 .updateNodesConnectedData(translateTo, dependsOnResourceId, dependsOnResource,
315 sourceResource, nodeTemplateId, ToscaConstants.DEPENDS_ON_REQUIREMENT_ID,
316 requirementAssignment);
321 Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
323 HeatOrchestrationTemplate heatOrchestrationTemplate,
324 String translatedResourceId,
325 TranslateTo translateTo,
326 String heatResourceType) {
327 List<Map.Entry<String, Resource>> list = heatOrchestrationTemplate.getResources().entrySet()
329 .filter(entry -> getPredicatesForTranslatedIdToResourceId(heatFileName,
330 heatOrchestrationTemplate, translatedResourceId, translateTo.getContext(),
333 .allMatch(p -> p.test(entry)))
334 .collect(Collectors.toList());
335 if (CollectionUtils.isEmpty(list)) {
336 return Optional.empty();
338 return Optional.of(list);
342 private List<Predicate<Map.Entry<String, Resource>>> getPredicatesForTranslatedIdToResourceId(
343 String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
344 String translatedResourceId, TranslationContext context, String heatResourceType) {
345 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
347 entry.getValue().getType().equals(heatResourceType));
349 Optional<String> resourceTranslatedId =
350 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, entry.getKey(), context);
351 return resourceTranslatedId.isPresent()
352 && resourceTranslatedId.get().equals(translatedResourceId);
357 boolean isResourceTypeSupported(Resource resource, List<String> supporteTypes) {
358 return Objects.nonNull(resource) && supporteTypes.contains(resource.getType());