package ru.soune.nocopy.migration; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.service.file.cloud.CloudStorageService; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.List; @Component @Slf4j @RequiredArgsConstructor public class S3MigrationTool { private final FileEntityRepository fileEntityRepository; private final CloudStorageService cloudStorageService; private static final Path FAILED_LOG = Paths.get("migration_failed.txt"); public void migrationFilesToS3() { log.info("=== START MIGRATION ==="); clearLogFile(); List allFiles = fileEntityRepository.findAll(); log.info("Total files: {}", allFiles.size()); int success = 0; List failedIds = new ArrayList<>(); for (FileEntity file : allFiles) { if (migrateFile(file)) { success++; } else { failedIds.add(file.getId()); } } log.info("=== COMPLETED: success {}, failed {} ===", success, failedIds.size()); if (!failedIds.isEmpty()) { log.info("Failed file IDs: {}", String.join(", ", failedIds)); log.info("Details saved to: {}", FAILED_LOG.toAbsolutePath()); } } private boolean migrateFile(FileEntity file) { StringBuilder errors = new StringBuilder(); try { cloudStorageService.saveFilesToStorage( file.getMimeType(), file.getFileExtension(), file.getFilePath() ); } catch (Exception e) { errors.append("main:").append(e.getMessage()).append("; "); } if ("image".equals(file.getMimeType())) { try { cloudStorageService.saveFilesToStorage( file.getMimeType(), file.getFileExtension(), file.getMediumPath() ); } catch (Exception e) { errors.append("medium:").append(e.getMessage()).append("; "); } try { cloudStorageService.saveFilesToStorage( file.getMimeType(), file.getFileExtension(), file.getThumbnailPath() ); } catch (Exception e) { errors.append("thumb:").append(e.getMessage()).append("; "); } } if (file.getProtectedFilePath() != null) { try { cloudStorageService.saveFilesToStorage( file.getMimeType() != null ? file.getMimeType() : "application", file.getFileExtension(), file.getProtectedFilePath() ); } catch (Exception e) { errors.append("protected:").append(e.getMessage()).append("; "); } } if (errors.length() > 0) { writeToFile(String.format("%s | %s | %s", file.getId(), file.getOriginalFileName(), errors)); log.warn("Failed to migrate: {} | {}", file.getId(), file.getOriginalFileName()); return false; } return true; } private void clearLogFile() { try { Files.deleteIfExists(FAILED_LOG); } catch (IOException e) { log.warn("Failed to clear log file"); } } private void writeToFile(String line) { try { Files.write(FAILED_LOG, (line + "\n").getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND); } catch (IOException e) { log.error("Failed to write to log file", e); } } }