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.translator.services.heattotosca.impl.resourcetranslation;
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.openecomp.sdc.common.errors.CoreException;
21 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
22 import org.openecomp.sdc.heat.datatypes.model.Resource;
23 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
24 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
25 import org.openecomp.sdc.tosca.datatypes.ToscaTopologyTemplateElements;
26 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
27 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
28 import org.openecomp.sdc.tosca.services.DataModelUtil;
29 import org.openecomp.sdc.tosca.services.ToscaConstants;
30 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
31 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
32 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
33 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationEntityType;
34 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
35 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
36 import org.openecomp.sdc.translator.services.heattotosca.errors.DuplicateResourceIdsInDifferentFilesErrorBuilder;
37 import org.openecomp.sdc.translator.services.heattotosca.errors.ResourceNotFoundInHeatFileErrorBuilder;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.List;
46 import java.util.Objects;
47 import java.util.Optional;
49 import java.util.function.Predicate;
50 import java.util.stream.Collectors;
52 public abstract class ResourceTranslationBase {
54 protected static Logger logger = LoggerFactory.getLogger(ResourceTranslationBase.class);
55 protected abstract void translate(TranslateTo translateTo);
60 * @param heatFileName the heat file name
61 * @param serviceTemplate the service template
62 * @param heatOrchestrationTemplate the heat orchestration template
63 * @param resource the resource
64 * @param resourceId the resource id
65 * @param context the context
66 * @return the translated id if this resource is supported, or empty value if not supported
68 public Optional<String> translateResource(String heatFileName, ServiceTemplate serviceTemplate,
69 HeatOrchestrationTemplate heatOrchestrationTemplate,
70 Resource resource, String resourceId,
71 TranslationContext context) {
72 Optional<String> translatedId =
73 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
74 context.getTranslatedResources().putIfAbsent(heatFileName, new HashSet<>());
76 if (isResourceWithSameIdAppearsInOtherFiles(heatFileName, resourceId, context)) {
77 throw new CoreException(
78 new DuplicateResourceIdsInDifferentFilesErrorBuilder(resourceId).build());
80 if (context.getTranslatedResources().get(heatFileName).contains(resourceId)) {
83 if (!translatedId.isPresent()) {
84 return Optional.empty();
86 logger.debug("Translate- file: {} resource Id: {} translated resource id: {}",
87 heatFileName, resourceId, translatedId.get());
88 TranslateTo translateTo = new TranslateTo(heatFileName, serviceTemplate,
89 heatOrchestrationTemplate, resource, resourceId, translatedId.get(), context);
90 translate(translateTo);
91 context.getTranslatedResources().get(heatFileName).add(resourceId);
93 if (DataModelUtil.isNodeTemplate(translatedId.get(), serviceTemplate)) {
94 if (!context.getHeatStackGroupMembers().containsKey(heatFileName)) {
95 context.getHeatStackGroupMembers().put(heatFileName, new HashSet<>());
97 context.getHeatStackGroupMembers().get(heatFileName).add(translatedId.get());
98 updateResourceDependency(translateTo);
103 private boolean isResourceWithSameIdAppearsInOtherFiles(String heatFileName,
105 TranslationContext context) {
106 Set<String> translatedResourceIdsFromOtherFiles =
107 context.getTranslatedResourceIdsFromOtherFiles(heatFileName);
109 return CollectionUtils.isNotEmpty(translatedResourceIdsFromOtherFiles)
110 && translatedResourceIdsFromOtherFiles.contains(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) {
127 if (!context.getTranslatedIds().containsKey(heatFileName)) {
128 context.getTranslatedIds().put(heatFileName, new HashMap<>());
131 Map<String, String> translatedIdsPerFile = context.getTranslatedIds().get(heatFileName);
132 String translatedId = translatedIdsPerFile.get(resourceId);
133 if (translatedId != null) {
134 return Optional.of(translatedId);
137 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
138 if (resource == null) {
139 throw new CoreException(
140 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
142 return getTranslatedResourceId(resourceId, heatFileName, resource, heatOrchestrationTemplate,
147 private static Optional<String> getTranslatedResourceId(String resourceId,
150 HeatOrchestrationTemplate heatOrchestrationTemplate,
151 TranslationContext context) {
152 TranslateTo translateTo =
153 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
156 String translatedId =
157 ResourceTranslationFactory.getInstance(resource).generateTranslatedId(translateTo);
159 if (ConsolidationDataUtil.isNodeTemplatePointsToServiceTemplateWithoutNodeTemplates
160 (translatedId, heatFileName, context)) {
161 return Optional.empty();
164 if (translatedId != null) {
165 context.getTranslatedIds().get(heatFileName).put(resourceId, translatedId);
168 return Optional.ofNullable(translatedId);
173 * Gets resource translated element template.
175 * @param heatFileName the heat file name
176 * @param heatOrchestrationTemplate the heat orchestration template
177 * @param resourceId the resource id
178 * @param context the context
179 * @return the resource translated element template
181 public static Optional<ToscaTopologyTemplateElements> getResourceTranslatedElementTemplate(
183 HeatOrchestrationTemplate heatOrchestrationTemplate,
184 String resourceId, TranslationContext context) {
185 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
186 if (resource == null) {
187 throw new CoreException(
188 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
190 TranslateTo translateTo =
191 generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
194 return ResourceTranslationFactory.getInstance(resource)
195 .getTranslatedToscaTopologyElement(translateTo);
198 protected String generateTranslatedId(TranslateTo translateTo) {
199 if (isEssentialRequirementsValid(translateTo)) {
200 return translateTo.getResourceId();
207 protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
208 TranslateTo translateTo) {
209 if (isEssentialRequirementsValid(translateTo)) {
210 return Optional.of(ToscaTopologyTemplateElements.NODE_TEMPLATE);
212 return Optional.empty();
216 protected boolean isEssentialRequirementsValid(TranslateTo translateTo) {
220 private static TranslateTo generateTranslationTo(String heatFileName,
221 ServiceTemplate serviceTemplate,
222 HeatOrchestrationTemplate
223 heatOrchestrationTemplate,
224 Resource resource, String resourceId,
226 TranslationContext context) {
227 TranslateTo to = new TranslateTo();
228 to.setHeatFileName(heatFileName);
229 to.setServiceTemplate(serviceTemplate);
230 to.setHeatOrchestrationTemplate(heatOrchestrationTemplate);
231 to.setResource(resource);
232 to.setResourceId(resourceId);
233 to.setTranslatedId(translatedId);
234 to.setContext(context);
238 private void updateResourceDependency(TranslateTo translateTo) {
240 Resource resource = translateTo.getResource();
241 if (resource.getDepends_on() == null) {
245 if (resource.getDepends_on() instanceof List) {
246 List<String> dependsOnList = (List<String>) resource.getDepends_on();
247 for (String dependsOnResourceId : dependsOnList) {
248 addDependOnRequirement(dependsOnResourceId, translateTo);
251 String dependsOnResourceId = (String) resource.getDepends_on();
252 addDependOnRequirement(dependsOnResourceId, translateTo);
256 private void addDependOnRequirement(String dependsOnResourceId, TranslateTo translateTo) {
257 String nodeTemplateId = translateTo.getTranslatedId();
258 ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
259 String heatFileName = translateTo.getHeatFileName();
260 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
261 .getHeatOrchestrationTemplate();
262 TranslationContext context = translateTo.getContext();
263 RequirementAssignment requirementAssignment = new RequirementAssignment();
264 Optional<String> resourceTranslatedId =
265 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, dependsOnResourceId,
268 Optional<ToscaTopologyTemplateElements> resourceTranslatedElementTemplate =
269 getResourceTranslatedElementTemplate(heatFileName, heatOrchestrationTemplate,
270 dependsOnResourceId, context);
272 if (resourceTranslatedId.isPresent()
273 && (resourceTranslatedElementTemplate.isPresent() && resourceTranslatedElementTemplate
274 .get() == ToscaTopologyTemplateElements.NODE_TEMPLATE)) {
275 Resource sourceResource = translateTo.getResource();
276 Resource targetResource = HeatToToscaUtil
277 .getResource(heatOrchestrationTemplate, dependsOnResourceId,
278 translateTo.getHeatFileName());
279 if (isValidDependency(sourceResource, targetResource, translateTo)) {
280 requirementAssignment.setNode(resourceTranslatedId.get());
281 requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NODE);
282 requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_DEPENDS_ON);
283 DataModelUtil.addRequirementAssignment(
284 serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId),
285 ToscaConstants.DEPENDS_ON_REQUIREMENT_ID, requirementAssignment);
286 ConsolidationDataUtil
287 .updateNodesConnectedData(translateTo, dependsOnResourceId, targetResource,
288 sourceResource, nodeTemplateId, ToscaConstants.DEPENDS_ON_REQUIREMENT_ID,
289 requirementAssignment);
294 private boolean isValidDependency(Resource sourceResource, Resource targetResource, TranslateTo translateTo) {
295 return !(HeatToToscaUtil.isNestedResource(sourceResource) || HeatToToscaUtil.isNestedResource(targetResource))
296 && HeatToToscaUtil.isValidDependsOnCandidate(sourceResource, targetResource,
297 ConsolidationEntityType.OTHER, translateTo.getContext());
300 Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
302 HeatOrchestrationTemplate heatOrchestrationTemplate,
303 String translatedResourceId,
304 TranslateTo translateTo,
305 String heatResourceType) {
306 List<Map.Entry<String, Resource>> list = heatOrchestrationTemplate.getResources().entrySet()
308 .filter(entry -> getPredicatesForTranslatedIdToResourceId(heatFileName,
309 heatOrchestrationTemplate, translatedResourceId, translateTo.getContext(),
312 .allMatch(p -> p.test(entry)))
313 .collect(Collectors.toList());
314 if (CollectionUtils.isEmpty(list)) {
315 return Optional.empty();
317 return Optional.of(list);
321 private List<Predicate<Map.Entry<String, Resource>>> getPredicatesForTranslatedIdToResourceId(
322 String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
323 String translatedResourceId, TranslationContext context, String heatResourceType) {
324 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
326 entry.getValue().getType().equals(heatResourceType));
328 Optional<String> resourceTranslatedId =
329 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, entry.getKey(), context);
330 return resourceTranslatedId.isPresent()
331 && resourceTranslatedId.get().equals(translatedResourceId);
336 boolean isResourceTypeSupported(Resource resource, List<String> supporteTypes) {
337 return Objects.nonNull(resource) && supporteTypes.contains(resource.getType());