2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
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;
54 import java.util.ArrayList;
55 import java.util.List;
57 import java.util.Objects;
58 import java.util.Optional;
59 import java.util.function.Predicate;
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;
68 ResourceTranslationBase resourceTranslationBase;
70 BaseResourceConnection(ResourceTranslationBase resourceTranslationBase, TranslateTo translateTo,
71 FileData nestedFileData, NodeTemplate substitutionNodeTemplate,
73 this.translateTo = translateTo;
74 this.nestedFileData = nestedFileData;
75 this.substitutionNodeTemplate = substitutionNodeTemplate;
76 this.nodeType = nodeType;
77 this.resourceTranslationBase = resourceTranslationBase;
80 abstract boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate);
82 abstract List<Predicate<T>> getPredicatesListForConnectionPoints();
84 abstract Optional<List<String>> getConnectorPropertyParamName(String heatResourceId,
85 Resource heatResource,
86 HeatOrchestrationTemplate
87 nestedHeatOrchestrationTemplate,
88 String nestedHeatFileName);
90 abstract String getDesiredResourceType();
92 abstract String getMappedNodeTranslatedResourceId(ServiceTemplate nestedServiceTemplate,
93 Map.Entry<String, T> connectionPointEntry);
95 abstract Map.Entry<String, T> getMappedConnectionPointEntry(ServiceTemplate nestedServiceTemplate,
97 connectionPointEntry);
99 abstract void addRequirementToConnectResources(Map.Entry<String, T> connectionPointEntry,
100 List<String> paramNames);
102 abstract List<Map<String, T>> getAllConnectionPoints();
104 abstract boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
105 final String nestedPropertyName,
106 String connectionPointId,
107 Resource connectedResource,
108 List<String> supportedTypes);
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()) {
121 getConnectionParameterName(nestedServiceTemplate, nestedHeatOrchestrationTemplate,
122 nestedFileData.getFile(), connectionPointEntry);
123 if (paramNames != null && !paramNames.isEmpty()) {
124 addRequirementToConnectResources(connectionPointEntry, paramNames);
130 private List<String> getConnectionParameterName(ServiceTemplate nestedServiceTemplate,
131 HeatOrchestrationTemplate
132 nestedHeatOrchestrationTemplate,
133 String nestedHeatFileName,
134 Map.Entry<String, T> connectionPointEntry) {
137 mdcDataDebugMessage.debugEntryMessage(null, null);
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);
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)) {
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));
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);
181 mdcDataDebugMessage.debugExitMessage(null, null);
182 return connectionParameterNameList;
186 mdcDataDebugMessage.debugExitMessage(null, null);
190 private List<String> getResourcesConnectionParameterName(String translatedResourceId,
191 HeatOrchestrationTemplate
192 nestedHeatOrchestrationTemplate,
193 String nestedHeatFileName) {
196 mdcDataDebugMessage.debugEntryMessage(null, null);
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);
213 mdcDataDebugMessage.debugExitMessage(null, null);
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());
233 return resourceByTranslatedResourceId;
236 RequirementAssignment createRequirementAssignment(Map.Entry<String, RequirementDefinition>
237 requirementEntry, String node,
238 NodeTemplate nodeTemplate) {
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);
248 .addRequirementAssignment(nodeTemplate, requirementEntry.getKey(), requirementAssignment);
250 mdcDataDebugMessage.debugExitMessage(null, null);
251 return requirementAssignment;
255 Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
256 Map.Entry<String, T> connectionPointEntry, String paramName,
257 List<String> supportedNodeTypes) {
259 Optional<AttachedResourceId> attachedResourceId =
260 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
261 if (!attachedResourceId.isPresent()) {
262 return Optional.empty();
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());
276 return Optional.empty();
279 Optional<TranslatedHeatResource> getConnectionTranslatedHeatResourceUsingGetParamFunc(
280 Map.Entry<String, T> connectionPointEntry, String paramName,
281 List<String> supportedNodeTypes) {
283 Optional<AttachedResourceId> attachedResourceId =
284 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
285 if (!attachedResourceId.isPresent()) {
286 return Optional.empty();
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);
300 return Optional.empty();
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());
320 return Optional.empty();
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;
336 return Optional.empty();