diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index dfc65ec7..3fd9d83f 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -255,6 +255,7 @@ public class DelegationDao { throw new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DELEGATION_NOT_FOUND)); } + amazonS3Service.deleteDelegationfromS3(userCompanyDelegationEntity); userCompanyDelegationEntity.setStatus(UserCompanyDelegationStatusEnum.INACTIVE.getValue()); userCompanyDelegationRepository.save(userCompanyDelegationEntity); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java index 6f8e3243..1ccd9386 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java @@ -1,30 +1,29 @@ package net.gepafin.tendermanagement.dao; - -import java.util.stream.Collectors; - import lombok.extern.slf4j.Slf4j; -import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; - import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.CallEntity; import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.DocumentRepository; import net.gepafin.tendermanagement.service.AmazonS3Service; +import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CallService; +import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; - +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Slf4j @Component @@ -47,6 +46,14 @@ public class DocumentDao { @Autowired private ApplicationRepository applicationFormRepository; + + @Autowired + ApplicationService applicationService; + + @Value("${aws.s3.bucket.name}") + private String bucketName; + + // @Value("${aws.s3.url.folder}") // private String s3Folder; @@ -110,13 +117,22 @@ public class DocumentDao { public void deleteFile(Long documentId) { DocumentEntity documentEntity = validateDocument(documentId); -// String fileName= Utils.extractFileName(documentEntity.getFilePath()); -// deleteFileOnAmazonS3(fileName); + Long callId = null; + Long applicationId = null; + + if ("CALL".equalsIgnoreCase(documentEntity.getSource())) { + callId = documentEntity.getSourceId(); + } else if ("APPLICATION".equalsIgnoreCase(documentEntity.getSource())) { + applicationId = documentEntity.getSourceId(); + ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); + callId = applicationEntity.getCall().getId(); + } + + amazonS3Service.deleteFileFromS3(documentEntity,callId,applicationId); documentEntity.setIsDeleted(true); documentRepository.save(documentEntity); } - public DocumentEntity validateDocument(Long id) { return documentRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.DOCUMENT_NOT_FOUND))); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java index 751dfa92..998c7d13 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java @@ -3,7 +3,10 @@ package net.gepafin.tendermanagement.enums; public enum DocOtherSourceTypeEnum { USER_SIGNED_DOCUMENT("USER_SIGNED_DOCUMENT"), USER_DELEGATION("USER_DELEGATION"), - TEMPLATE("TEMPLATE"); + TEMPLATE("TEMPLATE"), + DELETED_USER_DELEGATION("DELETED_USER_DELEGATION"), + DELETED_APPLICATION("DELETED_APPLICATION"), + DELETED_CALL("DELETED_CALL"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java index 6cc27000..92cbdfab 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AmazonS3Service.java @@ -1,5 +1,8 @@ package net.gepafin.tendermanagement.service; +import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @@ -9,12 +12,23 @@ import java.io.IOException; import java.io.InputStream; @Component -public interface AmazonS3Service { +public interface +AmazonS3Service { UploadFileOnAmazonS3Response uploadFileOnAmazonS3(String s3Folder, MultipartFile file); Boolean delete(String s3Folder, String filePath); InputStream getFile(String s3Folder, String filePath) throws IOException; - + + String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId); + + String generateS3PathForDeletedDocumentForOther(); + + void moveFile(String bucketName, String oldPath, String newPath); + + void deleteDelegationfromS3(UserCompanyDelegationEntity userCompanyDelegationEntity); + + void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId); + } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 56141be2..5e7624ac 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -1,10 +1,17 @@ package net.gepafin.tendermanagement.service.impl; +import com.amazonaws.AmazonServiceException; +import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.*; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; +import net.gepafin.tendermanagement.dao.S3PathConfig; +import net.gepafin.tendermanagement.entities.DocumentEntity; +import net.gepafin.tendermanagement.entities.UserCompanyDelegationEntity; +import net.gepafin.tendermanagement.enums.DocOtherSourceTypeEnum; import net.gepafin.tendermanagement.model.response.UploadFileOnAmazonS3Response; import net.gepafin.tendermanagement.service.AmazonS3Service; import net.gepafin.tendermanagement.util.Utils; @@ -45,6 +52,18 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { @Value("${aws.s3.url}") private String s3Url; + @Autowired + private S3PathConfig s3ConfigBean; + + @Autowired + private AmazonS3Client s3Client; + + @Value("${aws.s3.region}") + private String region; + + private String getBucketUrlPrefix() { + return "https://" + bucketName + ".s3." + region + ".amazonaws.com/"; + } private String upload(String fileName, String s3Folder, MultipartFile file) throws IOException { @@ -125,4 +144,86 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { Translator.toLocale(GepafinConstant.UPLOAD_ERROR_S3)); } } + + @Override + public String generateS3PathForDeletedDocument(DocOtherSourceTypeEnum typeOfDocument, Long callId, Long applicationId) { + try { + return s3ConfigBean.generateDocumentPathForOther(typeOfDocument, callId, applicationId); + } catch (IllegalArgumentException e) { + throw new CustomValidationException( + Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG) + ); + } + } + + @Override + public String generateS3PathForDeletedDocumentForOther() { + try { + return s3ConfigBean.generateDocumentPathForDelegationAndSignedDocument(DocOtherSourceTypeEnum.DELETED_USER_DELEGATION); + } catch (IllegalArgumentException e) { + throw new CustomValidationException( + Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.S3_PATH_GENERATION_ERROR_MSG) + ); + } + } + + @Override + public void moveFile(String bucketName, String oldPath, String newPath) { + try { + log.info("Moving file from {} to {} in bucket {}", oldPath, newPath, bucketName); + + CopyObjectRequest copyRequest = new CopyObjectRequest(bucketName, oldPath, bucketName, newPath); + s3Client.copyObject(copyRequest); + log.info("File copied successfully from {} to {}", oldPath, newPath); + + s3Client.deleteObject(bucketName, oldPath); + log.info("Original file deleted successfully: {}", oldPath); + } catch (AmazonServiceException e) { + log.error("AWS service error while moving file: {}", e.getErrorMessage(), e); + throw e; + } catch (SdkClientException e) { + log.error("SDK client error while moving file: {}", e.getMessage(), e); + throw e; + } catch (Exception e) { + log.error("Unexpected error while moving file: {}", e.getMessage(), e); + throw e; + } + } + + @Override + public void deleteDelegationfromS3(UserCompanyDelegationEntity userCompanyDelegationEntity) { + String oldS3Path = userCompanyDelegationEntity.getFilePath(); + String newS3Path = generateS3PathForDeletedDocumentForOther() + + "/" + oldS3Path.substring(oldS3Path.lastIndexOf("/") + 1); + + String bucketUrlPrefix = getBucketUrlPrefix(); + if (oldS3Path.startsWith(bucketUrlPrefix)) { + oldS3Path = oldS3Path.replace(bucketUrlPrefix, ""); + } + moveFile(bucketName, oldS3Path, newS3Path); + log.info("File for company ID {} successfully moved to deleted folder.", userCompanyDelegationEntity.getId()); + } + + @Override + public void deleteFileFromS3(DocumentEntity documentEntity, Long callId, Long applicationId) { + try { + String oldS3Path = documentEntity.getFilePath(); + String newS3Path = generateS3PathForDeletedDocument(DocOtherSourceTypeEnum.valueOf("DELETED_" + documentEntity.getSource().toUpperCase()), callId, applicationId) + + "/" + oldS3Path.substring(oldS3Path.lastIndexOf("/") + 1); + String bucketUrlPrefix = getBucketUrlPrefix(); + if (oldS3Path.startsWith(bucketUrlPrefix)) { + oldS3Path = oldS3Path.replace(bucketUrlPrefix, ""); + } + + moveFile(bucketName, oldS3Path, newS3Path); + log.info("File for document ID {} successfully moved to deleted folder.", documentEntity.getId()); + } catch (Exception e) { + log.error("Error moving file for document ID {} to deleted folder: {}", documentEntity.getId(), e.getMessage()); + throw new CustomValidationException(Status.VALIDATION_ERROR, "Error occurred while moving file to deleted folder."); + } + } + + } \ No newline at end of file