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