From f052841954c7a7cc385e746121d8c59ef37f9e11 Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Thu, 17 Jul 2025 17:05:39 +0300 Subject: [PATCH] Update MonitoringService to read nbki responses by batches --- .../credit_tracker/config/xml/XmlConfig.java | 3 +- .../response/online_download/Inquiry.java | 14 ++ .../response/online_download/Person.java | 14 ++ .../response/online_download/Persons.java | 13 ++ .../service/MonitoringService.java | 121 ++++++++++++------ .../credit_tracker/service/SignalService.java | 14 +- .../service/xml/stax/BaseStaxReader.java | 26 +++- ...OnlineDownloadReportPersonsStaxReader.java | 77 +++++++++++ .../service/xml/stax/StaxReader.java | 2 + .../service/xml/stax/StaxXmlProcessor.java | 2 + .../xml/stax/XmlProcessorStaxImpl.java | 17 +++ .../ru/nbch/credit_tracker/utils/CTUtil.java | 18 +++ .../ru/nbch/credit_tracker/stax/StaxTest.java | 31 ++++- .../xml/nbki_monitoring_report.xml | 44 +++++++ 14 files changed, 340 insertions(+), 56 deletions(-) create mode 100644 src/main/java/ru/nbch/credit_tracker/service/xml/stax/OnlineDownloadReportPersonsStaxReader.java create mode 100644 src/test/resources/monitoring_request/xml/nbki_monitoring_report.xml diff --git a/src/main/java/ru/nbch/credit_tracker/config/xml/XmlConfig.java b/src/main/java/ru/nbch/credit_tracker/config/xml/XmlConfig.java index 8331a83..0661630 100644 --- a/src/main/java/ru/nbch/credit_tracker/config/xml/XmlConfig.java +++ b/src/main/java/ru/nbch/credit_tracker/config/xml/XmlConfig.java @@ -5,7 +5,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import ru.nbch.credit_tracker.entities.response.errors.MonitoringError; import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.MonitoringSignalResponse; -import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadReport; import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport; import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse; import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor; @@ -23,7 +22,6 @@ public class XmlConfig { public IXmlProcessor xmlProcessor() throws JAXBException { return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"), // unmarshalling classes - OnlineDownloadReport.class, SgnlOnlineReport.class, // marshalling classes MonitoringError.class, @@ -36,6 +34,7 @@ public class XmlConfig { List> staxReader = new ArrayList<>(); staxReader.add(new SgnlReportStatusStaxReader()); staxReader.add(new MonitoringRequestStaxReader()); + staxReader.add(new OnlineDownloadReportPersonsStaxReader()); return new XmlProcessorStaxImpl(staxReader); } } diff --git a/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Inquiry.java b/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Inquiry.java index 06b53cf..d3d49d3 100644 --- a/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Inquiry.java +++ b/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Inquiry.java @@ -42,4 +42,18 @@ public class Inquiry { return this.signals; } + private Signal currentSignal; + + public void createCurrentSignal() { + currentSignal = new Signal(); + } + + public Signal getCurrentSignal() { + return currentSignal; + } + + public void finalizeSignal() { + getSignals().add(currentSignal); + } + } diff --git a/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Person.java b/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Person.java index 11c2022..10da451 100644 --- a/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Person.java +++ b/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Person.java @@ -27,4 +27,18 @@ public class Person { } return this.inquiries; } + + private Inquiry currentInquiry; + + public void createCurrentInquiry() { + currentInquiry = new Inquiry(); + } + + public Inquiry getCurrentInquiry() { + return currentInquiry; + } + + public void finalizeInquiry() { + getInquiries().add(currentInquiry); + } } diff --git a/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Persons.java b/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Persons.java index 9ec4600..998cd09 100644 --- a/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Persons.java +++ b/src/main/java/ru/nbch/credit_tracker/entities/response/online_download/Persons.java @@ -24,5 +24,18 @@ public class Persons { return this.persons; } + private Person currentPerson; + + public void createCurrentPerson() { + currentPerson = new Person(); + } + + public Person getCurrentPerson() { + return currentPerson; + } + + public void finalizePerson() { + getPersons().add(currentPerson); + } } 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 7d25c2c..d1b2513 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java @@ -10,18 +10,19 @@ import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; import ru.nbch.credit_tracker.entities.dto.UserPackage; import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.*; import ru.nbch.credit_tracker.entities.response.online_download.Inquiry; -import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadReport; import ru.nbch.credit_tracker.entities.response.online_download.Person; +import ru.nbch.credit_tracker.entities.response.online_download.Persons; import ru.nbch.credit_tracker.entities.response.online_report.Report; import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport; import ru.nbch.credit_tracker.service.signal.SignalRestService; import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor; +import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor; import ru.nbch.credit_tracker.utils.CTUtil; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileOutputStream; +import java.io.*; import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.Executors; @@ -38,16 +39,19 @@ public class MonitoringService { private final SignalRestService signalRestService; private final SignalService signalService; private final IXmlProcessor xmlProcessor; + private final StaxXmlProcessor staxXmlProcessor; private final CreditTrackerSettings config; private final Integer batchSize = 10000; public MonitoringService(SignalRestService signalRestService, SignalService signalService, IXmlProcessor xmlProcessor, + StaxXmlProcessor staxXmlProcessor, CreditTrackerSettings config) { this.signalRestService = signalRestService; this.signalService = signalService; this.xmlProcessor = xmlProcessor; + this.staxXmlProcessor = staxXmlProcessor; this.config = config; } @@ -89,42 +93,73 @@ public class MonitoringService { log.info("Last Downloaded Report Name is empty"); } - OnlineDownloadReport report = null; - if (StringUtils.isBlank(userPackage.getLastDownloadedReport()) && newReport.isPresent()) { - report = loadReport(newReport.get()); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным - } else if (lastDownloadedReportDate != null && newReport.isPresent()) { - LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport.get()); - if (newReportDate.isAfter(lastDownloadedReportDate)) { - report = loadReport(newReport.get()); // полученный отчет новее записанного в базу + try { + String reportPath = null; + if (StringUtils.isBlank(userPackage.getLastDownloadedReport()) && newReport.isPresent()) { + reportPath = loadReport(userPackage.getId(), newReport.get()); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным + } else if (lastDownloadedReportDate != null && newReport.isPresent()) { + LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport.get()); + if (newReportDate.isAfter(lastDownloadedReportDate)) { + reportPath = loadReport(userPackage.getId(), newReport.get()); // полученный отчет новее записанного в базу + } + } + if (reportPath == null) { + log.info("Report was not loaded for package {}", userPackage.getPackageName()); + continue; } - } - if (report == null) { - log.info("Report was not loaded for package {}", userPackage.getPackageName()); - continue; - } - MonitoringSignalResponse response = generateResponse(userPackage, report.getPersons().getPersons()); - String fileName = createResponseFile(userPackage, response); - if (fileName != null) { - log.info("New report fileName: {}", fileName); - updateSignalHits(userPackage, response, fileName); - signalService.updateLastDownloadedReport(userPackage.getId(), newReport.get()); - } else { - log.info("Report was not created for package {}", userPackage.getPackageName()); + + MonitoringSignalResponse response = generateResponse(userPackage, reportPath); + String fileName = createResponseFile(userPackage, response); + if (fileName != null) { + log.info("New report fileName: {}", fileName); + updateSignalHits(userPackage, response, fileName); + signalService.updateLastDownloadedReport(userPackage.getId(), newReport.get()); + } else { + log.info("Report was not created for package {}", userPackage.getPackageName()); + } + } catch (Exception e) { + log.error(e.getMessage(), e); } } log.info("Finish monitoring"); } - private MonitoringSignalResponse generateResponse(UserPackage userPackage, List persons) { + private MonitoringSignalResponse generateResponse(UserPackage userPackage, String reportPath) { MonitoringSignalResponse response = new MonitoringSignalResponse(); response.setPackageName(userPackage.getPackageName()); // Имя пакета, переданного при установке Subjects subjects = new Subjects(); + + try (InputStream in = Files.newInputStream(Path.of(reportPath))) { + staxXmlProcessor.read(in, Persons.class, + personsData -> { + List subjectsBatch = processPersons(userPackage, personsData.getPersons()); + subjects.getSubjects().addAll(subjectsBatch); + personsData.getPersons().clear(); + }, + 10000, + "/Report/Persons/Person"); + } catch (IOException e) { + throw new RuntimeException("Error while parsing nbki downloaded report", e); + } + response.setSubjects(subjects); + + try { + Files.delete(Path.of(reportPath)); + } catch (IOException e) { + log.warn("File {} hasn't been deleted", reportPath); + } + + return response; + } + + private List processPersons(UserPackage userPackage, List persons) { + List subjects = new ArrayList<>(); for (Person person : persons) { Signals signals = new Signals(); for (Inquiry inquiry : person.getInquiries()) { // Отбираем только тех фл, у которых bus_category in (MFO, MKK, MFK) и есть сигналы с кодом 16 - if (!CTUtil.checkBusCategory(inquiry.getBusCategory()) && inquiry.getSignals().stream().anyMatch(signal -> signal.getN().equals(16))) { + if (!CTUtil.checkBusCategory(inquiry.getBusCategory()) || inquiry.getSignals().stream().anyMatch(signal -> signal.getN().equals(16))) { continue; } Signal signal = new Signal(); @@ -137,19 +172,18 @@ public class MonitoringService { // Если есть хотя бы один заполненный сигнал, значит заполняем остальные данные if (!signals.getSignals().isEmpty()) { PhoneFidMap subjectData = signalService.findPhoneFidMapBySubjectId(userPackage.getId(), person.getUid()); - if(subjectData != null) { + if (subjectData != null) { Subject subject = new Subject(); subject.setId(subjectData.getSubjectId()); // Уникальный идентификатор субъекта (равен Id из XML-пакета при установке мониторинга) subject.setClientId(subjectData.getPhone()); subject.setFlagDebt5000(subjectData.getFlagDebt5000()); subject.setFlag9012(subjectData.getFlag90days()); subject.setSignals(signals); - subjects.getSubjects().add(subject); + subjects.add(subject); } } } - response.setSubjects(subjects); - return response; + return subjects; } private String createResponseFile(UserPackage userPackage, MonitoringSignalResponse response) { @@ -202,22 +236,35 @@ public class MonitoringService { log.info("Signal hits updated for package {}", userPackage.getPackageName()); } - private OnlineDownloadReport loadReport(String reportName) { + /** + * Loads .gz report from nbki service, unzips it to tmp_folder + * + * @return path to unzipped file. Example: /tmp_folder//0001XX_MY_BATCH_204.1.online.2025-07-08T20-00-46.xml.gz.xml + */ + public String loadReport(Integer packageId, String reportName) { byte[] archive = signalRestService.downloadReport(reportName); if (archive == null) { return null; } - OnlineDownloadReport report; - try (GZIPInputStream zipInputStream = new GZIPInputStream(new ByteArrayInputStream(archive))) { - report = xmlProcessor.read(zipInputStream, OnlineDownloadReport.class); + String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator + packageId + File.separator; + String filePath = folderPath + reportName + ".xml"; + CTUtil.createFolder(folderPath); - } catch (Exception e) { + try (InputStream in = new GZIPInputStream(new ByteArrayInputStream(archive)); + OutputStream out = Files.newOutputStream(Path.of(filePath))) { + + byte[] buffer = new byte[65536]; + int bytesRead; + while ((bytesRead = in.read(buffer)) > 0) { + out.write(buffer, 0, bytesRead); + } + + return filePath; + } catch (IOException e) { log.error(e.getMessage(), e); return null; } - - return report; } } diff --git a/src/main/java/ru/nbch/credit_tracker/service/SignalService.java b/src/main/java/ru/nbch/credit_tracker/service/SignalService.java index 1fe8036..e839a70 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/SignalService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/SignalService.java @@ -20,11 +20,9 @@ import ru.nbch.credit_tracker.service.signal.HitsService; import ru.nbch.credit_tracker.service.signal.PhoneFidMapService; import ru.nbch.credit_tracker.service.signal.UserPackageService; import ru.nbch.credit_tracker.service.xml.stax.SignalsStaxXmlWriter; +import ru.nbch.credit_tracker.utils.CTUtil; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; import java.time.LocalDateTime; import java.util.*; import java.util.function.Consumer; @@ -175,15 +173,7 @@ public class SignalService { String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator + packageId + File.separator; String filePath = folderPath + UUID.randomUUID() + "_output.xml"; - File folder = new File(folderPath); - if (!folder.exists()) { - try { - Files.createDirectories(Path.of(folderPath)); - } catch (IOException e) { - log.error("Could not create folder: {}", folderPath, e); - throw new RuntimeException(e); - } - } + CTUtil.createFolder(folderPath); Signals signals = buildSignals(packageId); diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/BaseStaxReader.java b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/BaseStaxReader.java index 8dd6bec..9365668 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/BaseStaxReader.java +++ b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/BaseStaxReader.java @@ -6,15 +6,22 @@ import javax.xml.stream.XMLStreamReader; import java.util.ArrayDeque; import java.util.Deque; import java.util.Iterator; +import java.util.function.Consumer; public abstract class BaseStaxReader implements StaxReader { private final Deque stack = new ArrayDeque<>(); protected final StringBuilder buffer = new StringBuilder(); + protected abstract T createObject(); @Override public T read(XMLStreamReader reader) throws XMLStreamException { + return read(reader, null, null, null); + } + + public T read(XMLStreamReader reader, Consumer objProcessor, Integer batchSize, String endBatchElementPath) throws XMLStreamException { T obj = createObject(); + int objCount = 0; try { while (reader.hasNext()) { boolean breakExecution = false; @@ -29,14 +36,31 @@ public abstract class BaseStaxReader implements StaxReader { String text = reader.getText().trim(); if (!text.isEmpty()) buffer.append(text); } + case XMLStreamConstants.ATTRIBUTE -> { + breakExecution = innerProcess(reader, obj); + } case XMLStreamConstants.END_ELEMENT -> { breakExecution = innerProcess(reader, obj); + String lastElementPath = getPath(); endElement(); + if (objProcessor != null) { + if (endBatchElementPath.equals(lastElementPath)) { + objCount++; + if (objCount == batchSize) { + objProcessor.accept(obj); + objCount = 0; + } + } + } + } + default -> { } - default -> {} } if (breakExecution) break; } + if (objProcessor != null) { + objProcessor.accept(obj); + } return obj; } catch (Exception e) { stack.clear(); diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/OnlineDownloadReportPersonsStaxReader.java b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/OnlineDownloadReportPersonsStaxReader.java new file mode 100644 index 0000000..4c765ee --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/OnlineDownloadReportPersonsStaxReader.java @@ -0,0 +1,77 @@ +package ru.nbch.credit_tracker.service.xml.stax; + +import lombok.extern.slf4j.Slf4j; +import ru.nbch.credit_tracker.entities.response.online_download.Persons; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +@Slf4j +public class OnlineDownloadReportPersonsStaxReader extends BaseStaxReader { + + @Override + protected Persons createObject() { + return new Persons(); + } + + @Override + protected boolean innerProcess(XMLStreamReader reader, Persons obj) throws XMLStreamException { + String text = buffer.toString(); + String currPath = getPath(); + switch (currPath) { + case "/Report/Persons/Person" -> + obj.finalizePerson(); + case "/Report/Persons/Person/Inquiry" -> + obj.getCurrentPerson().finalizeInquiry(); + case "/Report/Persons/Person/Inquiry/Signal" -> + obj.getCurrentPerson().getCurrentInquiry().finalizeSignal(); + } + return false; + } + + @Override + protected void innerProcessStartElement(XMLStreamReader reader, Persons obj) throws XMLStreamException { + String currPath = getPath(); + switch (currPath) { + case "/Report/Persons/Person" -> + obj.createCurrentPerson(); + case "/Report/Persons/Person/Inquiry" -> + obj.getCurrentPerson().createCurrentInquiry(); + case "/Report/Persons/Person/Inquiry/Signal" -> + obj.getCurrentPerson().getCurrentInquiry().createCurrentSignal(); + } + + for (int i = 0; i < reader.getAttributeCount(); i++) { + String text = reader.getAttributeValue(i); + switch (reader.getAttributeLocalName(i)) { + case "uid" -> + obj.getCurrentPerson().setUid(text); + case "date" -> + obj.getCurrentPerson().getCurrentInquiry().setDate(text); + case "bus_category" -> + obj.getCurrentPerson().getCurrentInquiry().setBusCategory(text); + case "inq_p" -> { + try { + int inqP = Integer.parseInt(text); + obj.getCurrentPerson().getCurrentInquiry().setInqP(inqP); + } catch (NumberFormatException e) { + log.warn("Couldn't parse inqP: {}", text); + } + } + case "n" -> { + try { + int n = Integer.parseInt(text); + obj.getCurrentPerson().getCurrentInquiry().getCurrentSignal().setN(n); + } catch (NumberFormatException e) { + log.warn("Couldn't parse signal n: {}", text); + } + } + } + } + } + + @Override + public Class type() { + return Persons.class; + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxReader.java b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxReader.java index d594e9b..74b944d 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxReader.java +++ b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/StaxReader.java @@ -2,8 +2,10 @@ package ru.nbch.credit_tracker.service.xml.stax; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import java.util.function.Consumer; public interface StaxReader { Class type(); T read(XMLStreamReader xmlStreamReader) throws XMLStreamException; + T read(XMLStreamReader reader, Consumer objProcessor, Integer batchSize, String endBatchElementPath) throws XMLStreamException; } 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 9a5b65c..3004ae6 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 @@ -1,9 +1,11 @@ package ru.nbch.credit_tracker.service.xml.stax; import java.io.InputStream; +import java.util.function.Consumer; public interface StaxXmlProcessor { Z read(String xml, Class clazz); Z read(byte[] xml, Class clazz); Z read(InputStream inputStream, Class clazz); + Z read(InputStream inputStream, Class clazz, Consumer objProcessor, Integer batchSize, String endBatchElementPath); } \ No newline at end of file diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/XmlProcessorStaxImpl.java b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/XmlProcessorStaxImpl.java index 93fccda..8f32840 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/XmlProcessorStaxImpl.java +++ b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/XmlProcessorStaxImpl.java @@ -14,6 +14,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; public class XmlProcessorStaxImpl implements StaxXmlProcessor { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -83,4 +84,20 @@ public class XmlProcessorStaxImpl implements StaxXmlProcessor { throw new RuntimeException(e); } } + + @Override + public Z read(InputStream inputStream, Class clazz, Consumer objProcessor, Integer batchSize, String endBatchElementPath) { + try { + XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(inputStream); + @SuppressWarnings("unchecked") + StaxReader staxProcessor = (StaxReader) staxReaders.get(clazz); + if (staxProcessor != null) { + return staxProcessor.read(xmlStreamReader, objProcessor, batchSize, endBatchElementPath); + } + throw new IllegalStateException("no stax reader registered for " + clazz); + } catch (Exception e) { + log.error(ExceptionUtils.getStackTrace(e)); + throw new RuntimeException(e); + } + } } diff --git a/src/main/java/ru/nbch/credit_tracker/utils/CTUtil.java b/src/main/java/ru/nbch/credit_tracker/utils/CTUtil.java index 123dada..cece72d 100644 --- a/src/main/java/ru/nbch/credit_tracker/utils/CTUtil.java +++ b/src/main/java/ru/nbch/credit_tracker/utils/CTUtil.java @@ -1,7 +1,12 @@ package ru.nbch.credit_tracker.utils; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; @@ -10,6 +15,7 @@ import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; +@Slf4j public class CTUtil { private static DateTimeFormatter onlineReportDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss"); @@ -65,4 +71,16 @@ public class CTUtil { } return Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()); } + + public static void createFolder(String folderPath) { + File folder = new File(folderPath); + if (!folder.exists()) { + try { + Files.createDirectories(Path.of(folderPath)); + } catch (IOException e) { + log.error("Could not create folder: {}", folderPath, e); + throw new RuntimeException(e); + } + } + } } diff --git a/src/test/java/ru/nbch/credit_tracker/stax/StaxTest.java b/src/test/java/ru/nbch/credit_tracker/stax/StaxTest.java index 1030edd..5598dd0 100644 --- a/src/test/java/ru/nbch/credit_tracker/stax/StaxTest.java +++ b/src/test/java/ru/nbch/credit_tracker/stax/StaxTest.java @@ -8,10 +8,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest; import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject; -import ru.nbch.credit_tracker.service.xml.stax.MonitoringRequestStaxReader; -import ru.nbch.credit_tracker.service.xml.stax.StaxReader; -import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor; -import ru.nbch.credit_tracker.service.xml.stax.XmlProcessorStaxImpl; +import ru.nbch.credit_tracker.entities.response.online_download.Person; +import ru.nbch.credit_tracker.entities.response.online_download.Persons; +import ru.nbch.credit_tracker.service.xml.stax.*; import javax.xml.stream.XMLStreamException; import java.io.IOException; @@ -34,6 +33,7 @@ public class StaxTest { public StaxXmlProcessor xmlProcessor() { List> staxReader = new ArrayList<>(); staxReader.add(new MonitoringRequestStaxReader()); + staxReader.add(new OnlineDownloadReportPersonsStaxReader()); return new XmlProcessorStaxImpl(staxReader); } } @@ -84,4 +84,27 @@ public class StaxTest { Assertions.assertNull(monitoringRequest.getSubjects().getSubject().get(0).getId()); } + @Test + void testParseNbkiMonitoringReport() { + List firstPersonList = new ArrayList<>(); + staxXmlProcessor.read(getClass().getResourceAsStream("/monitoring_request/xml/nbki_monitoring_report.xml"), Persons.class, + personsData -> { + Assertions.assertTrue(personsData.getPersons().size() == 1 || personsData.getPersons().isEmpty()); + firstPersonList.addAll(personsData.getPersons()); + personsData.getPersons().clear(); + }, + 1, + "/Report/Persons/Person"); + + List secondPersonList = new ArrayList<>(); + staxXmlProcessor.read(getClass().getResourceAsStream("/monitoring_request/xml/nbki_monitoring_report.xml"), Persons.class, + personsData -> { + secondPersonList.addAll(personsData.getPersons()); + personsData.getPersons().clear(); + }, + 3, + "/Report/Persons/Person"); + + Assertions.assertEquals(firstPersonList.size(), secondPersonList.size()); + } } diff --git a/src/test/resources/monitoring_request/xml/nbki_monitoring_report.xml b/src/test/resources/monitoring_request/xml/nbki_monitoring_report.xml new file mode 100644 index 0000000..d7e157c --- /dev/null +++ b/src/test/resources/monitoring_request/xml/nbki_monitoring_report.xml @@ -0,0 +1,44 @@ + + + 0001XX_MY_BATCH_204 + 1 + 0001ZZ000001 + 08.07.2025 20:00:33 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +