[SDC] Onboarding 1710 rebase.
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / resourcetranslation / BaseResourceConnection.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.MapUtils;
24 import org.openecomp.sdc.tosca.services.YamlUtil;
25 import org.openecomp.sdc.common.errors.CoreException;
26 import org.openecomp.sdc.common.errors.ErrorCategory;
27 import org.openecomp.sdc.common.errors.ErrorCode;
28 import org.openecomp.sdc.datatypes.error.ErrorLevel;
29 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
30 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
31 import org.openecomp.sdc.heat.datatypes.model.Resource;
32 import org.openecomp.sdc.logging.api.Logger;
33 import org.openecomp.sdc.logging.api.LoggerFactory;
34 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
35 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
36 import org.openecomp.sdc.logging.types.LoggerConstants;
37 import org.openecomp.sdc.logging.types.LoggerErrorCode;
38 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
39 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
40 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
41 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
42 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
43 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
44 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
45 import org.openecomp.sdc.tosca.services.DataModelUtil;
46 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
47 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
48 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
49 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
50 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
51 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
52 import org.openecomp.sdc.translator.services.heattotosca.errors.TranslatorErrorCodes;
53
54 import java.util.ArrayList;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.Objects;
58 import java.util.Optional;
59 import java.util.function.Predicate;
60
61 abstract class BaseResourceConnection<T> {
62   protected static Logger logger = (Logger) LoggerFactory.getLogger(BaseResourceConnection.class);
63   protected static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
64   protected TranslateTo translateTo;
65   FileData nestedFileData;
66   NodeTemplate substitutionNodeTemplate;
67   NodeType nodeType;
68   ResourceTranslationBase resourceTranslationBase;
69
70   BaseResourceConnection(ResourceTranslationBase resourceTranslationBase, TranslateTo translateTo,
71                          FileData nestedFileData, NodeTemplate substitutionNodeTemplate,
72                          NodeType nodeType) {
73     this.translateTo = translateTo;
74     this.nestedFileData = nestedFileData;
75     this.substitutionNodeTemplate = substitutionNodeTemplate;
76     this.nodeType = nodeType;
77     this.resourceTranslationBase = resourceTranslationBase;
78   }
79
80   abstract boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate);
81
82   abstract List<Predicate<T>> getPredicatesListForConnectionPoints();
83
84   abstract Optional<List<String>> getConnectorPropertyParamName(String heatResourceId,
85                                                                 Resource heatResource,
86                                                                 HeatOrchestrationTemplate
87                                                                     nestedHeatOrchestrationTemplate,
88                                                                 String nestedHeatFileName);
89
90   abstract String getDesiredResourceType();
91
92   abstract String getMappedNodeTranslatedResourceId(ServiceTemplate nestedServiceTemplate,
93                                                     Map.Entry<String, T> connectionPointEntry);
94
95   abstract Map.Entry<String, T> getMappedConnectionPointEntry(ServiceTemplate nestedServiceTemplate,
96                                                               Map.Entry<String, T>
97                                                                   connectionPointEntry);
98
99   abstract void addRequirementToConnectResources(Map.Entry<String, T> connectionPointEntry,
100                                                  List<String> paramNames);
101
102   abstract List<Map<String, T>> getAllConnectionPoints();
103
104   abstract boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
105                                                                final String nestedPropertyName,
106                                                                String connectionPointId,
107                                                                Resource connectedResource,
108                                                                List<String> supportedTypes);
109
110   void connect() {
111     ServiceTemplate nestedServiceTemplate = translateTo.getContext().getTranslatedServiceTemplates()
112         .get(translateTo.getResource().getType());
113     List<String> paramNames;
114     HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
115         .yamlToObject(translateTo.getContext().getFileContent(nestedFileData.getFile()),
116             HeatOrchestrationTemplate.class);
117     List<Map<String, T>> exposedConnectionPoints = getAllConnectionPoints();
118     for (Map<String, T> connectionPointsMap : exposedConnectionPoints) {
119       for (Map.Entry<String, T> connectionPointEntry : connectionPointsMap.entrySet()) {
120         paramNames =
121             getConnectionParameterName(nestedServiceTemplate, nestedHeatOrchestrationTemplate,
122                 nestedFileData.getFile(), connectionPointEntry);
123         if (paramNames != null && !paramNames.isEmpty()) {
124           addRequirementToConnectResources(connectionPointEntry, paramNames);
125         }
126       }
127     }
128   }
129
130   private List<String> getConnectionParameterName(ServiceTemplate nestedServiceTemplate,
131                                                   HeatOrchestrationTemplate
132                                                       nestedHeatOrchestrationTemplate,
133                                                   String nestedHeatFileName,
134                                                   Map.Entry<String, T> connectionPointEntry) {
135
136
137     mdcDataDebugMessage.debugEntryMessage(null, null);
138
139     List<String> connectionParameterNameList = new ArrayList<>();
140     String mappedTranslatedResourceId =
141         getMappedNodeTranslatedResourceId(nestedServiceTemplate, connectionPointEntry);
142     NodeTemplate mappedNodeTemplate =
143         nestedServiceTemplate.getTopology_template().getNode_templates()
144             .get(mappedTranslatedResourceId);
145     if (isDesiredNodeTemplateType(mappedNodeTemplate)) {
146       return getResourcesConnectionParameterName(mappedTranslatedResourceId,
147           nestedHeatOrchestrationTemplate, nestedHeatFileName);
148     }
149
150     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
151     if (toscaAnalyzerService.isSubstitutableNodeTemplate(mappedNodeTemplate)) {
152       Optional<String> mappedSubstituteServiceTemplateName = toscaAnalyzerService
153           .getSubstituteServiceTemplateName(mappedTranslatedResourceId, mappedNodeTemplate);
154       if (mappedSubstituteServiceTemplateName.isPresent()) {
155         String mappedNestedHeatFileName = translateTo.getContext().getNestedHeatFileName()
156             .get(mappedSubstituteServiceTemplateName.get());
157         if (Objects.isNull(mappedNestedHeatFileName)) {
158           return null;
159         }
160         HeatOrchestrationTemplate mappedNestedHeatOrchestrationTemplate = new YamlUtil()
161             .yamlToObject(translateTo.getContext().getFileContent(mappedNestedHeatFileName),
162                 HeatOrchestrationTemplate.class);
163         ServiceTemplate mappedNestedServiceTemplate =
164             translateTo.getContext().getTranslatedServiceTemplates().get(mappedNestedHeatFileName);
165         List<String> nestedPropertyNames = getConnectionParameterName(mappedNestedServiceTemplate,
166             mappedNestedHeatOrchestrationTemplate, mappedNestedHeatFileName,
167             getMappedConnectionPointEntry(nestedServiceTemplate, connectionPointEntry));
168
169         if (nestedPropertyNames != null && !nestedPropertyNames.isEmpty()) {
170           for (String propertyName : nestedPropertyNames) {
171             Object propertyValue = mappedNodeTemplate.getProperties().get(propertyName);
172             if (propertyValue instanceof Map && ((Map) propertyValue).containsKey("get_input")) {
173               Object paramName = ((Map) propertyValue).get("get_input");
174               if (paramName instanceof String) {
175                 connectionParameterNameList.add((String) paramName);
176               }
177             }
178           }
179         }
180
181         mdcDataDebugMessage.debugExitMessage(null, null);
182         return connectionParameterNameList;
183       }
184     }
185
186     mdcDataDebugMessage.debugExitMessage(null, null);
187     return null;
188   }
189
190   private List<String> getResourcesConnectionParameterName(String translatedResourceId,
191                                                            HeatOrchestrationTemplate
192                                                                nestedHeatOrchestrationTemplate,
193                                                            String nestedHeatFileName) {
194
195
196     mdcDataDebugMessage.debugEntryMessage(null, null);
197
198     List<String> params = new ArrayList<>();
199     Optional<List<Map.Entry<String, Resource>>> heatResources =
200         getResourceByTranslatedResourceId(translatedResourceId, nestedHeatOrchestrationTemplate);
201     if (heatResources.isPresent()) {
202       for (Map.Entry<String, Resource> resourceEntry : heatResources.get()) {
203         Resource heatResource = resourceEntry.getValue();
204         if (!MapUtils.isEmpty(heatResource.getProperties())) {
205           Optional<List<String>> connectorParamName =
206               getConnectorPropertyParamName(resourceEntry.getKey(), heatResource,
207                   nestedHeatOrchestrationTemplate, nestedHeatFileName);
208           connectorParamName.ifPresent(params::addAll);
209         }
210       }
211     }
212
213     mdcDataDebugMessage.debugExitMessage(null, null);
214     return params;
215   }
216
217   protected Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
218       String translatedResourceId, HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
219     Optional<List<Map.Entry<String, Resource>>> resourceByTranslatedResourceId =
220         resourceTranslationBase.getResourceByTranslatedResourceId(nestedFileData.getFile(),
221             nestedHeatOrchestrationTemplate, translatedResourceId, translateTo,
222             getDesiredResourceType());
223     if (!resourceByTranslatedResourceId.isPresent()) {
224       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
225           LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
226           LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
227       throw new CoreException((new ErrorCode.ErrorCodeBuilder()).withMessage(
228           "Failed to get original resource from heat for translate resource id '"
229               + translatedResourceId + "'")
230           .withId(TranslatorErrorCodes.HEAT_TO_TOSCA_MAPPING_COLLISION)
231           .withCategory(ErrorCategory.APPLICATION).build());
232     }
233     return resourceByTranslatedResourceId;
234   }
235
236   RequirementAssignment createRequirementAssignment(Map.Entry<String, RequirementDefinition>
237                                                         requirementEntry, String node,
238                                                     NodeTemplate nodeTemplate) {
239
240     mdcDataDebugMessage.debugEntryMessage(null, null);
241     RequirementAssignment requirementAssignment = null;
242     if (Objects.nonNull(node)) {
243       requirementAssignment = new RequirementAssignment();
244       requirementAssignment.setRelationship(requirementEntry.getValue().getRelationship());
245       requirementAssignment.setCapability(requirementEntry.getValue().getCapability());
246       requirementAssignment.setNode(node);
247       DataModelUtil
248           .addRequirementAssignment(nodeTemplate, requirementEntry.getKey(), requirementAssignment);
249     }
250     mdcDataDebugMessage.debugExitMessage(null, null);
251     return requirementAssignment;
252   }
253
254
255   Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
256       Map.Entry<String, T> connectionPointEntry, String paramName,
257       List<String> supportedNodeTypes) {
258
259     Optional<AttachedResourceId> attachedResourceId =
260         HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
261     if (!attachedResourceId.isPresent()) {
262       return Optional.empty();
263     }
264     AttachedResourceId resourceId = attachedResourceId.get();
265     if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
266       TranslatedHeatResource shareResource =
267           translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
268       if (Objects.nonNull(shareResource)
269           && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
270         if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
271             connectionPointEntry.getKey(), shareResource.getHeatResource(), supportedNodeTypes)) {
272           return Optional.of(shareResource.getTranslatedId());
273         }
274       }
275     }
276     return Optional.empty();
277   }
278
279   Optional<TranslatedHeatResource> getConnectionTranslatedHeatResourceUsingGetParamFunc(
280       Map.Entry<String, T> connectionPointEntry, String paramName,
281       List<String> supportedNodeTypes) {
282
283     Optional<AttachedResourceId> attachedResourceId =
284         HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
285     if (!attachedResourceId.isPresent()) {
286       return Optional.empty();
287     }
288     AttachedResourceId resourceId = attachedResourceId.get();
289     if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
290       TranslatedHeatResource shareResource =
291           translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
292       if (Objects.nonNull(shareResource)
293           && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
294         if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
295             connectionPointEntry.getKey(), shareResource.getHeatResource(), supportedNodeTypes)) {
296           return Optional.of(shareResource);
297         }
298       }
299     }
300     return Optional.empty();
301   }
302
303
304   Optional<String> getConnectionTranslatedNodeUsingGetResourceFunc(
305       Map.Entry<String, T> connectionPointEntry, String paramName, Object paramValue,
306       List<String> supportedNodeTypes) {
307     Optional<String> getResourceAttachedResourceId =
308         HeatToToscaUtil.extractContrailGetResourceAttachedHeatResourceId(paramValue);
309     if (getResourceAttachedResourceId.isPresent()) { // get resource
310       Resource resource = translateTo.getHeatOrchestrationTemplate().getResources()
311           .get(getResourceAttachedResourceId.get());
312       if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
313           connectionPointEntry.getKey(), resource, supportedNodeTypes)) {
314         return ResourceTranslationBase.getResourceTranslatedId(translateTo.getHeatFileName(),
315             translateTo.getHeatOrchestrationTemplate(), getResourceAttachedResourceId.get(),
316             translateTo.getContext());
317       }
318     }
319
320     return Optional.empty();
321   }
322
323   Optional<String> getConnectionResourceUsingGetResourceFunc(
324       Map.Entry<String, T> connectionPointEntry, String paramName, Object paramValue,
325       List<String> supportedNodeTypes) {
326     Optional<String> getResourceAttachedResourceId =
327         HeatToToscaUtil.extractContrailGetResourceAttachedHeatResourceId(paramValue);
328     if (getResourceAttachedResourceId.isPresent()) { // get resource
329       Resource resource = translateTo.getHeatOrchestrationTemplate().getResources()
330           .get(getResourceAttachedResourceId.get());
331       if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
332           connectionPointEntry.getKey(), resource, supportedNodeTypes)) {
333         return getResourceAttachedResourceId;
334       }
335     }
336     return Optional.empty();
337   }
338 }