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.vendorsoftwareproduct.impl;
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.apache.commons.collections4.MapUtils;
25 import org.openecomp.core.model.dao.ServiceModelDao;
26 import org.openecomp.core.model.types.ServiceElement;
27 import org.openecomp.core.utilities.file.FileContentHandler;
28 import org.openecomp.core.utilities.file.FileUtils;
29 import org.openecomp.core.utilities.json.JsonUtil;
30 import org.openecomp.sdc.activityLog.ActivityLogManager;
31 import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity;
32 import org.openecomp.sdc.common.errors.CoreException;
33 import org.openecomp.sdc.common.errors.Messages;
34 import org.openecomp.sdc.common.utils.CommonUtil;
35 import org.openecomp.sdc.common.utils.SdcCommon;
36 import org.openecomp.sdc.datatypes.error.ErrorLevel;
37 import org.openecomp.sdc.datatypes.error.ErrorMessage;
38 import org.openecomp.sdc.healing.api.HealingManager;
39 import org.openecomp.sdc.healing.types.HealCode;
40 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
41 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
42 import org.openecomp.sdc.heat.services.tree.HeatTreeManager;
43 import org.openecomp.sdc.heat.services.tree.HeatTreeManagerUtil;
44 import org.openecomp.sdc.logging.api.Logger;
45 import org.openecomp.sdc.logging.api.LoggerFactory;
46 import org.openecomp.sdc.logging.api.annotations.Metrics;
47 import org.openecomp.sdc.logging.context.impl.MdcDataDebugMessage;
48 import org.openecomp.sdc.logging.types.LoggerServiceName;
49 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
50 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
51 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
52 import org.openecomp.sdc.validation.util.ValidationManagerUtil;
53 import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager;
54 import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateDao;
55 import org.openecomp.sdc.vendorsoftwareproduct.dao.VendorSoftwareProductDao;
56 import org.openecomp.sdc.vendorsoftwareproduct.dao.VendorSoftwareProductInfoDao;
57 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateCandidateData;
58 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.UploadData;
59 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
60 import org.openecomp.sdc.vendorsoftwareproduct.errors.OrchestrationTemplateNotFoundErrorBuilder;
61 import org.openecomp.sdc.vendorsoftwareproduct.services.composition.CompositionDataExtractor;
62 import org.openecomp.sdc.vendorsoftwareproduct.services.composition.CompositionEntityDataManager;
63 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.CandidateService;
64 import org.openecomp.sdc.vendorsoftwareproduct.services.utils.CandidateEntityBuilder;
65 import org.openecomp.sdc.vendorsoftwareproduct.types.OrchestrationTemplateActionResponse;
66 import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse;
67 import org.openecomp.sdc.vendorsoftwareproduct.types.ValidationResponse;
68 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.FilesDataStructure;
69 import org.openecomp.sdc.vendorsoftwareproduct.utils.VendorSoftwareProductUtils;
70 import org.openecomp.sdc.versioning.dao.types.Version;
71 import org.openecomp.sdcrests.activitylog.types.ActivityType;
73 import java.io.ByteArrayInputStream;
74 import java.io.IOException;
75 import java.io.InputStream;
76 import java.nio.ByteBuffer;
77 import java.util.HashMap;
78 import java.util.List;
80 import java.util.Optional;
82 public class OrchestrationTemplateCandidateManagerImpl
83 implements OrchestrationTemplateCandidateManager {
84 private static MdcDataDebugMessage mdcDataDebugMessage = new MdcDataDebugMessage();
85 private static final Logger logger =
86 LoggerFactory.getLogger(OrchestrationTemplateCandidateManagerImpl.class);
88 private VendorSoftwareProductDao vendorSoftwareProductDao;
89 private VendorSoftwareProductInfoDao vspInfoDao;
90 private OrchestrationTemplateDao orchestrationTemplateDataDao;
91 private CandidateService candidateService;
92 private HealingManager healingManager;
93 private CompositionDataExtractor compositionDataExtractor;
94 private ServiceModelDao<ToscaServiceModel, ServiceElement> serviceModelDao;
95 private CompositionEntityDataManager compositionEntityDataManager;
96 private ActivityLogManager activityLogManager;
98 public OrchestrationTemplateCandidateManagerImpl(
99 VendorSoftwareProductDao vendorSoftwareProductDao, VendorSoftwareProductInfoDao
101 OrchestrationTemplateDao orchestrationTemplateDataDao,
102 CandidateService candidateService, HealingManager healingManager,
103 CompositionDataExtractor compositionDataExtractor,
104 ServiceModelDao<ToscaServiceModel, ServiceElement> serviceModelDao,
105 CompositionEntityDataManager compositionEntityDataManager,
106 ActivityLogManager activityLogManager) {
107 this.vendorSoftwareProductDao = vendorSoftwareProductDao;
108 this.vspInfoDao = vspInfoDao;
109 this.orchestrationTemplateDataDao = orchestrationTemplateDataDao;
110 this.candidateService = candidateService;
111 this.healingManager = healingManager;
112 this.compositionDataExtractor = compositionDataExtractor;
113 this.serviceModelDao = serviceModelDao;
114 this.compositionEntityDataManager = compositionEntityDataManager;
115 this.activityLogManager = activityLogManager;
120 public UploadFileResponse upload(String vspId, Version version, InputStream heatFileToUpload,
122 mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
124 VspDetails vspDetails = getVspDetails(vspId, version);
126 UploadFileResponse uploadFileResponse = new UploadFileResponse();
127 if (isNotEmptyFileToUpload(heatFileToUpload, uploadFileResponse)) {
128 return uploadFileResponse;
131 byte[] uploadedFileData = FileUtils.toByteArray(heatFileToUpload);
132 if (isInvalidRawZipData(uploadFileResponse, uploadedFileData)) {
133 return uploadFileResponse;
136 Optional<FileContentHandler> optionalContentMap =
137 getZipContentMap(uploadFileResponse, uploadedFileData);
138 if (!optionalContentMap.isPresent()) {
139 logger.error(Messages.ZIP_CONTENT_MAP.getErrorMessage());
142 SdcCommon.UPLOAD_FILE,
143 new ErrorMessage(ErrorLevel.ERROR, Messages.ZIP_CONTENT_MAP.getErrorMessage()));
145 mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
146 return uploadFileResponse;
149 if (!MapUtils.isEmpty(uploadFileResponse.getErrors())) {
151 mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
152 return uploadFileResponse;
155 OrchestrationTemplateCandidateData candidateData =
156 new CandidateEntityBuilder(candidateService)
157 .buildCandidateEntityFromZip(vspDetails, uploadedFileData, optionalContentMap.get(),
158 uploadFileResponse.getErrors(), user);
159 candidateService.updateCandidateUploadData(candidateData, vspDetails.getId());
160 } catch (Exception exception) {
161 logger.error(Messages.ZIP_CONTENT_MAP.getErrorMessage());
164 SdcCommon.UPLOAD_FILE,
165 new ErrorMessage(ErrorLevel.ERROR, exception.getMessage()));
167 mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
168 return uploadFileResponse;
171 mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
172 return uploadFileResponse;
176 public OrchestrationTemplateActionResponse process(String vspId,
177 Version version, String user) {
178 mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
180 Optional<OrchestrationTemplateCandidateData> candidate =
181 fetchCandidateDataEntity(vspId, version);
182 if (!candidate.isPresent()) {
183 throw new CoreException(new OrchestrationTemplateNotFoundErrorBuilder(vspId).build());
186 OrchestrationTemplateActionResponse response = new OrchestrationTemplateActionResponse();
187 UploadFileResponse uploadFileResponse = new UploadFileResponse();
188 OrchestrationTemplateCandidateData candidateDataEntity = candidate.get();
189 Optional<FileContentHandler> fileContent =
190 getZipContentMap(uploadFileResponse, candidateDataEntity.getContentData().array());
191 if (!fileContent.isPresent()) {
192 response.addStructureErrors(uploadFileResponse.getErrors());
193 mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
197 Map<String, List<ErrorMessage>> uploadErrors = uploadFileResponse.getErrors();
198 FileContentHandler fileContentMap = fileContent.get();
199 FilesDataStructure structure =
200 JsonUtil.json2Object(candidateDataEntity.getFilesDataStructure(), FilesDataStructure.class);
202 if (CollectionUtils.isNotEmpty(structure.getUnassigned())) {
203 response.addErrorMessageToMap(SdcCommon.UPLOAD_FILE,
204 Messages.FOUND_UNASSIGNED_FILES.getErrorMessage(), ErrorLevel.ERROR);
206 mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
210 VspDetails vspDetails =
211 getVspDetails(vspId, version);
213 String manifest = candidateService.createManifest(vspDetails, structure);
214 fileContentMap.addFile(SdcCommon.MANIFEST_NAME, manifest.getBytes());
216 HeatStructureTree tree = createAndValidateHeatTree(response, fileContentMap);
218 Optional<ByteArrayInputStream> zipByteArrayInputStream = candidateService
219 .fetchZipFileByteArrayInputStream(vspId, candidateDataEntity, manifest, uploadErrors);
220 if (!zipByteArrayInputStream.isPresent()) {
223 deleteUploadDataAndContent(vspId, version);
224 saveHotData(vspId, version, zipByteArrayInputStream.get(), fileContentMap, tree);
226 ToscaServiceModel toscaServiceModel =
227 HeatToToscaUtil.loadAndTranslateTemplateData(fileContentMap)
228 .getToscaServiceModel();
229 if (toscaServiceModel != null) {
230 serviceModelDao.storeServiceModel(vspId, version, toscaServiceModel);
231 compositionEntityDataManager.saveCompositionData(vspId, version,
232 compositionDataExtractor.extractServiceCompositionData(toscaServiceModel));
234 uploadFileResponse.addStructureErrors(uploadErrors);
236 ActivityLogEntity activityLogEntity = new ActivityLogEntity(vspId, String.valueOf(version.getMajor()+1),
237 ActivityType.UPLOAD_HEAT.toString(), user, true, "", "");
238 activityLogManager.addActionLog(activityLogEntity, user);
240 mdcDataDebugMessage.debugExitMessage("VSP id", vspId);
246 public Optional<FilesDataStructure> getFilesDataStructure(
247 String vspId, Version version, String user) {
248 mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
250 Optional<FilesDataStructure> candidateFileDataStructure =
251 candidateService.getOrchestrationTemplateCandidateFileDataStructure(vspId, version);
252 if (candidateFileDataStructure.isPresent()) {
253 return candidateFileDataStructure;
255 Map<String, Object> healingParams = getHealingParamsAsMap(vspId, version, user);
258 .debugExitMessage("VSP id", vspId);
259 return (Optional<FilesDataStructure>) healingManager
260 .heal(HealCode.FILE_DATA_STRUCTURE_HEALER, healingParams);
266 public ValidationResponse updateFilesDataStructure(String vspId,
267 Version version, String user,
268 FilesDataStructure fileDataStructure) {
269 mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
271 ValidationResponse response = new ValidationResponse();
272 Optional<List<ErrorMessage>> validateErrors =
273 candidateService.validateFileDataStructure(fileDataStructure);
274 if (validateErrors.isPresent()) {
275 List<ErrorMessage> errorMessages = validateErrors.get();
276 if (CollectionUtils.isNotEmpty(errorMessages)) {
277 Map<String, List<ErrorMessage>> errorsMap = new HashMap<>();
278 errorsMap.put(SdcCommon.UPLOAD_FILE, errorMessages);
279 response.setUploadDataErrors(errorsMap, LoggerServiceName.Update_Manifest,
280 LoggerTragetServiceName.VALIDATE_FILE_DATA_STRUCTURE);
283 .debugExitMessage("VSP id", vspId);
287 candidateService.updateOrchestrationTemplateCandidateFileDataStructure(vspId, version,
291 .debugExitMessage("VSP id", vspId);
297 public Optional<byte[]> get(String vspId, Version version, String user)
299 mdcDataDebugMessage.debugEntryMessage("VSP id", vspId);
301 VspDetails vspDetails =
302 getVspDetails(vspId, version);
304 Optional<OrchestrationTemplateCandidateData> candidateDataEntity =
305 fetchCandidateDataEntity(vspId, version);
307 if (!candidateDataEntity.isPresent()) {
308 ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR,
309 Messages.NO_ZIP_FILE_WAS_UPLOADED_OR_ZIP_NOT_EXIST.getErrorMessage());
310 logger.error(errorMessage.getMessage());
313 .debugExitMessage("VSP id", vspId);
314 return Optional.empty();
317 FilesDataStructure structure = JsonUtil
318 .json2Object(candidateDataEntity.get().getFilesDataStructure(), FilesDataStructure.class);
319 String manifest = candidateService.createManifest(vspDetails, structure);
322 .debugExitMessage("VSP id", vspId);
323 return Optional.ofNullable(candidateService
324 .replaceManifestInZip(candidateDataEntity.get().getContentData(), manifest, vspId));
327 private Optional<OrchestrationTemplateCandidateData> fetchCandidateDataEntity(
328 String vspId, Version version) {
330 .ofNullable(candidateService.getOrchestrationTemplateCandidate(vspId, version));
333 private HeatStructureTree createAndValidateHeatTree(OrchestrationTemplateActionResponse response,
334 FileContentHandler fileContentMap) {
335 VendorSoftwareProductUtils.addFileNamesToUploadFileResponse(fileContentMap, response);
336 Map<String, List<ErrorMessage>> validationErrors =
337 ValidationManagerUtil.initValidationManager(fileContentMap).validate();
338 response.getErrors().putAll(validationErrors);
340 HeatTreeManager heatTreeManager = HeatTreeManagerUtil.initHeatTreeManager(fileContentMap);
341 heatTreeManager.createTree();
342 heatTreeManager.addErrors(validationErrors);
343 return heatTreeManager.getTree();
346 private void saveHotData(String vspId, Version activeVersion, InputStream uploadedFileData,
347 FileContentHandler fileContentMap, HeatStructureTree tree) {
348 Map<String, Object> manifestAsMap =
349 (Map<String, Object>) JsonUtil.json2Object(fileContentMap.getFileContent(
350 SdcCommon.MANIFEST_NAME), Map.class);
352 UploadData uploadData = new UploadData();
353 uploadData.setPackageName((String) manifestAsMap.get("name"));
354 uploadData.setPackageVersion((String) manifestAsMap.get("version"));
355 uploadData.setContentData(ByteBuffer.wrap(FileUtils.toByteArray(uploadedFileData)));
356 uploadData.setValidationDataStructure(new ValidationStructureList(tree));
357 orchestrationTemplateDataDao.updateOrchestrationTemplateData(vspId, uploadData);
360 private void deleteUploadDataAndContent(String vspId, Version version) {
361 //fixme change this when more tables are zusammenized
362 vendorSoftwareProductDao.deleteUploadData(vspId, version);
365 private boolean isInvalidRawZipData(UploadFileResponse uploadFileResponse,
366 byte[] uploadedFileData) {
367 Optional<ErrorMessage> errorMessage;
368 errorMessage = candidateService.validateRawZipData(uploadedFileData);
369 if (errorMessage.isPresent()) {
370 uploadFileResponse.addStructureError(SdcCommon.UPLOAD_FILE, errorMessage.get());
376 private boolean isNotEmptyFileToUpload(InputStream heatFileToUpload,
377 UploadFileResponse uploadFileResponse) {
378 Optional<ErrorMessage> errorMessage =
379 candidateService.validateNonEmptyFileToUpload(heatFileToUpload);
380 if (errorMessage.isPresent()) {
381 uploadFileResponse.addStructureError(SdcCommon.UPLOAD_FILE, errorMessage.get());
387 private Optional<FileContentHandler> getZipContentMap(UploadFileResponse uploadFileResponse,
388 byte[] uploadedFileData) {
389 FileContentHandler contentMap = null;
391 contentMap = CommonUtil.loadUploadFileContent(uploadedFileData);
392 } catch (IOException exception) {
393 uploadFileResponse.addStructureError(
394 SdcCommon.UPLOAD_FILE,
395 new ErrorMessage(ErrorLevel.ERROR, Messages.INVALID_ZIP_FILE.getErrorMessage()));
396 } catch (CoreException coreException) {
397 uploadFileResponse.addStructureError(
398 SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, coreException.getMessage()));
400 return Optional.ofNullable(contentMap);
403 // todo *************************** move to reusable place! *************************
405 private Map<String, Object> getHealingParamsAsMap(String vspId, Version version, String user) {
406 Map<String, Object> healingParams = new HashMap<>();
408 healingParams.put(SdcCommon.VSP_ID, vspId);
409 healingParams.put(SdcCommon.VERSION, version);
410 healingParams.put(SdcCommon.USER, user);
412 return healingParams;
415 public VspDetails getVspDetails(String vspId, Version version) {
416 VspDetails vspDetails = vspInfoDao.get(new VspDetails(vspId, version));
417 vspDetails.setValidationData(orchestrationTemplateDataDao.getValidationData(vspId, version));