2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
23 import java.util.Objects;
24 import java.util.Optional;
25 import java.util.function.Predicate;
27 import org.apache.commons.collections4.CollectionUtils;
28 import org.apache.commons.collections4.MapUtils;
29 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
30 import org.onap.sdc.tosca.datatypes.model.NodeType;
31 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
32 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
33 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
34 import org.onap.sdc.tosca.services.YamlUtil;
35 import org.openecomp.sdc.common.errors.CoreException;
36 import org.openecomp.sdc.common.errors.ErrorCategory;
37 import org.openecomp.sdc.common.errors.ErrorCode;
38 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
39 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
40 import org.openecomp.sdc.heat.datatypes.model.Resource;
41 import org.openecomp.sdc.logging.api.Logger;
42 import org.openecomp.sdc.logging.api.LoggerFactory;
43 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
44 import org.openecomp.sdc.tosca.services.DataModelUtil;
45 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
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 abstract class BaseResourceConnection<T> {
54 protected static Logger logger = LoggerFactory.getLogger(BaseResourceConnection.class);
55 protected TranslateTo translateTo;
56 FileData nestedFileData;
57 NodeTemplate substitutionNodeTemplate;
59 ResourceTranslationBase resourceTranslationBase;
61 BaseResourceConnection(ResourceTranslationBase resourceTranslationBase, TranslateTo translateTo,
62 FileData nestedFileData, NodeTemplate substitutionNodeTemplate,
64 this.translateTo = translateTo;
65 this.nestedFileData = nestedFileData;
66 this.substitutionNodeTemplate = substitutionNodeTemplate;
67 this.nodeType = nodeType;
68 this.resourceTranslationBase = resourceTranslationBase;
71 abstract boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate);
73 abstract List<Predicate<T>> getPredicatesListForConnectionPoints();
75 abstract Optional<List<String>> getConnectorPropertyParamName(String heatResourceId,
76 Resource heatResource,
77 HeatOrchestrationTemplate
78 nestedHeatOrchestrationTemplate,
79 String nestedHeatFileName);
81 abstract String getDesiredResourceType();
83 abstract String getMappedNodeTranslatedResourceId(ServiceTemplate nestedServiceTemplate,
84 Map.Entry<String, T> connectionPointEntry);
86 abstract Map.Entry<String, T> getMappedConnectionPointEntry(ServiceTemplate nestedServiceTemplate,
88 connectionPointEntry);
90 abstract void addRequirementToConnectResources(Map.Entry<String, T> connectionPointEntry,
91 List<String> paramNames);
93 abstract List<Map<String, T>> getAllConnectionPoints();
95 abstract boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
96 final String nestedPropertyName,
97 String connectionPointId,
98 Resource connectedResource,
99 List<String> supportedTypes);
102 ServiceTemplate nestedServiceTemplate = translateTo.getContext().getTranslatedServiceTemplates()
103 .get(translateTo.getResource().getType());
104 List<String> paramNames;
105 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate = new YamlUtil()
106 .yamlToObject(translateTo.getContext().getFileContentAsStream(nestedFileData.getFile()),
107 HeatOrchestrationTemplate.class);
108 List<Map<String, T>> exposedConnectionPoints = getAllConnectionPoints();
109 for (Map<String, T> connectionPointsMap : exposedConnectionPoints) {
110 for (Map.Entry<String, T> connectionPointEntry : connectionPointsMap.entrySet()) {
112 getConnectionParameterName(nestedServiceTemplate, nestedHeatOrchestrationTemplate,
113 nestedFileData.getFile(), connectionPointEntry);
114 if (CollectionUtils.isNotEmpty(paramNames)) {
115 addRequirementToConnectResources(connectionPointEntry, paramNames);
121 private List<String> getConnectionParameterName(ServiceTemplate nestedServiceTemplate,
122 HeatOrchestrationTemplate
123 nestedHeatOrchestrationTemplate,
124 String nestedHeatFileName,
125 Map.Entry<String, T> connectionPointEntry) {
126 List<String> connectionParameterNameList = new ArrayList<>();
127 String mappedTranslatedResourceId = getMappedNodeTranslatedResourceId(nestedServiceTemplate,
128 connectionPointEntry);
129 NodeTemplate mappedNodeTemplate = nestedServiceTemplate.getTopology_template().getNode_templates()
130 .get(mappedTranslatedResourceId);
131 if (isDesiredNodeTemplateType(mappedNodeTemplate)) {
132 return getResourcesConnectionParameterName(mappedTranslatedResourceId,
133 nestedHeatOrchestrationTemplate, nestedHeatFileName);
136 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
137 if (!toscaAnalyzerService.isSubstitutableNodeTemplate(mappedNodeTemplate)) {
138 return Collections.emptyList();
140 Optional<String> mappedSubstituteServiceTemplateName = toscaAnalyzerService
141 .getSubstituteServiceTemplateName(mappedTranslatedResourceId, mappedNodeTemplate);
142 if (!mappedSubstituteServiceTemplateName.isPresent()) {
143 return Collections.emptyList();
145 String mappedNestedHeatFileName = translateTo.getContext().getNestedHeatFileName()
146 .get(mappedSubstituteServiceTemplateName.get());
147 if (Objects.isNull(mappedNestedHeatFileName)) {
148 return Collections.emptyList();
150 HeatOrchestrationTemplate mappedNestedHeatOrchestrationTemplate = new YamlUtil()
151 .yamlToObject(translateTo.getContext().getFileContentAsStream(mappedNestedHeatFileName),
152 HeatOrchestrationTemplate.class);
153 ServiceTemplate mappedNestedServiceTemplate =
154 translateTo.getContext().getTranslatedServiceTemplates().get(mappedNestedHeatFileName);
155 List<String> nestedPropertyNames = getConnectionParameterName(mappedNestedServiceTemplate,
156 mappedNestedHeatOrchestrationTemplate, mappedNestedHeatFileName,
157 getMappedConnectionPointEntry(nestedServiceTemplate, connectionPointEntry));
159 if (CollectionUtils.isEmpty(nestedPropertyNames)) {
160 return connectionParameterNameList;
162 for (String propertyName : nestedPropertyNames) {
163 Object propertyValue = mappedNodeTemplate.getProperties().get(propertyName);
164 if (propertyValue instanceof Map
165 && ((Map) propertyValue).containsKey(ToscaFunctions.GET_INPUT.getFunctionName())) {
166 Object paramName = ((Map) propertyValue).get(ToscaFunctions.GET_INPUT.getFunctionName());
167 if (paramName instanceof String) {
168 connectionParameterNameList.add((String) paramName);
172 return connectionParameterNameList;
175 private List<String> getResourcesConnectionParameterName(String translatedResourceId,
176 HeatOrchestrationTemplate
177 nestedHeatOrchestrationTemplate,
178 String nestedHeatFileName) {
179 List<String> params = new ArrayList<>();
180 Optional<List<Map.Entry<String, Resource>>> heatResources =
181 getResourceByTranslatedResourceId(translatedResourceId, nestedHeatOrchestrationTemplate);
182 if (!heatResources.isPresent()) {
185 for (Map.Entry<String, Resource> resourceEntry : heatResources.get()) {
186 Resource heatResource = resourceEntry.getValue();
187 if (!MapUtils.isEmpty(heatResource.getProperties())) {
188 Optional<List<String>> connectorParamName =
189 getConnectorPropertyParamName(resourceEntry.getKey(), heatResource,
190 nestedHeatOrchestrationTemplate, nestedHeatFileName);
191 connectorParamName.ifPresent(params::addAll);
197 protected Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
198 String translatedResourceId, HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
199 Optional<List<Map.Entry<String, Resource>>> resourceByTranslatedResourceId =
200 resourceTranslationBase.getResourceByTranslatedResourceId(nestedFileData.getFile(),
201 nestedHeatOrchestrationTemplate, translatedResourceId, translateTo,
202 getDesiredResourceType());
203 if (!resourceByTranslatedResourceId.isPresent()) {
204 throw new CoreException((new ErrorCode.ErrorCodeBuilder()).withMessage(
205 "Failed to get original resource from heat for translate resource id '"
206 + translatedResourceId + "'")
207 .withId(TranslatorErrorCodes.HEAT_TO_TOSCA_MAPPING_COLLISION)
208 .withCategory(ErrorCategory.APPLICATION).build());
210 return resourceByTranslatedResourceId;
213 RequirementAssignment createRequirementAssignment(Map.Entry<String, RequirementDefinition> requirementEntry,
215 NodeTemplate nodeTemplate) {
216 RequirementAssignment requirementAssignment = null;
217 if (Objects.nonNull(node)) {
218 requirementAssignment = new RequirementAssignment();
219 requirementAssignment.setRelationship(requirementEntry.getValue().getRelationship());
220 requirementAssignment.setCapability(requirementEntry.getValue().getCapability());
221 requirementAssignment.setNode(node);
222 DataModelUtil.addRequirementAssignment(nodeTemplate, requirementEntry.getKey(), requirementAssignment);
224 return requirementAssignment;
228 Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
229 Map.Entry<String, T> connectionPointEntry, String paramName,
230 List<String> supportedNodeTypes) {
232 Optional<AttachedResourceId> attachedResourceId =
233 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
234 if (!attachedResourceId.isPresent()) {
235 return Optional.empty();
237 AttachedResourceId resourceId = attachedResourceId.get();
238 if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
239 TranslatedHeatResource shareResource =
240 translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
241 if (isSupportedSharedResource(paramName, connectionPointEntry.getKey(), supportedNodeTypes,
243 return Optional.of(shareResource.getTranslatedId());
246 return Optional.empty();
249 private boolean isSupportedSharedResource(String paramName, String connectionPointId,
250 List<String> supportedNodeTypes,
251 TranslatedHeatResource shareResource) {
252 return Objects.nonNull(shareResource)
253 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())
254 && validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
255 connectionPointId, shareResource.getHeatResource(), supportedNodeTypes);
258 Optional<TranslatedHeatResource> getConnectionTranslatedHeatResourceUsingGetParamFunc(
259 Map.Entry<String, T> connectionPointEntry, String paramName,
260 List<String> supportedNodeTypes) {
262 Optional<AttachedResourceId> attachedResourceId =
263 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
264 if (!attachedResourceId.isPresent()) {
265 return Optional.empty();
267 AttachedResourceId resourceId = attachedResourceId.get();
268 if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
269 TranslatedHeatResource shareResource =
270 translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
271 if (isSupportedSharedResource(paramName, connectionPointEntry.getKey(), supportedNodeTypes,
273 return Optional.of(shareResource);
276 return Optional.empty();
280 Optional<String> getConnectionTranslatedNodeUsingGetResourceFunc(
281 Map.Entry<String, T> connectionPointEntry, String paramName, Object paramValue,
282 List<String> supportedNodeTypes) {
283 Optional<String> getResourceAttachedResourceId =
284 HeatToToscaUtil.extractContrailGetResourceAttachedHeatResourceId(paramValue);
285 if (getResourceAttachedResourceId.isPresent()) { // get resource
286 Resource resource = translateTo.getHeatOrchestrationTemplate().getResources()
287 .get(getResourceAttachedResourceId.get());
288 if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
289 connectionPointEntry.getKey(), resource, supportedNodeTypes)) {
290 return ResourceTranslationBase.getResourceTranslatedId(translateTo.getHeatFileName(),
291 translateTo.getHeatOrchestrationTemplate(), getResourceAttachedResourceId.get(),
292 translateTo.getContext());
296 return Optional.empty();
299 Optional<String> getConnectionResourceUsingGetResourceFunc(
300 Map.Entry<String, T> connectionPointEntry, String paramName, Object paramValue,
301 List<String> supportedNodeTypes) {
302 Optional<String> getResourceAttachedResourceId =
303 HeatToToscaUtil.extractContrailGetResourceAttachedHeatResourceId(paramValue);
304 if (getResourceAttachedResourceId.isPresent()) { // get resource
305 Resource resource = translateTo.getHeatOrchestrationTemplate().getResources()
306 .get(getResourceAttachedResourceId.get());
307 if (validateResourceTypeSupportedForReqCreation(translateTo.getResourceId(), paramName,
308 connectionPointEntry.getKey(), resource, supportedNodeTypes)) {
309 return getResourceAttachedResourceId;
312 return Optional.empty();