[SDC-29] Amdocs OnBoard 1707 initial commit.
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / resourcetranslation / ResourceTranslationBase.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
22
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;
50
51 import java.util.ArrayList;
52 import java.util.HashMap;
53 import java.util.HashSet;
54 import java.util.List;
55 import java.util.Map;
56 import java.util.Objects;
57 import java.util.Optional;
58 import java.util.function.Predicate;
59 import java.util.stream.Collectors;
60
61 public abstract class ResourceTranslationBase {
62
63   protected static Logger logger = (Logger) LoggerFactory.getLogger(ResourceTranslationBase.class);
64   protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
65
66   protected abstract void translate(TranslateTo translateTo);
67
68   /**
69    * Translate resource.
70    *
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
78    */
79   public Optional<String> translateResource(String heatFileName, ServiceTemplate serviceTemplate,
80                                             HeatOrchestrationTemplate heatOrchestrationTemplate,
81                                             Resource resource, String resourceId,
82                                             TranslationContext context) {
83
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)) {
89       return translatedId;
90     }
91     if (!translatedId.isPresent()) {
92       return Optional.empty();
93     }
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);
100
101     if (DataModelUtil.isNodeTemplate(translatedId.get(), serviceTemplate)) {
102       if (!context.getHeatStackGroupMembers().containsKey(heatFileName)) {
103         context.getHeatStackGroupMembers().put(heatFileName, new HashSet<>());
104       }
105       context.getHeatStackGroupMembers().get(heatFileName).add(translatedId.get());
106       updateResourceDependency(translateTo);
107     }
108
109     mdcDataDebugMessage.debugExitMessage("file, resource", heatFileName, resourceId);
110     return translatedId;
111   }
112
113   /**
114    * Gets resource translated id.
115    *
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
121    */
122   public static Optional<String> getResourceTranslatedId(String heatFileName,
123                                                          HeatOrchestrationTemplate
124                                                              heatOrchestrationTemplate,
125                                                          String resourceId,
126                                                          TranslationContext context) {
127
128
129     mdcDataDebugMessage.debugEntryMessage(null, null);
130
131     if (!context.getTranslatedIds().containsKey(heatFileName)) {
132       context.getTranslatedIds().put(heatFileName, new HashMap<>());
133     }
134
135     Map<String, String> translatedIdsPerFile = context.getTranslatedIds().get(heatFileName);
136     String translatedId = translatedIdsPerFile.get(resourceId);
137     if (translatedId != null) {
138       return Optional.of(translatedId);
139     }
140
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());
148     }
149     TranslateTo translateTo =
150         generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
151             null, context);
152     translatedId =
153         ResourceTranslationFactory.getInstance(resource).generateTranslatedId(translateTo);
154     if (translatedId != null) {
155       context.getTranslatedIds().get(heatFileName).put(resourceId, translatedId);
156     }
157
158     mdcDataDebugMessage.debugExitMessage(null, null);
159     return Optional.ofNullable(translatedId);
160   }
161
162
163   /**
164    * Gets resource translated element template.
165    *
166    * @param heatFileName              the heat file name
167    * @param heatOrchestrationTemplate the heat orchestration template
168    * @param resourceId                the resource id
169    * @param context                   the context
170    * @return the resource translated element template
171    */
172   public static Optional<ToscaTopologyTemplateElements> getResourceTranslatedElementTemplate(
173       String heatFileName,
174       HeatOrchestrationTemplate heatOrchestrationTemplate,
175       String resourceId, TranslationContext context) {
176
177     mdcDataDebugMessage.debugEntryMessage(null, null);
178
179     Resource resource = heatOrchestrationTemplate.getResources().get(resourceId);
180     if (resource == null) {
181       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
182           LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
183           LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
184       throw new CoreException(
185           new ResourceNotFoundInHeatFileErrorBuilder(resourceId, heatFileName).build());
186     }
187     TranslateTo translateTo =
188         generateTranslationTo(heatFileName, null, heatOrchestrationTemplate, resource, resourceId,
189             null, context);
190
191     Optional<ToscaTopologyTemplateElements> translatedElementTemplate =
192         ResourceTranslationFactory.getInstance(resource)
193             .getTranslatedToscaTopologyElement(translateTo);
194
195     mdcDataDebugMessage.debugExitMessage(null, null);
196     return translatedElementTemplate;
197   }
198
199   protected String generateTranslatedId(TranslateTo translateTo) {
200     if (isEssentialRequirementsValid(translateTo)) {
201       return translateTo.getResourceId();
202     } else {
203       return null;
204     }
205
206   }
207
208   protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
209       TranslateTo translateTo) {
210     if (isEssentialRequirementsValid(translateTo)) {
211       return Optional.of(ToscaTopologyTemplateElements.NODE_TEMPLATE);
212     } else {
213       return Optional.empty();
214     }
215   }
216
217   protected boolean isEssentialRequirementsValid(TranslateTo translateTo) {
218     return true;
219   }
220
221   private static TranslateTo generateTranslationTo(String heatFileName,
222                                                    ServiceTemplate serviceTemplate,
223                                                    HeatOrchestrationTemplate
224                                                        heatOrchestrationTemplate,
225                                                    Resource resource, String resourceId,
226                                                    String translatedId,
227                                                    TranslationContext context) {
228     TranslateTo to = new TranslateTo();
229     to.setHeatFileName(heatFileName);
230     to.setServiceTemplate(serviceTemplate);
231     to.setHeatOrchestrationTemplate(heatOrchestrationTemplate);
232     to.setResource(resource);
233     to.setResourceId(resourceId);
234     to.setTranslatedId(translatedId);
235     to.setContext(context);
236     return to;
237   }
238
239   private void updateResourceDependency(TranslateTo translateTo) {
240
241     String heatFileName = translateTo.getHeatFileName();
242     mdcDataDebugMessage.debugEntryMessage("file", heatFileName);
243
244     Resource resource = translateTo.getResource();
245     HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
246         .getHeatOrchestrationTemplate();
247     String translatedId = translateTo.getTranslatedId();
248     ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
249     TranslationContext context = translateTo.getContext();
250     if (resource.getDepends_on() == null) {
251       return;
252     }
253
254     if (resource.getDepends_on() instanceof List) {
255       List<String> dependsOnList = (List<String>) resource.getDepends_on();
256       for (String dependsOnResourceId : dependsOnList) {
257         addDependOnRequirement(dependsOnResourceId, translateTo);
258       }
259     } else {
260       String dependsOnResourceId = (String) resource.getDepends_on();
261       addDependOnRequirement(dependsOnResourceId, translateTo);
262     }
263
264     mdcDataDebugMessage.debugExitMessage("file", heatFileName);
265   }
266
267   private void addDependOnRequirement(String dependsOnResourceId, TranslateTo translateTo) {
268
269     mdcDataDebugMessage.debugEntryMessage(null, null);
270     String nodeTemplateId = translateTo.getTranslatedId();
271     ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
272     String heatFileName = translateTo.getHeatFileName();
273     HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo
274         .getHeatOrchestrationTemplate();
275     TranslationContext context = translateTo.getContext();
276     RequirementAssignment requirementAssignment = new RequirementAssignment();
277     Optional<String> resourceTranslatedId =
278         getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, dependsOnResourceId,
279             context);
280
281     Optional<ToscaTopologyTemplateElements> resourceTranslatedElementTemplate =
282         getResourceTranslatedElementTemplate(heatFileName, heatOrchestrationTemplate,
283             dependsOnResourceId, context);
284
285     if (resourceTranslatedId.isPresent()
286         && (resourceTranslatedElementTemplate.isPresent() && resourceTranslatedElementTemplate
287         .get() == ToscaTopologyTemplateElements.NODE_TEMPLATE)) {
288       Resource sourceResource = translateTo.getResource();
289       Resource targetResource = HeatToToscaUtil
290           .getResource(heatOrchestrationTemplate, dependsOnResourceId,
291               translateTo.getHeatFileName());
292       if (HeatToToscaUtil
293           .isValidDependsOnCandidate(heatOrchestrationTemplate, sourceResource, targetResource,
294               ConsolidationEntityType.OTHER, translateTo.getContext())) {
295         requirementAssignment.setNode(resourceTranslatedId.get());
296         requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_NODE);
297         requirementAssignment.setRelationship(ToscaRelationshipType.NATIVE_DEPENDS_ON);
298         DataModelUtil.addRequirementAssignment(
299             serviceTemplate.getTopology_template().getNode_templates().get(nodeTemplateId),
300             ToscaConstants.DEPENDS_ON_REQUIREMENT_ID, requirementAssignment);
301         Resource dependsOnResource = targetResource;
302         ConsolidationDataUtil
303             .updateNodesConnectedData(translateTo, dependsOnResourceId, dependsOnResource,
304                 sourceResource, nodeTemplateId, ToscaConstants.DEPENDS_ON_REQUIREMENT_ID,
305                 requirementAssignment);
306       }
307     }
308     mdcDataDebugMessage.debugExitMessage(null, null);
309   }
310
311   Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
312       String heatFileName,
313       HeatOrchestrationTemplate heatOrchestrationTemplate,
314       String translatedResourceId,
315       TranslateTo translateTo,
316       String heatResourceType) {
317     mdcDataDebugMessage.debugEntryMessage(null, null);
318     List<Map.Entry<String, Resource>> list = heatOrchestrationTemplate.getResources().entrySet()
319         .stream()
320         .filter(entry -> getPredicatesForTranslatedIdToResourceId(heatFileName,
321             heatOrchestrationTemplate, translatedResourceId, translateTo.getContext(),
322             heatResourceType)
323             .stream()
324             .allMatch(p -> p.test(entry)))
325         .collect(Collectors.toList());
326     if (CollectionUtils.isEmpty(list)) {
327       mdcDataDebugMessage.debugExitMessage(null, null);
328       return Optional.empty();
329     } else {
330       mdcDataDebugMessage.debugExitMessage(null, null);
331       return Optional.of(list);
332     }
333   }
334
335   private List<Predicate<Map.Entry<String, Resource>>> getPredicatesForTranslatedIdToResourceId(
336       String heatFileName, HeatOrchestrationTemplate heatOrchestrationTemplate,
337       String translatedResourceId, TranslationContext context, String heatResourceType) {
338     List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
339     list.add(entry ->
340         entry.getValue().getType().equals(heatResourceType));
341     list.add(entry -> {
342       Optional<String> resourceTranslatedId =
343           getResourceTranslatedId(heatFileName, heatOrchestrationTemplate, entry.getKey(), context);
344       return resourceTranslatedId.isPresent()
345           && resourceTranslatedId.get().equals(translatedResourceId);
346     });
347     return list;
348   }
349
350   boolean isResourceTypeSupported(Resource resource, List<String> supporteTypes) {
351     return Objects.nonNull(resource) && supporteTypes.contains(resource.getType());
352   }
353
354 }