From 15c651debd719695dde546f58141bc34e87a70fd Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Tue, 30 Jun 2026 12:56:53 +0300 Subject: [PATCH] LP: added package validation --- .../component/MonitoringRequestValidator.java | 10 +++- .../monitoring_request/MonitoringRequest.java | 14 ++--- .../monitoring_request/Subject.java | 9 ++- .../credit_tracker/enums/SignalError.java | 3 + .../model/ValidationResult.java | 9 +++ .../service/ValidationService.java | 55 ++++++++++++++++--- .../xml/stax/MonitoringRequestStaxReader.java | 6 +- 7 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/main/java/ru/nbch/credit_tracker/component/MonitoringRequestValidator.java b/src/main/java/ru/nbch/credit_tracker/component/MonitoringRequestValidator.java index 1a5e038..ca25046 100644 --- a/src/main/java/ru/nbch/credit_tracker/component/MonitoringRequestValidator.java +++ b/src/main/java/ru/nbch/credit_tracker/component/MonitoringRequestValidator.java @@ -1,7 +1,7 @@ package ru.nbch.credit_tracker.component; -import java.util.concurrent.atomic.AtomicBoolean; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings; @@ -11,8 +11,8 @@ import ru.nbch.credit_tracker.enums.XmlErrorFormat; import ru.nbch.credit_tracker.exceptions.SignalException; import ru.nbch.credit_tracker.model.MonitoringValidationError; import ru.nbch.credit_tracker.model.ValidationResult; -import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor; import ru.nbch.credit_tracker.service.ValidationService; +import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor; import ru.nbch.credit_tracker.utils.ZipUtils; import java.io.BufferedInputStream; @@ -20,6 +20,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -85,6 +86,11 @@ public class MonitoringRequestValidator { if (request.getPassword() != null && validationResult.getPassword() == null) { validationResult.setPassword(request.getPassword()); } + if (StringUtils.isBlank(request.getSubjectType()) && validationResult.getSubjectType() == null) { + validationResult.setSubjectType(1); + } else if (StringUtils.isNotBlank(request.getSubjectType()) && validationResult.getSubjectType() == null) { + validationResult.setSubjectType(2); + } if (request.getSignalTypes() != null && !request.getSignalTypes().isEmpty() && validationResult.getSignalTypes().isEmpty()) { validationResult.setSignalTypes(request.getSignalTypes()); diff --git a/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/MonitoringRequest.java b/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/MonitoringRequest.java index 69c9c38..58e1a4e 100644 --- a/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/MonitoringRequest.java +++ b/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/MonitoringRequest.java @@ -1,16 +1,13 @@ package ru.nbch.credit_tracker.entities.user_request.monitoring_request; -import jakarta.xml.bind.annotation.XmlAccessType; -import jakarta.xml.bind.annotation.XmlAccessorType; -import jakarta.xml.bind.annotation.XmlElement; -import jakarta.xml.bind.annotation.XmlRootElement; -import jakarta.xml.bind.annotation.XmlType; -import java.util.ArrayList; -import java.util.List; +import jakarta.xml.bind.annotation.*; import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; +import java.util.List; + @Setter @Getter @@ -19,6 +16,7 @@ import lombok.Setter; "userId", "password", "packageName", + "subjectType", "subjects" }) @XmlRootElement(name = "MonitoringRequest") @@ -30,6 +28,8 @@ public class MonitoringRequest { protected String password; @XmlElement(name = "PackageName", required = true) protected String packageName; + @XmlElement(name = "SubjectType", required = false) + protected String subjectType; @XmlElement(name = "Subjects", required = true) protected Subjects subjects; protected List signalTypes = null; diff --git a/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/Subject.java b/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/Subject.java index 626f698..d5b23ad 100644 --- a/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/Subject.java +++ b/src/main/java/ru/nbch/credit_tracker/entities/user_request/monitoring_request/Subject.java @@ -14,7 +14,9 @@ import lombok.Setter; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "SubjectType", propOrder = { "id", - "clientId" + "clientId", + "inn", + "regNum" }) public class Subject { @@ -24,5 +26,10 @@ public class Subject { @XmlElement(name = "ClientId", required = true) protected String clientId; + @XmlElement(name = "Inn", required = true) + protected String inn; + + @XmlElement(name = "RegNum", required = true) + protected String regNum; } diff --git a/src/main/java/ru/nbch/credit_tracker/enums/SignalError.java b/src/main/java/ru/nbch/credit_tracker/enums/SignalError.java index 0a5aa5c..f6de324 100644 --- a/src/main/java/ru/nbch/credit_tracker/enums/SignalError.java +++ b/src/main/java/ru/nbch/credit_tracker/enums/SignalError.java @@ -28,6 +28,9 @@ public enum SignalError implements IEnumKeyCode { ERROR_026("026", "Пакет {} обновляется. Удаление невозможно. Дождитесь завершения обновления и повторите попытку."), ERROR_027("027", "Недопустимое значение в элементе SignalTypes"), ERROR_028("028", "Некорректный формат запроса: в теле ожидается ZIP-архив"), + ERROR_029("029", "Элемент Inn не соответствует формату XXXXXXXXX. Id: {}"), + ERROR_030("030", "Элемент RegNum не соответствует формату XXXXXXXXXXXXX. Id: {}"), + ERROR_031("031", "Состав Subject не соответствует типу пакета"), ; diff --git a/src/main/java/ru/nbch/credit_tracker/model/ValidationResult.java b/src/main/java/ru/nbch/credit_tracker/model/ValidationResult.java index ec4c00a..e13469d 100644 --- a/src/main/java/ru/nbch/credit_tracker/model/ValidationResult.java +++ b/src/main/java/ru/nbch/credit_tracker/model/ValidationResult.java @@ -7,6 +7,7 @@ public class ValidationResult { private String packageName; private String userId; private String password; + private Integer subjectType; private List signalTypes = new ArrayList<>(); private List validationErrors = new ArrayList<>(); @@ -41,6 +42,14 @@ public class ValidationResult { this.password = password; } + public Integer getSubjectType() { + return subjectType; + } + + public void setSubjectType(Integer subjectType) { + this.subjectType = subjectType; + } + public List getSignalTypes() { return signalTypes; } diff --git a/src/main/java/ru/nbch/credit_tracker/service/ValidationService.java b/src/main/java/ru/nbch/credit_tracker/service/ValidationService.java index 03d3266..ad0df1f 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/ValidationService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/ValidationService.java @@ -1,8 +1,7 @@ package ru.nbch.credit_tracker.service; -import java.util.List; -import java.util.regex.Pattern; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import ru.nbch.credit_tracker.config.mdc.SetAndClearMdc; import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest; @@ -10,6 +9,10 @@ import ru.nbch.credit_tracker.entities.user_request.monitoring_request.Subject; import ru.nbch.credit_tracker.enums.SignalError; import ru.nbch.credit_tracker.enums.XmlErrorFormat; import ru.nbch.credit_tracker.exceptions.SignalClientException; + +import java.util.List; +import java.util.regex.Pattern; + import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp; @Slf4j @@ -17,6 +20,8 @@ import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp; public class ValidationService { private static final String phoneRegex = "^\\d{9}$"; + private static final String innRegex = "^\\d{10}$"; + private static final String regNumRegex = "^\\d{13}$"; private static final String packageNameRegex = "^[A-Z0-9_]{1,22}$"; private static final String npIdRegex = "^\\S{1,36}$"; @@ -44,6 +49,10 @@ public class ValidationService { throw clientExcp(SignalError.ERROR_002, packageName, XmlErrorFormat.MonitoringError, "Password"); } + if (StringUtils.isNotBlank(request.getSubjectType()) && !request.getSubjectType().equalsIgnoreCase("LEGAL")) { + throw clientExcp(SignalError.ERROR_031, XmlErrorFormat.MonitoringError); + } + if (request.getSubjects() == null) { throw clientExcp(SignalError.ERROR_002, packageName, XmlErrorFormat.MonitoringError, "Subjects"); } @@ -54,18 +63,32 @@ public class ValidationService { List signalTypes = request.getSignalTypes(); if (signalTypes != null) { - boolean validValues = !signalTypes.isEmpty() && signalTypes.stream().allMatch(integer -> integer == 1 || integer == 2); + boolean validValues = !signalTypes.isEmpty() && signalTypes.stream().allMatch(integer -> integer == 1 || integer == 2 || integer == 3); if (!validValues) { throw clientExcp(SignalError.ERROR_027, packageName, XmlErrorFormat.MonitoringError); } } - for (Subject subject : request.getSubjects().getSubject()) { - if (!validateNPId(subject.getId())) { - throw clientExcp(SignalError.ERROR_010, packageName, XmlErrorFormat.MonitoringError, subject.getId()); + if (StringUtils.isBlank(request.getSubjectType())) { + for (Subject subject : request.getSubjects().getSubject()) { + if (!validateId(subject.getId())) { + throw clientExcp(SignalError.ERROR_010, packageName, XmlErrorFormat.MonitoringError, subject.getId()); + } + if (!validatePhone(subject.getClientId())) { + throw clientExcp(SignalError.ERROR_003, packageName, XmlErrorFormat.MonitoringError, subject.getId()); + } } - if (!validatePhone(subject.getClientId())) { - throw clientExcp(SignalError.ERROR_003, packageName, XmlErrorFormat.MonitoringError, subject.getId()); + } else { + for (Subject subject : request.getSubjects().getSubject()) { + if (!validateId(subject.getId())) { + throw clientExcp(SignalError.ERROR_010, packageName, XmlErrorFormat.MonitoringError, subject.getId()); + } + if (!validateInn(subject.getInn())) { + throw clientExcp(SignalError.ERROR_029, packageName, XmlErrorFormat.MonitoringError, subject.getId()); + } + if (!validateRegNum(subject.getRegNum())) { + throw clientExcp(SignalError.ERROR_030, packageName, XmlErrorFormat.MonitoringError, subject.getId()); + } } } } @@ -77,6 +100,20 @@ public class ValidationService { return Pattern.matches(phoneRegex, input); } + private static boolean validateInn(String input) { + if (input == null) { + return false; + } + return Pattern.matches(innRegex, input); + } + + private static boolean validateRegNum(String input) { + if (input == null) { + return false; + } + return Pattern.matches(regNumRegex, input); + } + private static boolean validatePackageName(String input) { if (input == null) { return false; @@ -84,7 +121,7 @@ public class ValidationService { return Pattern.matches(packageNameRegex, input); } - private static boolean validateNPId(String input) { + private static boolean validateId(String input) { if (input == null) { return false; } diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/MonitoringRequestStaxReader.java b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/MonitoringRequestStaxReader.java index 5780ce2..af6d46d 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/xml/stax/MonitoringRequestStaxReader.java +++ b/src/main/java/ru/nbch/credit_tracker/service/xml/stax/MonitoringRequestStaxReader.java @@ -1,8 +1,9 @@ package ru.nbch.credit_tracker.service.xml.stax; +import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest; + import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest; public class MonitoringRequestStaxReader extends BaseStaxReader { @@ -24,12 +25,15 @@ public class MonitoringRequestStaxReader extends BaseStaxReader obj.setUserId(text); case "/MonitoringRequest/Password" -> obj.setPassword(text); case "/MonitoringRequest/PackageName" -> obj.setPackageName(text); + case "/MonitoringRequest/SubjectType" -> obj.setSubjectType(text); case "/MonitoringRequest/SignalTypes/SignalType" -> { if (!text.isEmpty()) obj.getSignalTypes().add(Integer.parseInt(text)); } case "/MonitoringRequest/Subjects/Subject" -> obj.finalizeSubject(); case "/MonitoringRequest/Subjects/Subject/Id" -> obj.getCurrentSubject().setId(text); case "/MonitoringRequest/Subjects/Subject/ClientId" -> obj.getCurrentSubject().setClientId(text); + case "/MonitoringRequest/Subjects/Subject/Inn" -> obj.getCurrentSubject().setInn(text); + case "/MonitoringRequest/Subjects/Subject/RegNum" -> obj.getCurrentSubject().setRegNum(text); } return false; }