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.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.context.impl.MdcDataErrorMessage;
34 import org.openecomp.sdc.logging.types.LoggerConstants;
35 import org.openecomp.sdc.logging.types.LoggerErrorCode;
36 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
37 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
38 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
39 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
40 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
41 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
42 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
43 import org.openecomp.sdc.tosca.services.DataModelUtil;
44 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
45 import org.openecomp.sdc.tosca.services.YamlUtil;
46 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
47 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
48 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
49 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
50 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
51 import org.openecomp.sdc.translator.services.heattotosca.errors.TranslatorErrorCodes;
53 import java.util.ArrayList;
54 import java.util.List;
56 import java.util.Objects;
57 import java.util.Optional;
58 import java.util.function.Predicate;
60 abstract class BaseResourceConnection<T> {
61 protected static Logger logger = (Logger) LoggerFactory.getLogger(BaseResourceConnection.class);
62 protected TranslateTo translateTo;
63 FileData nestedFileData;
64 NodeTemplate substitutionNodeTemplate;
66 ResourceTranslationBase resourceTranslationBase;
68 BaseResourceConnection(ResourceTranslationBase resourceTranslationBase, TranslateTo translateTo,
69 FileData nestedFileData, NodeTemplate substitutionNodeTemplate,
71 this.translateTo = translateTo;
72 this.nestedFileData = nestedFileData;
73 this.substitutionNodeTemplate = substitutionNodeTemplate;
74 this.nodeType = nodeType;
75 this.resourceTranslationBase = resourceTranslationBase;
78 abstract boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate);
80 abstract List<Predicate<T>> getPredicatesListForConnectionPoints();
82 abstract Optional<List<String>> getConnectorPropertyParamName(String heatResourceId,
83 Resource heatResource,
84 HeatOrchestrationTemplate
85 nestedHeatOrchestrationTemplate,
86 String nestedHeatFileName);
88 abstract String getDesiredResourceType();
90 abstract String getMappedNodeTranslatedResourceId(ServiceTemplate nestedServiceTemplate,
91 Map.Entry<String, T> connectionPointEntry);
93 abstract Map.Entry<String, T> getMappedConnectionPointEntry(ServiceTemplate nestedServiceTemplate,
95 connectionPointEntry);
97 abstract void addRequirementToConnectResources(Map.Entry<String, T> connectionPointEntry,
98 List<String> paramNames);
100 abstract List<Map<String, T>> getAllConnectionPoints();
102 abstract boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
103 final String nestedPropertyName,
104 String connectionPointId,
105 Resource connectedResource,
106 List<String> supportedTypes);
109 ServiceTemplate nestedServiceTemplate = translateTo.getContext().getTranslatedServiceTemplates()
110 .get(translateTo.getResource().getType());
111 List<String> paramNames;
112 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
113 .yamlToObject(translateTo.getContext().getFileContent(nestedFileData.getFile()),
114 HeatOrchestrationTemplate.class);
115 List<Map<String, T>> exposedConnectionPoints = getAllConnectionPoints();
116 for (Map<String, T> connectionPointsMap : exposedConnectionPoints) {
117 for (Map.Entry<String, T> connectionPointEntry : connectionPointsMap.entrySet()) {
119 getConnectionParameterName(nestedServiceTemplate, nestedHeatOrchestrationTemplate,
120 nestedFileData.getFile(), connectionPointEntry);
121 if (paramNames != null && !paramNames.isEmpty()) {
122 addRequirementToConnectResources(connectionPointEntry, paramNames);
128 private List<String> getConnectionParameterName(ServiceTemplate nestedServiceTemplate,
129 HeatOrchestrationTemplate
130 nestedHeatOrchestrationTemplate,
131 String nestedHeatFileName,
132 Map.Entry<String, T> connectionPointEntry) {
133 List<String> connectionParameterNameList = new ArrayList<>();
134 String mappedTranslatedResourceId =
135 getMappedNodeTranslatedResourceId(nestedServiceTemplate, connectionPointEntry);
136 NodeTemplate mappedNodeTemplate =
137 nestedServiceTemplate.getTopology_template().getNode_templates()
138 .get(mappedTranslatedResourceId);
139 if (isDesiredNodeTemplateType(mappedNodeTemplate)) {
140 return getResourcesConnectionParameterName(mappedTranslatedResourceId,
141 nestedHeatOrchestrationTemplate, nestedHeatFileName);
144 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
145 if (toscaAnalyzerService.isSubstitutableNodeTemplate(mappedNodeTemplate)) {
146 Optional<String> mappedSubstituteServiceTemplateName = toscaAnalyzerService
147 .getSubstituteServiceTemplateName(mappedTranslatedResourceId, mappedNodeTemplate);
148 if (mappedSubstituteServiceTemplateName.isPresent()) {
149 String mappedNestedHeatFileName = translateTo.getContext().getNestedHeatFileName()
150 .get(mappedSubstituteServiceTemplateName.get());
151 if (Objects.isNull(mappedNestedHeatFileName)) {
154 HeatOrchestrationTemplate mappedNestedHeatOrchestrationTemplate = new YamlUtil()
155 .yamlToObject(translateTo.getContext().getFileContent(mappedNestedHeatFileName),
156 HeatOrchestrationTemplate.class);
157 ServiceTemplate mappedNestedServiceTemplate =
158 translateTo.getContext().getTranslatedServiceTemplates().get(mappedNestedHeatFileName);
159 List<String> nestedPropertyNames = getConnectionParameterName(mappedNestedServiceTemplate,
160 mappedNestedHeatOrchestrationTemplate, mappedNestedHeatFileName,
161 getMappedConnectionPointEntry(nestedServiceTemplate, connectionPointEntry));
163 if (nestedPropertyNames != null && !nestedPropertyNames.isEmpty()) {
164 for (String propertyName : nestedPropertyNames) {
165 Object propertyValue = mappedNodeTemplate.getProperties().get(propertyName);
166 if (propertyValue instanceof Map && ((Map) propertyValue).containsKey("get_input")) {
167 Object paramName = ((Map) propertyValue).get("get_input");
168 if (paramName instanceof String) {
169 connectionParameterNameList.add((String) paramName);
174 return connectionParameterNameList;
180 private List<String> getResourcesConnectionParameterName(String translatedResourceId,
181 HeatOrchestrationTemplate
182 nestedHeatOrchestrationTemplate,
183 String nestedHeatFileName) {
184 List<String> params = new ArrayList<>();
185 Optional<List<Map.Entry<String, Resource>>> heatResources =
186 getResourceByTranslatedResourceId(translatedResourceId, nestedHeatOrchestrationTemplate);
187 if (heatResources.isPresent()) {
188 for (Map.Entry<String, Resource> resourceEntry : heatResources.get()) {
189 Resource heatResource = resourceEntry.getValue();
190 if (!MapUtils.isEmpty(heatResource.getProperties())) {
191 Optional<List<String>> connectorParamName =
192 getConnectorPropertyParamName(resourceEntry.getKey(), heatResource,
193 nestedHeatOrchestrationTemplate, nestedHeatFileName);
194 connectorParamName.ifPresent(params::addAll);
201 protected Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
202 String translatedResourceId, HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
203 Optional<List<Map.Entry<String, Resource>>> resourceByTranslatedResourceId =
204 resourceTranslationBase.getResourceByTranslatedResourceId(nestedFileData.getFile(),
205 nestedHeatOrchestrationTemplate, translatedResourceId, translateTo,
206 getDesiredResourceType());
207 if (!resourceByTranslatedResourceId.isPresent()) {
208 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
209 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
210 LoggerErrorCode.DATA_ERROR.getErrorCode(), LoggerErrorDescription.TRANSLATE_HEAT);
211 throw new CoreException((new ErrorCode.ErrorCodeBuilder()).withMessage(
212 "Failed to get original resource from heat for translate resource id '"
213 + translatedResourceId + "'")
214 .withId(TranslatorErrorCodes.HEAT_TO_TOSCA_MAPPING_COLLISION)
215 .withCategory(ErrorCategory.APPLICATION).build());
217 return resourceByTranslatedResourceId;
220 RequirementAssignment createRequirementAssignment(Map.Entry<String, RequirementDefinition>
221 requirementEntry, String node,
222 NodeTemplate nodeTemplate) {
223 RequirementAssignment requirementAssignment = null;
224 if (Objects.nonNull(node)) {
225 requirementAssignment = new RequirementAssignment();
226 requirementAssignment.setRelationship(requirementEntry.getValue().getRelationship());
227 requirementAssignment.setCapability(requirementEntry.getValue().getCapability());
228 requirementAssignment.setNode(node);
230 .addRequirementAssignment(nodeTemplate, requirementEntry.getKey(), requirementAssignment);
232 return requirementAssignment;
236 Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
237 Map.Entry<String, T> connectionPointEntry, String paramName,
238 List<String> supportedNodeTypes) {
240 Optional<AttachedResourceId> attachedResourceId =
241 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
242 if (!attachedResourceId.isPresent()) {
243 return Optional.empty();
245 AttachedResourceId resourceId = attachedResourceId.get();
246 if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
247 TranslatedHeatResource shareResource =
248 translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
249 if (Objects.nonNull(shareResource)
250 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
251 if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
252 connectionPointEntry.getKey(), shareResource.getHeatResource(), supportedNodeTypes)) {
253 return Optional.of(shareResource.getTranslatedId());
257 return Optional.empty();
260 Optional<TranslatedHeatResource> getConnectionTranslatedHeatResourceUsingGetParamFunc(
261 Map.Entry<String, T> connectionPointEntry, String paramName,
262 List<String> supportedNodeTypes) {
264 Optional<AttachedResourceId> attachedResourceId =
265 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
266 if (!attachedResourceId.isPresent()) {
267 return Optional.empty();
269 AttachedResourceId resourceId = attachedResourceId.get();
270 if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
271 TranslatedHeatResource shareResource =
272 translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
273 if (Objects.nonNull(shareResource)
274 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
275 if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
276 connectionPointEntry.getKey(), shareResource.getHeatResource(), supportedNodeTypes)) {
277 return Optional.of(shareResource);
281 return Optional.empty();
285 Optional<String> getConnectionTranslatedNodeUsingGetResourceFunc(
286 Map.Entry<String, T> connectionPointEntry, String paramName, Object paramValue,
287 List<String> supportedNodeTypes) {
288 Optional<String> getResourceAttachedResourceId =
289 HeatToToscaUtil.extractContrailGetResourceAttachedHeatResourceId(paramValue);
290 if (getResourceAttachedResourceId.isPresent()) { // get resource
291 Resource resource = translateTo.getHeatOrchestrationTemplate().getResources()
292 .get(getResourceAttachedResourceId.get());
293 if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
294 connectionPointEntry.getKey(), resource, supportedNodeTypes)) {
295 return ResourceTranslationBase.getResourceTranslatedId(translateTo.getHeatFileName(),
296 translateTo.getHeatOrchestrationTemplate(), getResourceAttachedResourceId.get(),
297 translateTo.getContext());
301 return Optional.empty();
304 Optional<String> getConnectionResourceUsingGetResourceFunc(
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 getResourceAttachedResourceId;
317 return Optional.empty();