Files
bflows-bandi-be/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java
2024-10-25 15:29:28 +05:30

198 lines
7.6 KiB
Java

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.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import lombok.extern.slf4j.Slf4j;
import net.gepafin.tendermanagement.dao.S3PathConfig;
import net.gepafin.tendermanagement.entities.DocumentEntity;
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
import net.gepafin.tendermanagement.repositories.ApplicationRepository;
import net.gepafin.tendermanagement.repositories.ApplicationSignedDocumentRepository;
import net.gepafin.tendermanagement.repositories.DocumentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Slf4j
@Service
public class S3ReUploadMigrationService {
private static final String OLD_BUCKET = "mementoresources";
private static final String SECURE_KEY = "267163962963";
@Autowired
private DocumentRepository documentRepository;
@Autowired
private AmazonS3Client s3Client;
@Autowired
private S3PathConfig s3ConfigBean;
@Autowired
private ApplicationRepository applicationRepository;
@Autowired
private ApplicationSignedDocumentRepository applicationSignedDocumentRepository;
@Autowired
private AmazonS3 amazonS3;
@Value("${aws.s3.url}")
private String s3Url;
private boolean migrationCompleted = false;
public String reUploadAndMigrateDocuments(String providedKey) {
if (migrationCompleted) {
return "Migration already completed.";
}
// Validate the provided key
if (!isValidKey(providedKey)) {
return "Invalid or missing migration key.";
}
List<DocumentEntity> documents = documentRepository.findAllByIsDeleteFalse();
if (documents.isEmpty()) {
return "No documents found to migrate.";
}
for (DocumentEntity document : documents) {
String oldUrl = document.getFilePath(); // This should contain the full URL
log.info("Processing {}", oldUrl);
try {
File localFile = downloadFileFromS3(oldUrl);
String newKey = generateNewS3Path(document); // Make sure this generates the correct new path
String uploadedPath = uploadFileToNewBucket(localFile, newKey);
updateDocumentPathAndDeleteOldEntry(document, uploadedPath);
} catch (Exception e) {
log.error("Error processing document {}: {}", document.getId(), e.getMessage());
}
}
return "Migrated Successfully.";
}
private boolean isValidKey(String providedKey) {
return providedKey != null && providedKey.equals(SECURE_KEY);
}
private File downloadFileFromS3(String fileUrl) throws Exception {
String key = extractS3KeyFromUrl(fileUrl); // Get the S3 key from the URL
File localFile = new File("/tmp/" + extractFileName(key)); // Save file locally
GetObjectRequest getObjectRequest = new GetObjectRequest(OLD_BUCKET, key); // Use the key
try (InputStream s3Stream = s3Client.getObject(getObjectRequest).getObjectContent(); FileOutputStream outputStream = new FileOutputStream(localFile)) {
s3Stream.transferTo(outputStream);
}
log.info("Downloaded file from old S3 bucket: {}", key);
return localFile;
}
private String extractS3KeyFromUrl(String url) {
// Assuming the URL structure is consistent
return url.replace("https://mementoresources.s3.eu-west-1.amazonaws.com/", "");
}
private String uploadFileToNewBucket(File localFile, String s3Folder) {
InputStream inputStream = null; // Declare the InputStream here for cleanup
try {
// Extract file name from the local file
String fileName = extractFileName(localFile.getAbsolutePath()); // Get the file name
String path = s3Folder + "/" + fileName; // Construct the S3 path
// Create InputStream from the local file
inputStream = new FileInputStream(localFile);
// Set up object metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType("application/octet-stream");
objectMetadata.setContentLength(localFile.length());
// Upload to S3
s3Client.putObject(OLD_BUCKET, path, inputStream, objectMetadata);
// Construct the full S3 URL
String fullUrl = String.format("https://%s.s3.%s.amazonaws.com/%s", OLD_BUCKET, "eu-west-1", path);
log.info("File '{}' uploaded successfully to Amazon S3 with URL: {}", fileName, fullUrl);
return fullUrl;
} catch (IOException e) {
log.error("IOException occurred during file upload for '{}': {}", localFile.getName(), e.getMessage());
throw new RuntimeException("Upload failed for: " + s3Folder + "/" + localFile.getName(), e);
} catch (AmazonServiceException e) {
log.error("Amazon service exception while uploading file '{}': {}", localFile.getName(), e.getMessage());
throw new RuntimeException("Upload failed for: " + s3Folder + "/" + localFile.getName(), e);
} catch (SdkClientException e) {
log.error("SDK client exception while uploading file '{}': {}", localFile.getName(), e.getMessage());
throw new RuntimeException("Upload failed for: " + s3Folder + "/" + localFile.getName(), e);
} finally {
// Close InputStream if it was opened
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.warn("Failed to close InputStream for file '{}': {}", localFile.getName(), e.getMessage());
}
}
}
}
private String generateNewS3Path(DocumentEntity document) {
DocumentSourceTypeEnum sourceType = DocumentSourceTypeEnum.valueOf(document.getSource());
Long callId;
if (sourceType.equals(DocumentSourceTypeEnum.CALL)) {
return s3ConfigBean.generateDocumentPath(sourceType, document.getSourceId(), 0L);
} else {
callId = applicationRepository.findCallIdById(document.getSourceId());
return s3ConfigBean.generateDocumentPath(sourceType, callId, document.getSourceId());
}
}
private String extractFileName(String filePath) {
String[] parts = filePath.split("/");
return parts[parts.length - 1];
}
private void updateDocumentPathAndDeleteOldEntry(DocumentEntity document, String newPath) {
String fileName = extractFileName(newPath);
DocumentEntity newDocument = new DocumentEntity();
newDocument.setFilePath(newPath);
newDocument.setSource(document.getSource());
newDocument.setType(document.getType());
newDocument.setIsDeleted(false);
newDocument.setSourceId(document.getSourceId());
newDocument.setFileName(fileName);
documentRepository.save(newDocument);
documentRepository.delete(document);
log.info("Migrated document ID: {} to new path: {}", document.getId(), newPath);
}
}