LP: added package validation

This commit is contained in:
Mikhail Trofimov 2026-06-30 12:56:53 +03:00
parent 50b8eeee89
commit 15c651debd
7 changed files with 86 additions and 20 deletions

View file

@ -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());

View file

@ -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<Integer> signalTypes = null;

View file

@ -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;
}

View file

@ -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 не соответствует типу пакета"),
;

View file

@ -7,6 +7,7 @@ public class ValidationResult {
private String packageName;
private String userId;
private String password;
private Integer subjectType;
private List<Integer> signalTypes = new ArrayList<>();
private List<MonitoringValidationError> 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<Integer> getSignalTypes() {
return signalTypes;
}

View file

@ -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,20 +63,34 @@ public class ValidationService {
List<Integer> 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);
}
}
if (StringUtils.isBlank(request.getSubjectType())) {
for (Subject subject : request.getSubjects().getSubject()) {
if (!validateNPId(subject.getId())) {
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());
}
}
} 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());
}
}
}
}
private static boolean validatePhone(String input) {
@ -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;
}

View file

@ -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<MonitoringRequest> {
@ -24,12 +25,15 @@ public class MonitoringRequestStaxReader extends BaseStaxReader<MonitoringReques
case "/MonitoringRequest/UserId" -> 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;
}