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.CollectionUtils;
24 import org.openecomp.sdc.common.errors.CoreException;
25 import org.openecomp.sdc.datatypes.error.ErrorLevel;
26 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
27 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
28 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
29 import org.openecomp.sdc.heat.datatypes.model.Resource;
30 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
31 import org.openecomp.sdc.logging.types.LoggerConstants;
32 import org.openecomp.sdc.logging.types.LoggerErrorCode;
33 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
34 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
35 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
36 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
37 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
38 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
39 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
40 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
41 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
42 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
43 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
44 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
45 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
46 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ResourceFileDataAndIDs;
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.MissingMandatoryPropertyErrorBuilder;
51 import org.openecomp.sdc.translator.services.heattotosca.helper.VolumeTranslationHelper;
53 import java.util.ArrayList;
54 import java.util.Collections;
55 import java.util.List;
57 import java.util.Objects;
58 import java.util.Optional;
59 import java.util.function.Predicate;
60 import java.util.stream.Collectors;
62 class NovaToVolResourceConnection extends ResourceConnectionUsingRequirementHelper {
64 public NovaToVolResourceConnection(ResourceTranslationBase resourceTranslationBase,
65 TranslateTo translateTo, FileData nestedFileData,
66 NodeTemplate substitutionNodeTemplate, NodeType nodeType) {
67 super(resourceTranslationBase, translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
71 boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate) {
72 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
73 ToscaServiceModel toscaServiceModel =
74 HeatToToscaUtil.getToscaServiceModel(translateTo.getContext());
75 return toscaAnalyzerService.isTypeOf(nodeTemplate, ToscaNodeType.NOVA_SERVER,
76 translateTo.getContext().getTranslatedServiceTemplates()
77 .get(translateTo.getResource().getType()), toscaServiceModel);
81 List<Predicate<RequirementDefinition>> getPredicatesListForConnectionPoints() {
82 ArrayList<Predicate<RequirementDefinition>> predicates = new ArrayList<>();
84 .add(req -> req.getCapability().equals(ToscaCapabilityType.NATIVE_ATTACHMENT)
85 && req.getNode().equals(ToscaNodeType.NATIVE_BLOCK_STORAGE)
86 && req.getRelationship()
87 .equals(ToscaRelationshipType.NATIVE_ATTACHES_TO));
92 Optional<List<String>> getConnectorPropertyParamName(String heatResourceId, Resource heatResource,
93 HeatOrchestrationTemplate
94 nestedHeatOrchestrationTemplate,
95 String nestedHeatFileName) {
98 mdcDataDebugMessage.debugEntryMessage(null, null);
100 Optional<AttachedResourceId> volumeId = HeatToToscaUtil
101 .extractAttachedResourceId(nestedFileData.getFile(), nestedHeatOrchestrationTemplate,
102 translateTo.getContext(), heatResource.getProperties().get("volume_id"));
103 if (volumeId.isPresent() && volumeId.get().isGetParam()
104 && volumeId.get().getEntityId() instanceof String) {
105 mdcDataDebugMessage.debugExitMessage(null, null);
106 return Optional.of(Collections.singletonList((String) volumeId.get().getEntityId()));
108 mdcDataDebugMessage.debugExitMessage(null, null);
109 return Optional.empty();
114 String getDesiredResourceType() {
115 return HeatResourcesTypes.CINDER_VOLUME_ATTACHMENT_RESOURCE_TYPE.getHeatResource();
119 void addRequirementToConnectResources(
120 Map.Entry<String, RequirementDefinition> requirementDefinitionEntry,
121 List<String> paramNames) {
124 mdcDataDebugMessage.debugEntryMessage(null, null);
126 if (paramNames == null || paramNames.isEmpty()) {
130 List<String> supportedVolumeTypes =
131 Collections.singletonList(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
133 for (String paramName : paramNames) {
134 Object paramValue = translateTo.getResource().getProperties().get(paramName);
135 addRequirementToConnectResource(requirementDefinitionEntry, paramName, paramValue,
136 supportedVolumeTypes);
139 mdcDataDebugMessage.debugExitMessage(null, null);
143 boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
144 String nestedPropertyName,
145 String connectionPointId,
146 Resource connectedResource,
147 List<String> supportedTypes) {
150 mdcDataDebugMessage.debugEntryMessage(null, null);
152 if (!resourceTranslationBase.isResourceTypeSupported(connectedResource, supportedTypes)) {
153 logger.warn("Nested resource '" + nestedResourceId + "' property '" + nestedPropertyName
154 + "' is pointing to a resource with type '" + connectedResource.getType()
155 + "' which is not supported for requirement '" + connectionPointId
156 + "' that connect VolumeAttachment to Volume. Supported types are: '"
157 + supportedTypes.toString()
158 + "', therefore, this TOSCA requirement will not be connected.");
160 mdcDataDebugMessage.debugExitMessage(null, null);
164 mdcDataDebugMessage.debugExitMessage(null, null);
169 protected Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
170 String translatedResourceId, HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
173 mdcDataDebugMessage.debugEntryMessage(null, null);
175 List<Predicate<Map.Entry<String, Resource>>> predicates =
176 buildPredicates(nestedFileData.getFile(), nestedHeatOrchestrationTemplate,
177 translatedResourceId);
178 List<Map.Entry<String, Resource>> list =
179 nestedHeatOrchestrationTemplate.getResources().entrySet()
181 .filter(entry -> predicates
183 .allMatch(p -> p.test(entry)))
184 .collect(Collectors.toList());
185 if (CollectionUtils.isEmpty(list)) {
186 mdcDataDebugMessage.debugExitMessage(null, null);
187 return Optional.empty();
189 mdcDataDebugMessage.debugExitMessage(null, null);
190 return Optional.of(list);
195 Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
196 Map.Entry<String, RequirementDefinition> requirementDefinitionEntry, String paramName,
197 List<String> supportedTargetNodeTypes) {
200 mdcDataDebugMessage.debugEntryMessage(null, null);
202 Optional<String> targetTranslatedNodeId = super
203 .getConnectionTranslatedNodeUsingGetParamFunc(requirementDefinitionEntry, paramName,
204 supportedTargetNodeTypes);
205 if (targetTranslatedNodeId.isPresent()) {
206 return targetTranslatedNodeId;
208 Optional<AttachedResourceId> attachedResourceId =
209 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
210 if (!attachedResourceId.isPresent()) {
211 return Optional.empty();
213 AttachedResourceId resourceId = attachedResourceId.get();
214 if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
215 TranslatedHeatResource shareResource =
216 translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
217 if (Objects.isNull(shareResource)) {
218 List<FileData> allFilesData =
219 translateTo.getContext().getManifest().getContent().getData();
220 Optional<FileData> fileData =
221 HeatToToscaUtil.getFileData(translateTo.getHeatFileName(), allFilesData);
222 if (fileData.isPresent()) {
223 Optional<ResourceFileDataAndIDs> fileDataContainingResource =
224 new VolumeTranslationHelper(logger)
225 .getFileDataContainingVolume(fileData.get().getData(),
226 (String) resourceId.getEntityId(), translateTo, FileData.Type.HEAT_VOL);
227 if (fileDataContainingResource.isPresent()) {
228 mdcDataDebugMessage.debugExitMessage(null, null);
229 return Optional.of(fileDataContainingResource.get().getTranslatedResourceId());
235 mdcDataDebugMessage.debugExitMessage(null, null);
236 return Optional.empty();
240 private List<Predicate<Map.Entry<String, Resource>>> buildPredicates(
242 HeatOrchestrationTemplate heatOrchestrationTemplate,
243 String novaTranslatedResourceId) {
244 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
245 list.add(entry -> entry.getValue().getType().equals(getDesiredResourceType()));
247 Object instanceUuidProp = entry.getValue().getProperties().get("instance_uuid");
248 TranslationContext context = translateTo.getContext();
249 Optional<AttachedResourceId> instanceUuid = HeatToToscaUtil
250 .extractAttachedResourceId(fileName, heatOrchestrationTemplate, context,
252 if (instanceUuid.isPresent()) {
253 Optional<String> resourceTranslatedId =
254 ResourceTranslationBase.getResourceTranslatedId(fileName, heatOrchestrationTemplate,
255 (String) instanceUuid.get().getTranslatedId(), context);
256 return resourceTranslatedId.isPresent()
257 && resourceTranslatedId.get().equals(novaTranslatedResourceId);
260 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
261 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
262 LoggerErrorCode.DATA_ERROR.getErrorCode(),
263 LoggerErrorDescription.MISSING_MANDATORY_PROPERTY);
264 throw new CoreException(new MissingMandatoryPropertyErrorBuilder("instance_uuid").build());