From dfaebf81b8af7dd2310b8c12dcbafc2c65b06120 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 21 Sep 2025 16:58:01 +0500 Subject: [PATCH] report generation minio --- pom.xml | 7 ++ .../parser/controller/ReportController.java | 15 ++- .../konturai/parser/service/MinIOService.java | 93 +++++++++++++++++++ .../service/ReportGenerationService.java | 15 ++- src/main/resources/application.properties | 7 +- 5 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 src/main/java/kz/konturai/parser/service/MinIOService.java diff --git a/pom.xml b/pom.xml index 80857b1..7d61472 100644 --- a/pom.xml +++ b/pom.xml @@ -100,6 +100,13 @@ jfreechart 1.5.4 + + + + io.minio + minio + 8.5.7 + diff --git a/src/main/java/kz/konturai/parser/controller/ReportController.java b/src/main/java/kz/konturai/parser/controller/ReportController.java index f62b1c5..e6438ca 100644 --- a/src/main/java/kz/konturai/parser/controller/ReportController.java +++ b/src/main/java/kz/konturai/parser/controller/ReportController.java @@ -5,6 +5,7 @@ import kz.konturai.parser.model.ReportHistory; import kz.konturai.parser.repository.ReportHistoryRepository; import kz.konturai.parser.service.ReportGenerationService; import kz.konturai.parser.service.ReportGenerationService.ReportBinary; +import kz.konturai.parser.service.MinIOService; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -15,8 +16,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Optional; @RestController @@ -25,11 +24,14 @@ public class ReportController { private final ReportGenerationService reportGenerationService; private final ReportHistoryRepository reportHistoryRepository; + private final MinIOService minIOService; public ReportController(ReportGenerationService reportGenerationService, - ReportHistoryRepository reportHistoryRepository) { + ReportHistoryRepository reportHistoryRepository, + MinIOService minIOService) { this.reportGenerationService = reportGenerationService; this.reportHistoryRepository = reportHistoryRepository; + this.minIOService = minIOService; } @PostMapping("/generate") @@ -61,9 +63,12 @@ public class ReportController { return ResponseEntity.notFound().build(); } ReportHistory rh = opt.get(); - Path path = Path.of(rh.getFilePath()); try { - byte[] bytes = Files.readAllBytes(path); + // Download from MinIO + java.io.InputStream inputStream = minIOService.downloadFile(rh.getFilePath()); + byte[] bytes = inputStream.readAllBytes(); + inputStream.close(); + MediaType mt = rh.getFormat() != null && rh.getFormat().equalsIgnoreCase("DOCX") ? MediaType .parseMediaType("application/vnd.openxmlformats-officedocument.wordprocessingml.document") diff --git a/src/main/java/kz/konturai/parser/service/MinIOService.java b/src/main/java/kz/konturai/parser/service/MinIOService.java new file mode 100644 index 0000000..761aee7 --- /dev/null +++ b/src/main/java/kz/konturai/parser/service/MinIOService.java @@ -0,0 +1,93 @@ +package kz.konturai.parser.service; + +import io.minio.BucketExistsArgs; +import io.minio.GetObjectArgs; +import io.minio.MakeBucketArgs; +import io.minio.MinioClient; +import io.minio.PutObjectArgs; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +@Service +public class MinIOService { + + private static final Logger logger = LoggerFactory.getLogger(MinIOService.class); + + private final MinioClient minioClient; + private final String bucketName; + + public MinIOService(@Value("${minio.endpoint}") String endpoint, + @Value("${minio.access-key}") String accessKey, + @Value("${minio.secret-key}") String secretKey, + @Value("${minio.bucket-name}") String bucketName) { + this.minioClient = MinioClient.builder() + .endpoint(endpoint) + .credentials(accessKey, secretKey) + .build(); + this.bucketName = bucketName; + initializeBucket(); + } + + private void initializeBucket() { + try { + boolean exists = minioClient.bucketExists(BucketExistsArgs.builder() + .bucket(bucketName) + .build()); + + if (!exists) { + minioClient.makeBucket(MakeBucketArgs.builder() + .bucket(bucketName) + .build()); + logger.info("Created MinIO bucket: {}", bucketName); + } else { + logger.info("MinIO bucket already exists: {}", bucketName); + } + } catch (Exception e) { + logger.error("Failed to initialize MinIO bucket: {}", e.getMessage()); + } + } + + public void uploadFile(String objectName, byte[] data, String contentType) { + try { + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .stream(new ByteArrayInputStream(data), data.length, -1) + .contentType(contentType) + .build()); + logger.info("Successfully uploaded file to MinIO: {}", objectName); + } catch (Exception e) { + logger.error("Failed to upload file to MinIO: {}", e.getMessage()); + throw new RuntimeException("Failed to upload file to MinIO", e); + } + } + + public InputStream downloadFile(String objectName) { + try { + return minioClient.getObject(GetObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build()); + } catch (Exception e) { + logger.error("Failed to download file from MinIO: {}", e.getMessage()); + throw new RuntimeException("Failed to download file from MinIO", e); + } + } + + public boolean fileExists(String objectName) { + try { + minioClient.getObject(GetObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build()); + return true; + } catch (Exception e) { + return false; + } + } +} diff --git a/src/main/java/kz/konturai/parser/service/ReportGenerationService.java b/src/main/java/kz/konturai/parser/service/ReportGenerationService.java index 404650f..bc97385 100644 --- a/src/main/java/kz/konturai/parser/service/ReportGenerationService.java +++ b/src/main/java/kz/konturai/parser/service/ReportGenerationService.java @@ -5,7 +5,6 @@ import kz.konturai.parser.model.MarketItem; import kz.konturai.parser.repository.MarketItemRepository; import kz.konturai.parser.model.ReportHistory; import kz.konturai.parser.repository.ReportHistoryRepository; -import org.springframework.beans.factory.annotation.Value; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.encoders.EncoderUtil; @@ -59,16 +58,16 @@ public class ReportGenerationService { private final MarketItemRepository marketItemRepository; private final OllamaAnalyticsService ollamaAnalyticsService; private final ReportHistoryRepository reportHistoryRepository; - private final String storagePath; + private final MinIOService minIOService; public ReportGenerationService(MarketItemRepository marketItemRepository, OllamaAnalyticsService ollamaAnalyticsService, ReportHistoryRepository reportHistoryRepository, - @Value("${reports.storage.path:/data/reports}") String storagePath) { + MinIOService minIOService) { this.marketItemRepository = marketItemRepository; this.ollamaAnalyticsService = ollamaAnalyticsService; this.reportHistoryRepository = reportHistoryRepository; - this.storagePath = storagePath; + this.minIOService = minIOService; } public ReportBinary generate(ReportGenerateRequest req) { @@ -99,11 +98,9 @@ public class ReportGenerationService { private void persistReport(ReportGenerateRequest req, ReportBinary rb) { try { - java.nio.file.Path dir = java.nio.file.Paths.get(storagePath); - java.nio.file.Files.createDirectories(dir); - java.nio.file.Path file = dir.resolve(rb.getFilename()); if (rb.getBytes() != null) { - java.nio.file.Files.write(file, rb.getBytes()); + // Upload to MinIO + minIOService.uploadFile(rb.getFilename(), rb.getBytes(), rb.getMediaType().toString()); } ReportHistory rh = new ReportHistory(); @@ -114,7 +111,7 @@ public class ReportGenerationService { rh.setEndDate(req.getEndDate()); rh.setFormat(req.getFormat()); rh.setFilename(rb.getFilename()); - rh.setFilePath(file.toString()); + rh.setFilePath(rb.getFilename()); // Store object name instead of file path rh.setFileSize(rb.getBytes() == null ? 0 : rb.getBytes().length); rh.setCreatedAt(java.time.LocalDateTime.now()); reportHistoryRepository.save(rh); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 469b65a..a1a5ba1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,8 @@ -# Directory to store generated reports -reports.storage.path=/data/reports +# MinIO configuration +minio.endpoint=http://92.38.48.166:9000 +minio.access-key=z9HhZTjzhVWqw3D20u7q +minio.secret-key=lhhHtJow1b10z6EZRMTQIU1tsKkoaxCVpSypCrcb +minio.bucket-name=konturai spring.application.name=parser # MongoDB Configuration