From bb429511d3053b2153e2a03d34e372bbacfd7384 Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Thu, 24 Jul 2025 13:09:13 +0300 Subject: [PATCH] Cover MonitoringService with comments --- .../service/MonitoringService.java | 28 +++++++++++++------ .../service/signal/SignalRestService.java | 8 ++++-- .../service/xml/stax/StaxXmlProcessor.java | 12 ++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java b/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java index 02b22cc..a095623 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java @@ -70,14 +70,16 @@ public class MonitoringService { continue; } + // Формируем список имен файлов, по которым сработали сигналы. Сюда входят только те имена, у которых парсится дата формирования отчета List fileNames = onlineReports.getOperationReport().getReports().getReports().stream().map(Report::getFilename) - .filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать + .filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); if (fileNames.isEmpty()) { log.info("No new report found for package {}", userPackage.getPackageName()); continue; } + // Находим самый последний отчет по дате Optional newReport = Optional.of(fileNames) .orElseGet(Collections::emptyList) .stream().max(Comparator.comparing(CTUtil::parseDateFromReportFileName)); // отфильтровали только те имена, которые парсятся в дату, так что null тут не придет @@ -121,6 +123,10 @@ public class MonitoringService { log.info("Finish monitoring"); } + /** + * Формирует результирующий xml файл для конечного пользователя на основе файла из официального сервиса сигналов + * @return Путь к временному рещультирующему файлу + */ private String generateResponse(UserPackage userPackage, String reportPath) { String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator + userPackage.getId() + File.separator; String responsePath = folderPath + UUID.randomUUID() + "_response_output.xml"; @@ -128,15 +134,16 @@ public class MonitoringService { MonitoringSignalResponse response = new MonitoringSignalResponse(); response.setPackageName(userPackage.getPackageName()); // Имя пакета, переданного при установке + // Запись в результрующий файл MonitoringSignalResponseStaxXmlWriter staxXmlWriter = new MonitoringSignalResponseStaxXmlWriter(config.getEncoding()); staxXmlWriter.writeWithStax(responsePath, response, writer -> { try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(reportPath)), 4 * 1024 * 1024)) { staxXmlProcessor.read(in, Persons.class, - personsData -> { - List subjectsBatch = processPersons(userPackage, personsData.getPersons()); + personsData -> { // как только считали пачку Persons сразу записали ее в результирующий файл + List subjectsBatch = processPersons(personsData.getPersons()); writer.accept(subjectsBatch); - personsData.getPersons().clear(); + personsData.getPersons().clear(); // чистим список для экономии памяти }, 10000, "/Report/Persons/Person"); @@ -154,7 +161,7 @@ public class MonitoringService { return responsePath; } - private List processPersons(UserPackage userPackage, List persons) { + private List processPersons(List persons) { List subjects = new ArrayList<>(); for (Person person : persons) { Signals signals = new Signals(); @@ -187,6 +194,10 @@ public class MonitoringService { return subjects; } + /** + * Архивирует результирующий xml файл для пользователя + * @return Путь к результрующему файлу. Пример //0001ZZ_MY_BATCH_TEST_0717_04_20250723_101929.zip + */ private String createResponseFile(UserPackage userPackage, String responsePath) { try { String fileName = CTUtil.generateResponseReportFileName(userPackage.getUserId(), userPackage.getPackageName()); @@ -228,9 +239,10 @@ public class MonitoringService { private void updateSignalHits(UserPackage userPackage, String responsePath, String reportFileName) { log.info("Updating signal hits for {}", userPackage.getPackageName()); LocalDateTime responseSentAt = LocalDateTime.now(); + // Считываем результирующий файл пачками и обновляем таблицу hits try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(responsePath)), 4 * 1024 * 1024)) { staxXmlProcessor.read(in, MonitoringSignalResponse.class, - response -> { + response -> { // как только считали пачку Subjects сразу обновлям таблицу hits List hits = new ArrayList<>(); response.getSubjects().getSubjects().forEach(subject -> { subject.getSignals().getSignals().forEach(signal -> { @@ -244,7 +256,7 @@ public class MonitoringService { }); signalService.insertHits(hits); }); - response.getSubjects().getSubjects().clear(); + response.getSubjects().getSubjects().clear(); // чистим список для экономии памяти }, 10000, "/MonitoringSignalResponse/Subjects/Subject"); @@ -253,7 +265,7 @@ public class MonitoringService { } try { - Files.delete(Path.of(responsePath)); + Files.delete(Path.of(responsePath)); // удалям результирующий xml файл с диска (Он уже заархивирован к этому моменту) } catch (IOException e) { log.warn("File {} hasn't been deleted", responsePath); } diff --git a/src/main/java/ru/nbch/credit_tracker/service/signal/SignalRestService.java b/src/main/java/ru/nbch/credit_tracker/service/signal/SignalRestService.java index dd88b02..6c1b333 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/signal/SignalRestService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/signal/SignalRestService.java @@ -118,6 +118,10 @@ public class SignalRestService { } } + /** + * + * @return Список отчетов, по которым сработали сигналы из официального сервиса сигналов + */ public SgnlOnlineReport getReports(String packCode) { String url = GET_REPORTS_URI + "?packCode=" + packCode; @@ -149,9 +153,9 @@ public class SignalRestService { } /** - * Loads .gz report from nbki service, unzips it to tmp_folder + * Загружает .gz отчет из официального сервиса сигналов, разархивирует в tmp_folder * - * @return path to unzipped file. Example: /tmp_folder//0001XX_MY_BATCH_204.1.online.2025-07-08T20-00-46.xml.gz.xml + * @return путь к разархивированному файлу. Пример: /tmp_folder//0001XX_MY_BATCH_204.1.online.2025-07-08T20-00-46.xml.gz.xml */ public String downloadReport(Integer packageId, String reportName) { String url = DOWNLOAD_REPORT_URI + "?fNameReport=" + reportName; diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxXmlProcessor.java b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxXmlProcessor.java index 3004ae6..a340ec7 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxXmlProcessor.java +++ b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxXmlProcessor.java @@ -7,5 +7,17 @@ public interface StaxXmlProcessor { Z read(String xml, Class clazz); Z read(byte[] xml, Class clazz); Z read(InputStream inputStream, Class clazz); + + /** + * @param objProcessor: Консьюмер, который срабатывает, когда считается batchSize элементов endBatchElementPath + * @param batchSize: количество считываемых элементов в пачке + * @param endBatchElementPath: localPath считываемых в пачку элементов. Например: "/Report/Subjects/Subject" + * + * + * + * + * + * + */ Z read(InputStream inputStream, Class clazz, Consumer objProcessor, Integer batchSize, String endBatchElementPath); } \ No newline at end of file