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