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.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;
52 import java.util.ArrayList;
53 import java.util.List;
55 import java.util.Objects;
56 import java.util.Optional;
57 import java.util.function.Predicate;
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;
65 ResourceTranslationBase resourceTranslationBase;
67 BaseResourceConnection(ResourceTranslationBase resourceTranslationBase, TranslateTo translateTo,
68 FileData nestedFileData, NodeTemplate substitutionNodeTemplate,
70 this.translateTo = translateTo;
71 this.nestedFileData = nestedFileData;
72 this.substitutionNodeTemplate = substitutionNodeTemplate;
73 this.nodeType = nodeType;
74 this.resourceTranslationBase = resourceTranslationBase;
77 abstract boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate);
79 abstract List<Predicate<T>> getPredicatesListForConnectionPoints();
81 abstract Optional<List<String>> getConnectorPropertyParamName(String heatResourceId,
82 Resource heatResource,
83 HeatOrchestrationTemplate
84 nestedHeatOrchestrationTemplate,
85 String nestedHeatFileName);
87 abstract String getDesiredResourceType();
89 abstract String getMappedNodeTranslatedResourceId(ServiceTemplate nestedServiceTemplate,
90 Map.Entry<String, T> connectionPointEntry);
92 abstract Map.Entry<String, T> getMappedConnectionPointEntry(ServiceTemplate nestedServiceTemplate,
94 connectionPointEntry);
96 abstract void addRequirementToConnectResources(Map.Entry<String, T> connectionPointEntry,
97 List<String> paramNames);
99 abstract List<Map<String, T>> getAllConnectionPoints();
101 abstract boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
102 final String nestedPropertyName,
103 String connectionPointId,
104 Resource connectedResource,
105 List<String> supportedTypes);
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()) {
118 getConnectionParameterName(nestedServiceTemplate, nestedHeatOrchestrationTemplate,
119 nestedFileData.getFile(), connectionPointEntry);
120 if (paramNames != null && !paramNames.isEmpty()) {
121 addRequirementToConnectResources(connectionPointEntry, paramNames);
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);
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)) {
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));
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);
173 return connectionParameterNameList;
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);
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());
213 return resourceByTranslatedResourceId;
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);
226 .addRequirementAssignment(nodeTemplate, requirementEntry.getKey(), requirementAssignment);
228 return requirementAssignment;
232 Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
233 Map.Entry<String, T> connectionPointEntry, String paramName,
234 List<String> supportedNodeTypes) {
236 Optional<AttachedResourceId> attachedResourceId =
237 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
238 if (!attachedResourceId.isPresent()) {
239 return Optional.empty();
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());
253 return Optional.empty();
256 Optional<TranslatedHeatResource> getConnectionTranslatedHeatResourceUsingGetParamFunc(
257 Map.Entry<String, T> connectionPointEntry, String paramName,
258 List<String> supportedNodeTypes) {
260 Optional<AttachedResourceId> attachedResourceId =
261 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
262 if (!attachedResourceId.isPresent()) {
263 return Optional.empty();
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);
277 return Optional.empty();
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());
297 return Optional.empty();
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;
313 return Optional.empty();