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 java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.List;
24 import java.util.Objects;
25 import java.util.Optional;
27 import java.util.function.Predicate;
29 import java.util.stream.Collectors;
31 import org.apache.commons.collections4.CollectionUtils;
32 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
33 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
34 import org.openecomp.sdc.common.errors.CoreException;
35 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
36 import org.openecomp.sdc.heat.datatypes.model.Resource;
37 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
38 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
39 import org.openecomp.sdc.tosca.datatypes.ToscaTopologyTemplateElements;
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;
52 public abstract class ResourceTranslationBase {
54 protected static Logger logger = org.slf4j.LoggerFactory.getLogger(ResourceTranslationBase.class);
57 * Gets resource translated id.
59 * @param heatFileName the heat file name
60 * @param heatOrchestrationTemplate the heat orchestration template
61 * @param resourceId the resource id
62 * @param context the context
63 * @return the resource translated id
65 public static Optional<String> getResourceTranslatedId(String heatFileName,
66 HeatOrchestrationTemplate
67 heatOrchestrationTemplate,
69 TranslationContext context) {
70 if (!context.getTranslatedIds().containsKey(heatFileName)) {
71 context.getTranslatedIds().put(heatFileName, new HashMap<>());
74 Map<String, String> translatedIdsPerFile = context.getTranslatedIds().get(heatFileName);
75 String translatedId = translatedIdsPerFile.get(resourceId);
76 if (translatedId != null) {
77 return Optional.of(translatedId);
80 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
81 if (resource == null) {
82 throw new CoreException(
83 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
85 return getTranslatedResourceId(resourceId, heatFileName, resource, heatOrchestrationTemplate,
90 private static Optional<String> getTranslatedResourceId(String resourceId,
93 HeatOrchestrationTemplate heatOrchestrationTemplate,
94 TranslationContext context) {
95 TranslateTo translateTo =
96 generateTranslationTo(heatFileName, heatOrchestrationTemplate, resource, resourceId,
100 ResourceTranslationFactory.getInstance(resource).generateTranslatedId(translateTo);
102 if (ConsolidationDataUtil.isNodeTemplatePointsToServiceTemplateWithoutNodeTemplates(translatedId,
103 heatFileName, context)) {
104 return Optional.empty();
107 if (translatedId != null) {
108 context.getTranslatedIds().get(heatFileName).put(resourceId, translatedId);
111 return Optional.ofNullable(translatedId);
114 private static Optional<ToscaTopologyTemplateElements> getResourceTranslatedElementTemplate(String heatFileName,
115 HeatOrchestrationTemplate heatOrchestrationTemplate,
116 String resourceId, TranslationContext context) {
117 Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
118 if (resource == null) {
119 throw new CoreException(
120 new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
122 TranslateTo translateTo =
123 generateTranslationTo(heatFileName, heatOrchestrationTemplate, resource, resourceId,
126 return ResourceTranslationFactory.getInstance(resource)
127 .getTranslatedToscaTopologyElement(translateTo);
130 private static TranslateTo generateTranslationTo(String heatFileName,
131 HeatOrchestrationTemplate
132 heatOrchestrationTemplate,
133 Resource resource, String resourceId,
134 TranslationContext context) {
135 TranslateTo to = new TranslateTo();
136 to.setHeatFileName(heatFileName);
137 to.setServiceTemplate(null);
138 to.setHeatOrchestrationTemplate(heatOrchestrationTemplate);
139 to.setResource(resource);
140 to.setResourceId(resourceId);
141 to.setTranslatedId(null);
142 to.setContext(context);
146 protected abstract void translate(TranslateTo translateTo);
149 * Translate resource.
151 * @param heatFileName the heat file name
152 * @param serviceTemplate the service template
153 * @param heatOrchestrationTemplate the heat orchestration template
154 * @param resource the resource
155 * @param resourceId the resource id
156 * @param context the context
157 * @return the translated id if this resource is supported, or empty value if not supported
159 public Optional<String> translateResource(String heatFileName, ServiceTemplate serviceTemplate,
160 HeatOrchestrationTemplate heatOrchestrationTemplate,
161 Resource resource, String resourceId,
162 TranslationContext context) {
163 Optional<String> translatedId =
164 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, resourceId, context);
165 context.getTranslatedResources().putIfAbsent(heatFileName, new HashSet<>());
167 if (isResourceWithSameIdAppearsInOtherFiles(heatFileName, resourceId, context)) {
168 throw new CoreException(
169 new DuplicateResourceIdsInDifferentFilesErrorBuilder(resourceId).build());
171 if (context.getTranslatedResources().get(heatFileName).contains(resourceId)) {
174 if (!translatedId.isPresent()) {
175 return Optional.empty();
177 logger.debug("Translate- file: {} resource Id: {} translated resource id: {}",
178 heatFileName, resourceId, translatedId.get());
179 TranslateTo translateTo = new TranslateTo(heatFileName, serviceTemplate,
180 heatOrchestrationTemplate, resource, resourceId, translatedId.get(), context);
181 translate(translateTo);
182 context.getTranslatedResources().get(heatFileName).add(resourceId);
184 if (DataModelUtil.isNodeTemplate(translatedId.get(), serviceTemplate)) {
185 if (!context.getHeatStackGroupMembers().containsKey(heatFileName)) {
186 context.getHeatStackGroupMembers().put(heatFileName, new HashSet<>());
188 context.getHeatStackGroupMembers().get(heatFileName).add(translatedId.get());
189 updateResourceDependency(translateTo);
194 private boolean isResourceWithSameIdAppearsInOtherFiles(String heatFileName,
196 TranslationContext context) {
197 Set<String> translatedResourceIdsFromOtherFiles =
198 context.getTranslatedResourceIdsFromOtherFiles(heatFileName);
200 return CollectionUtils.isNotEmpty(translatedResourceIdsFromOtherFiles)
201 && translatedResourceIdsFromOtherFiles.contains(resourceId);
204 protected String generateTranslatedId(TranslateTo translateTo) {
205 if (isEssentialRequirementsValid(translateTo)) {
206 return translateTo.getResourceId();
213 protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
214 TranslateTo translateTo) {
215 if (isEssentialRequirementsValid(translateTo)) {
216 return Optional.of(ToscaTopologyTemplateElements.NODE_TEMPLATE);
218 return Optional.empty();
222 protected boolean isEssentialRequirementsValid(TranslateTo translateTo) {
226 private void updateResourceDependency(TranslateTo translateTo) {
228 Resource resource = translateTo.getResource();
229 if (resource.getDepends_on() == null) {
233 if (resource.getDepends_on() instanceof List) {
234 List<String> dependsOnList = (List<String>) resource.getDepends_on();
235 for (String dependsOnResourceId : dependsOnList) {
236 addDependency(dependsOnResourceId, translateTo);
239 String dependsOnResourceId = (String) resource.getDepends_on();
240 addDependency(dependsOnResourceId, translateTo);
244 private void addDependency(String dependsOnResourceId, TranslateTo translateTo) {
245 String heatFileName = translateTo.getHeatFileName();
246 HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
247 .getHeatOrchestrationTemplate();
248 TranslationContext context = translateTo.getContext();
250 Optional<String> resourceTranslatedId =
251 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, dependsOnResourceId,
254 Optional<ToscaTopologyTemplateElements> resourceTranslatedElementTemplate =
255 getResourceTranslatedElementTemplate(heatFileName, heatOrchestrationTemplate,
256 dependsOnResourceId, context);
258 if (resourceTranslatedId.isPresent()
259 && (resourceTranslatedElementTemplate.isPresent()
260 && resourceTranslatedElementTemplate.get() == ToscaTopologyTemplateElements.NODE_TEMPLATE)) {
261 Resource sourceResource = translateTo.getResource();
262 Resource targetResource = HeatToToscaUtil.getResource(heatOrchestrationTemplate, dependsOnResourceId,
263 translateTo.getHeatFileName());
264 if (isValidDependency(sourceResource, targetResource, translateTo)) {
265 addDependsOnRequirement(dependsOnResourceId, translateTo, resourceTranslatedId.get(), sourceResource,
271 private void addDependsOnRequirement(String dependsOnResourceId, TranslateTo translateTo,
272 String resourceTranslatedId, Resource sourceResource,
273 Resource targetResource) {
274 RequirementAssignment requirementAssignment = new RequirementAssignment();
275 requirementAssignment.setNode(resourceTranslatedId);
276 requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NODE);
277 requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_DEPENDS_ON);
278 DataModelUtil.addRequirementAssignment(translateTo.getServiceTemplate().getTopology_template()
279 .getNode_templates().get(translateTo.getTranslatedId()),
280 ToscaConstants.DEPENDS_ON_REQUIREMENT_ID, requirementAssignment);
281 ConsolidationDataUtil
282 .updateNodesConnectedData(translateTo, dependsOnResourceId, targetResource,
283 sourceResource, translateTo.getTranslatedId(), ToscaConstants.DEPENDS_ON_REQUIREMENT_ID,
284 requirementAssignment);
287 private boolean isValidDependency(Resource sourceResource, Resource targetResource, TranslateTo translateTo) {
288 return !(HeatToToscaUtil.isNestedResource(sourceResource) || HeatToToscaUtil.isNestedResource(targetResource))
289 && HeatToToscaUtil.isValidDependsOnCandidate(sourceResource, targetResource,
290 ConsolidationEntityType.OTHER, translateTo.getContext());
293 Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
295 HeatOrchestrationTemplate heatOrchestrationTemplate,
296 String translatedResourceId,
297 TranslateTo translateTo,
298 String heatResourceType) {
299 List<Map.Entry<String, Resource>> list = heatOrchestrationTemplate.getResources().entrySet()
301 .filter(entry -> getPredicatesForTranslatedIdToResourceId(heatFileName,
302 heatOrchestrationTemplate, translatedResourceId, translateTo.getContext(),
305 .allMatch(p -> p.test(entry)))
306 .collect(Collectors.toList());
307 if (CollectionUtils.isEmpty(list)) {
308 return Optional.empty();
310 return Optional.of(list);
314 private List<Predicate<Map.Entry<String, Resource>>> getPredicatesForTranslatedIdToResourceId(
315 String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
316 String translatedResourceId, TranslationContext context, String heatResourceType) {
317 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
319 entry.getValue().getType().equals(heatResourceType));
321 Optional<String> resourceTranslatedId =
322 getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, entry.getKey(), context);
323 return resourceTranslatedId.isPresent()
324 && resourceTranslatedId.get().equals(translatedResourceId);
329 boolean isUnsupportedResourceType(Resource resource, List<String> supportedTypes) {
330 return !Objects.nonNull(resource) || !supportedTypes.contains(resource.getType());