From 392b99aca4d9b1fbc905a34932346bbb214aff2a Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Tue, 1 Jul 2025 15:47:45 +0300 Subject: [PATCH 01/11] new exception --- .../config/rest/GlobalExceptionHandler.java | 36 +++++- .../entities/dto/SubjectData.java | 2 + .../credit_tracker/enums/EnumKeyMessage.java | 41 +++++++ .../credit_tracker/enums/IEnumKeyCode.java | 102 +++++++++++++++++ .../credit_tracker/enums/SignalError.java | 17 ++- .../credit_tracker/enums/XmlErrorFormat.java | 10 ++ .../exceptions/SignalClientException.java | 18 +++ .../exceptions/SignalErrorException.java | 4 +- .../credit_tracker/facade/SignalFacade.java | 105 ++++++++---------- .../service/xml/jaxb/XmlUtilService.java | 1 + .../nbch/credit_tracker/utils/ZipUtils.java | 28 +++++ .../utils/error/ExceptionUtils.java | 15 +++ .../utils/error/SimpleMessageResolver.java | 12 ++ 13 files changed, 325 insertions(+), 66 deletions(-) create mode 100644 src/main/java/ru/nbch/credit_tracker/enums/EnumKeyMessage.java create mode 100644 src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java create mode 100644 src/main/java/ru/nbch/credit_tracker/enums/XmlErrorFormat.java create mode 100644 src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java create mode 100644 src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java create mode 100644 src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java create mode 100644 src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java diff --git a/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java b/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java index 3ce661b..c37e324 100644 --- a/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java +++ b/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java @@ -1,5 +1,6 @@ package ru.nbch.credit_tracker.config.rest; +import java.nio.charset.Charset; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -7,13 +8,19 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import ru.nbch.credit_tracker.entities.response.errors.CommonError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringDownloadError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringPackageDeleteError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringReportListError; +import ru.nbch.credit_tracker.exceptions.SignalClientException; import ru.nbch.credit_tracker.exceptions.SignalErrorException; - -import java.nio.charset.Charset; +import ru.nbch.credit_tracker.utils.error.SimpleMessageResolver; @RestControllerAdvice public class GlobalExceptionHandler { + private final SimpleMessageResolver messageResolver = new SimpleMessageResolver(); @ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE) public ResponseEntity handleInvalidUser(SignalErrorException ex) { HttpHeaders headers = new HttpHeaders(); @@ -24,4 +31,29 @@ public class GlobalExceptionHandler { return new ResponseEntity<>(ex.getError(), headers, HttpStatus.INTERNAL_SERVER_ERROR); } } + + @ExceptionHandler(value = SignalClientException.class, produces = MediaType.APPLICATION_XML_VALUE) + public ResponseEntity handleClientException(SignalClientException ex) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251"))); + CommonError commonError = getCommonError(ex); + commonError.setStatus("error"); + commonError.setErrorCode(ex.getErrorMessage().getSubject().getErrorCode()); + commonError.setErrorText(messageResolver.resolve(ex.getErrorMessage())); + + return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST); + } + + private static CommonError getCommonError(SignalClientException ex) { + CommonError commonError; + switch (ex.getErrorFormat()) { + case MonitoringError -> commonError = new MonitoringError(); + case MonitoringActivePackagesError -> commonError = new MonitoringActivePackagesError(); + case MonitoringDownloadError -> commonError = new MonitoringDownloadError(); + case MonitoringReportListError -> commonError = new MonitoringReportListError(); + case MonitoringPackageDeleteError -> commonError = new MonitoringPackageDeleteError(); + default -> throw new IllegalStateException("Unsupported error format: " + ex.getErrorFormat()); + } + return commonError; + } } diff --git a/src/main/java/ru/nbch/credit_tracker/entities/dto/SubjectData.java b/src/main/java/ru/nbch/credit_tracker/entities/dto/SubjectData.java index 95e1cd9..0dca665 100644 --- a/src/main/java/ru/nbch/credit_tracker/entities/dto/SubjectData.java +++ b/src/main/java/ru/nbch/credit_tracker/entities/dto/SubjectData.java @@ -1,6 +1,7 @@ package ru.nbch.credit_tracker.entities.dto; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -11,6 +12,7 @@ import java.time.LocalDateTime; @Setter @AllArgsConstructor @NoArgsConstructor +@Builder public class SubjectData { private Integer id; private Integer packageId; diff --git a/src/main/java/ru/nbch/credit_tracker/enums/EnumKeyMessage.java b/src/main/java/ru/nbch/credit_tracker/enums/EnumKeyMessage.java new file mode 100644 index 0000000..5c9e30f --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/enums/EnumKeyMessage.java @@ -0,0 +1,41 @@ +package ru.nbch.credit_tracker.enums; + +import java.util.Arrays; +import java.util.Collections; + +public class EnumKeyMessage { + private final IEnumKeyCode subject; + /** + * Параметры для подстановки в текст сообщения. Все Serializable. + * args not null. + */ + private Object[] args; + + public EnumKeyMessage(IEnumKeyCode subject) { + this.subject = subject; + this.args = Collections.emptyList().toArray(new Object[0]); + } + + + public EnumKeyMessage(IEnumKeyCode subject, Object... args) { + this.subject = subject; + this.args = args; + } + + public IEnumKeyCode getSubject() { + return subject; + } + + public Object[] getArgs() { + return args; + } + + public void setArgs(Object[] args) { + this.args = args; + } + + @Override + public String toString() { + return "EnumKeyMessage{subject=" + subject + ", args: " + Arrays.toString(args) + "}"; + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java b/src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java new file mode 100644 index 0000000..ea808ce --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java @@ -0,0 +1,102 @@ +package ru.nbch.credit_tracker.enums; + +import java.io.Serializable; +import java.util.Objects; + +public interface IEnumKeyCode extends Serializable { + String getKey(); + String getCode(); + + default boolean equalsByKey(String key) { + return key != null && getKey().equalsIgnoreCase(key); + } + + /** + * Проверяет что среди данного набора Enum, присутствует элемент с данным id + * id может быть null + */ + static & IEnumKeyCode> boolean contains(String id, T... enumSet) { + for (T e : enumSet) { + if (Objects.equals(id, e.getKey())) + return true; + } + return false; + } + static & IEnumKeyCode> boolean containsIgnoreCase(String id, T... enumSet) { + for (T e : enumSet) { + if (e.getKey() != null && e.getKey().equalsIgnoreCase(id)) { + return true; + } + } + return false; + } + + static & IEnumKeyCode> boolean contains(T e, T... enumSet) { + for (T enumEl : enumSet) { + if (enumEl.equals(e)) + return true; + } + return false; + } + + /** + * Проверяет что среди всех Enum данного класса, присутствует элемент с данным id + * id может быть null + */ + static & IEnumKeyCode> boolean contains(String key, Class enumClass) { + for (T e : enumClass.getEnumConstants()) { + if (Objects.equals(key, e.getKey())) + return true; + } + return false; + } + + /** + * Возвращает Enum по id, если в заданном классе такой определен + * id может быть null + * + * @return Enum если нашел, иначе null + */ + static & IEnumKeyCode> T getEnumByKey(Class enumClass, String key) { + for (T e : enumClass.getEnumConstants()) { + if (Objects.equals(key, e.getKey())) + return e; + } + return null; + } + + static & IEnumKeyCode> T getEnumByKeyOrUndefined(Class enumClass, String key) { + T enumByKey = getEnumByKey(enumClass, key); + return enumByKey == null ? getUndefined(enumClass) : enumByKey; + } + + static & IEnumKeyCode> T getUndefined(Class enumClass) { + T enumByKey = getEnumByKey(enumClass, UNDEFINED_VALUE); + if (enumByKey == null) { + throw new IllegalArgumentException("Undefined value not found in enum " + enumClass); + } + return enumByKey; + } + + default boolean theSameAs(Object other) { + if (!(other instanceof IEnumKeyCode otherCasted)) { + return false; + } + return this.getKey().equalsIgnoreCase(otherCasted.getKey()); + } + + default String getErrorCode() { + String key = getKey(); + String[] split = key.split("\\."); + if (split.length < 1) return null; + String s = split[split.length - 1]; + if (!s.matches("\\d+")) return null; + return s; + } + + static String getKeyOrNull(IEnumKeyCode enumVal) { + return enumVal == null ? null : enumVal.getKey(); + } + + String UNDEFINED_VALUE = "_Undefined"; +} 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 3a645e6..f3c8c1e 100644 --- a/src/main/java/ru/nbch/credit_tracker/enums/SignalError.java +++ b/src/main/java/ru/nbch/credit_tracker/enums/SignalError.java @@ -1,9 +1,6 @@ package ru.nbch.credit_tracker.enums; -import lombok.Getter; - -@Getter -public enum SignalError { +public enum SignalError implements IEnumKeyCode { ERROR_001("001", "Ошибка распаковки архива"), ERROR_002("002", "Отсутствует обязательный элемент: "), ERROR_003("003", "Элемент ClientId не соответствует формату XXXXXXXXX"), @@ -31,4 +28,16 @@ public enum SignalError { this.code = code; this.message = message; } + + @Override + public String getKey() { + return message; + } + + @Override + public String getCode() { + return code; + } + + } diff --git a/src/main/java/ru/nbch/credit_tracker/enums/XmlErrorFormat.java b/src/main/java/ru/nbch/credit_tracker/enums/XmlErrorFormat.java new file mode 100644 index 0000000..45498ea --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/enums/XmlErrorFormat.java @@ -0,0 +1,10 @@ +package ru.nbch.credit_tracker.enums; + +public enum XmlErrorFormat { + MonitoringActivePackagesError, + MonitoringDownloadError, + MonitoringError, + MonitoringPackageDeleteError, + MonitoringReportListError + +} diff --git a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java new file mode 100644 index 0000000..e6d85cb --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java @@ -0,0 +1,18 @@ +package ru.nbch.credit_tracker.exceptions; + +import lombok.Getter; +import ru.nbch.credit_tracker.enums.EnumKeyMessage; +import ru.nbch.credit_tracker.enums.XmlErrorFormat; + +@Getter +public class SignalClientException extends RuntimeException { + + private final EnumKeyMessage errorMessage; + private final XmlErrorFormat errorFormat; + + public SignalClientException(EnumKeyMessage errorMessage, + XmlErrorFormat errorFormat) { + this.errorMessage = errorMessage; + this.errorFormat = errorFormat; + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java index d3afa23..cad58f4 100644 --- a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java +++ b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java @@ -19,9 +19,9 @@ public class SignalErrorException extends RuntimeException { errorMessage.setStatus("error"); errorMessage.setErrorCode(error.getCode()); if (tag != null) { - errorMessage.setErrorText(error.getMessage() + " " + tag); + errorMessage.setErrorText(error.getKey() + " " + tag); } else { - errorMessage.setErrorText(error.getMessage()); + errorMessage.setErrorText(error.getKey()); } return errorMessage; } diff --git a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java index e1bff2d..d352328 100644 --- a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java +++ b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java @@ -1,5 +1,14 @@ package ru.nbch.credit_tracker.facade; +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.io.FileUrlResource; @@ -12,13 +21,19 @@ import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActiveP 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.entities.response.active_packages.MonitoringActivePackagesResponse; -import ru.nbch.credit_tracker.entities.response.errors.*; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringDownloadError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringPackageDeleteError; +import ru.nbch.credit_tracker.entities.response.errors.MonitoringReportListError; import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse; import ru.nbch.credit_tracker.entities.signal_package.Signals; import ru.nbch.credit_tracker.enums.SignalError; import ru.nbch.credit_tracker.enums.Status; +import ru.nbch.credit_tracker.enums.XmlErrorFormat; +import ru.nbch.credit_tracker.exceptions.SignalClientException; import ru.nbch.credit_tracker.exceptions.SignalErrorException; import ru.nbch.credit_tracker.service.SignalService; import ru.nbch.credit_tracker.service.indic.PhoneService; @@ -28,14 +43,8 @@ import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor; import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService; import ru.nbch.credit_tracker.utils.CTUtil; import ru.nbch.credit_tracker.utils.ValidationUtil; - -import java.io.File; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; +import ru.nbch.credit_tracker.utils.ZipUtils; +import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.excp; @Slf4j @Service @@ -76,64 +85,44 @@ public class SignalFacade { } // Валидация Архива на количетсво файлов, размер и расширение - try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) { - int fileCount = 0; - ZipEntry xmlEntry = null; - - ZipEntry entry = zipInputStream.getNextEntry(); - while (entry != null) { - if (!entry.isDirectory()) { - fileCount++; - if (fileCount > 1) { // Архив должен содержать ровно один XML-файл - throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); - } - - if (!entry.getName().toLowerCase().endsWith(".xml")) { // Файл должен быть с расширением xml - throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); - } - - xmlEntry = entry; - } else { - throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); // Архив должен содержать ровно один XML-файл. Никаких доп директорий - } - zipInputStream.closeEntry(); - entry = zipInputStream.getNextEntry(); - } - - if (fileCount == 0) { // Архив должен содержать ровно один XML-файл - throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); - } - - if (xmlEntry.getSize() > MAX_XML_FILE_SIZE) { // максимально 2 Гб до запаковки - throw new SignalErrorException(SignalError.ERROR_009, null, new MonitoringError(), true); - } - - } catch (Exception e) { - if (e instanceof SignalErrorException) { - throw (SignalErrorException) e; - } - log.error(e.getMessage(), e); - throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false); - } - - // Теперь знаем, что в архиве лежит ровно один файл с раширением xml и он весит меньше 2гб. Можно валидировать сам xml - // Пробуем распарсить xml MonitoringRequest monitoringRequest; Integer packageId; - try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) { + ZipInputStream zipInputStream = null; + try { + zipInputStream = new ZipInputStream(file.getInputStream()); + Optional xmlFileEntry = ZipUtils.extractValidEntry(zipInputStream); + if (xmlFileEntry.isEmpty()) { + throw excp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError); + } + if (xmlFileEntry.get().getSize() > MAX_XML_FILE_SIZE) { + throw excp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError); + } + + zipInputStream.close(); + zipInputStream = new ZipInputStream(file.getInputStream()); zipInputStream.getNextEntry(); IXmlProcessor processor = xmlUtilService.createJaxbProcessor(); monitoringRequest = processor.read(zipInputStream, MonitoringRequest.class); - } catch (Exception e) { - if (e instanceof SignalErrorException) { - throw (SignalErrorException) e; + if (e instanceof SignalClientException) { + throw (SignalClientException) e; } log.error(e.getMessage(), e); - throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false); + //todo throw new SignalServerException(e); + throw excp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError); + } finally { + if (zipInputStream != null) { + try { + zipInputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + //todo throw new SignalServerException(e); + } + } } + // валидация xml try { validateMonitoringRequest(monitoringRequest); @@ -247,8 +236,8 @@ public class SignalFacade { private boolean isZipFile(MultipartFile file) { return file.getContentType() != null && - (file.getContentType().equals("application/zip") || file.getContentType().equals("application/x-zip-compressed")) || - file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".zip"); + (file.getContentType().equals("application/zip") || file.getContentType().equals("application/x-zip-compressed")) || + file.getOriginalFilename() != null && file.getOriginalFilename().toLowerCase().endsWith(".zip"); } public ResponseEntity findActivePackages(MonitoringActivePackagesRequest activePackagesRequest) { diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/jaxb/XmlUtilService.java b/src/main/java/ru/nbch/credit_tracker/service/xml/jaxb/XmlUtilService.java index d8a1081..77253e7 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/xml/jaxb/XmlUtilService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/xml/jaxb/XmlUtilService.java @@ -35,6 +35,7 @@ import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; @Service public class XmlUtilService { + //сделать бином public IXmlProcessor createJaxbProcessor() throws JAXBException { return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"), // unmarshalling classes diff --git a/src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java b/src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java new file mode 100644 index 0000000..4d1438e --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java @@ -0,0 +1,28 @@ +package ru.nbch.credit_tracker.utils; + +import java.io.IOException; +import java.util.Optional; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ZipUtils { + public static Optional extractValidEntry(ZipInputStream inputStream) throws IOException { + Optional zipEntry = Optional.empty(); + ZipEntry entry; + while ((entry = inputStream.getNextEntry()) != null) { + if (!entry.isDirectory()) { + if (zipEntry.isPresent()) { + //если мы уже нашли валидный xml файл, то обработка всего файла недоступна, возвращаем пустой entry + return Optional.empty(); + } + if (entry.getName().toLowerCase().endsWith(".xml")) { // Файл должен быть с расширением xml + zipEntry = Optional.of(entry); + } + } + inputStream.closeEntry(); + } + return zipEntry; + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java b/src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java new file mode 100644 index 0000000..320aa87 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java @@ -0,0 +1,15 @@ +package ru.nbch.credit_tracker.utils.error; + +import ru.nbch.credit_tracker.enums.EnumKeyMessage; +import ru.nbch.credit_tracker.enums.IEnumKeyCode; +import ru.nbch.credit_tracker.enums.XmlErrorFormat; +import ru.nbch.credit_tracker.exceptions.SignalClientException; + +public class ExceptionUtils { +// public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat) { +// return new SignalClientException(new EnumKeyMessage(enumKeyCode), xmlErrorFormat); +// } + public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) { + return new SignalClientException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat); + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java b/src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java new file mode 100644 index 0000000..c557a8a --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java @@ -0,0 +1,12 @@ +package ru.nbch.credit_tracker.utils.error; + +import java.util.Arrays; +import ru.nbch.credit_tracker.enums.EnumKeyMessage; + + +public class SimpleMessageResolver { + public String resolve(EnumKeyMessage errorMessage) { + if (errorMessage == null) return "null"; + return String.format("(%s) args %s", errorMessage.getSubject().getKey(), Arrays.toString(errorMessage.getArgs())); + } +} From b80ec82ab913a4e52ea32de38e4ca7112fec958d Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Tue, 1 Jul 2025 18:10:58 +0300 Subject: [PATCH 02/11] Split signal mappers by tables --- .../mapper/signal/HitsMapper.java | 14 ++++ .../mapper/signal/PhoneFidMapMapper.java | 24 +++++++ ...gnalMapper.java => UserPackageMapper.java} | 22 +----- .../credit_tracker/service/SignalService.java | 46 ++++++++----- .../service/signal/HitsService.java | 21 ++++++ .../service/signal/PhoneFidMapService.java | 39 +++++++++++ .../service/signal/UserPackageService.java | 56 +++++++++++++++ .../mybatis/mapper/signal/HitsMapper.xml | 16 +++++ .../mybatis/mapper/signal/PhoneFidMapper.xml | 69 +++++++++++++++++++ ...SignalMapper.xml => UserPackageMapper.xml} | 69 +------------------ 10 files changed, 270 insertions(+), 106 deletions(-) create mode 100644 src/main/java/ru/nbch/credit_tracker/mapper/signal/HitsMapper.java create mode 100644 src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java rename src/main/java/ru/nbch/credit_tracker/mapper/signal/{SignalMapper.java => UserPackageMapper.java} (52%) create mode 100644 src/main/java/ru/nbch/credit_tracker/service/signal/HitsService.java create mode 100644 src/main/java/ru/nbch/credit_tracker/service/signal/PhoneFidMapService.java create mode 100644 src/main/java/ru/nbch/credit_tracker/service/signal/UserPackageService.java create mode 100644 src/main/resources/mybatis/mapper/signal/HitsMapper.xml create mode 100644 src/main/resources/mybatis/mapper/signal/PhoneFidMapper.xml rename src/main/resources/mybatis/mapper/signal/{SignalMapper.xml => UserPackageMapper.xml} (55%) diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/signal/HitsMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/signal/HitsMapper.java new file mode 100644 index 0000000..b5df999 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/mapper/signal/HitsMapper.java @@ -0,0 +1,14 @@ +package ru.nbch.credit_tracker.mapper.signal; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import ru.nbch.credit_tracker.entities.dto.HitsData; + +import java.util.List; + +@Mapper +public interface HitsMapper { + + void setHits(@Param("hits") List hits); + +} diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java new file mode 100644 index 0000000..23495c7 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/mapper/signal/PhoneFidMapMapper.java @@ -0,0 +1,24 @@ +package ru.nbch.credit_tracker.mapper.signal; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import ru.nbch.credit_tracker.entities.dto.SubjectData; +import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject; + +import java.time.LocalDateTime; +import java.util.List; + +@Mapper +public interface PhoneFidMapMapper { + + void registerSubjects(@Param("subjects") List subjects, @Param("packageId") Integer packageId); + + void registerSubjectsFidAndDebts(@Param("id") Integer id, @Param("fid") Integer fid, @Param("flagDebt5000") Integer flagDebt5000, @Param("flag90") Integer flag90, @Param("calculatedAt") LocalDateTime calculatedAt); + + List findSubjectsData(@Param("packageId") Integer packageId); + + List findFullSubjectsData(@Param("packageId") Integer packageId); + + void updateSubjects(@Param("subjects") List subjects); + +} diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/signal/SignalMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/signal/UserPackageMapper.java similarity index 52% rename from src/main/java/ru/nbch/credit_tracker/mapper/signal/SignalMapper.java rename to src/main/java/ru/nbch/credit_tracker/mapper/signal/UserPackageMapper.java index a61ccf8..d61211a 100644 --- a/src/main/java/ru/nbch/credit_tracker/mapper/signal/SignalMapper.java +++ b/src/main/java/ru/nbch/credit_tracker/mapper/signal/UserPackageMapper.java @@ -2,17 +2,14 @@ package ru.nbch.credit_tracker.mapper.signal; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; -import ru.nbch.credit_tracker.entities.dto.HitsData; import ru.nbch.credit_tracker.entities.dto.PackageData; -import ru.nbch.credit_tracker.entities.dto.SubjectData; import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest; -import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject; import java.time.LocalDateTime; import java.util.List; @Mapper -public interface SignalMapper { +public interface UserPackageMapper { boolean isPackageNotUnique(@Param("userId") String userId, @Param("packageName") String packageName); @@ -20,19 +17,11 @@ public interface SignalMapper { void deletePackage(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String newStatus, @Param("previousStatus") String previousStatus, @Param("deactivatedAt") LocalDateTime deactivatedAt); - Integer registerPackage(@Param("request") MonitoringRequest request, @Param("creadedAt") LocalDateTime creadedAt, @Param("status") String status); - - void registerSubjects(@Param("subjects") List subjects, @Param("packageId") Integer packageId); - - void insertPackage(@Param("request") MonitoringRequest request, @Param("creadedAt") LocalDateTime creadedAt, @Param("status") String status); - - void registerSubjectsFidAndDebts(@Param("id") Integer id, @Param("fid") Integer fid, @Param("flagDebt5000") Integer flagDebt5000, @Param("flag90") Integer flag90, @Param("calculatedAt") LocalDateTime calculatedAt); + Integer insertPackage(@Param("request") MonitoringRequest request, @Param("creadedAt") LocalDateTime creadedAt, @Param("status") String status); void setPackageStatus(@Param("packageId") Integer packageId, @Param("status") String status); - List findSubjectsData(@Param("packageId") Integer packageId); - - List findFullSubjectsData(@Param("packageId") Integer packageId); + void setPackageLastDownloadedReport(@Param("id") Integer id, @Param("fileName") String fileName); PackageData findPackageData(@Param("id") Integer id); @@ -40,9 +29,4 @@ public interface SignalMapper { List findPackagesByStatus(@Param("status") String status); - void setHits(@Param("hits") List hits); - - void updateSubjects(@Param("subjects") List subjects); - - void setPackageLastDownloadedReport(@Param("id") Integer id, @Param("fileName") String fileName); } 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 a8768ca..5cc0fb7 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/SignalService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/SignalService.java @@ -17,10 +17,12 @@ import ru.nbch.credit_tracker.entities.signal_package.Auth; import ru.nbch.credit_tracker.entities.signal_package.Person; import ru.nbch.credit_tracker.entities.signal_package.Signals; import ru.nbch.credit_tracker.enums.Status; -import ru.nbch.credit_tracker.mapper.signal.SignalMapper; import ru.nbch.credit_tracker.service.indic.FlagsService; import ru.nbch.credit_tracker.service.indic.PersonService; import ru.nbch.credit_tracker.service.indic.PhoneService; +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.utils.CTUtil; import java.text.DateFormat; @@ -39,7 +41,9 @@ public class SignalService { private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy"); private final CreditTrackerSettings config; - private final SignalMapper mapper; + private final HitsService hitsService; + private final UserPackageService userPackageService; + private final PhoneFidMapService phoneFidMapService; private final PhoneService phoneService; private final FlagsService flagsService; private final PersonService personService; @@ -47,12 +51,16 @@ public class SignalService { private final int batchSize = 10000; public SignalService(CreditTrackerSettings config, - SignalMapper mapper, + HitsService hitsService, + UserPackageService userPackageService, + PhoneFidMapService phoneFidMapService, PhoneService phoneService, FlagsService flagsService, PersonService personService) { this.config = config; - this.mapper = mapper; + this.hitsService = hitsService; + this.userPackageService = userPackageService; + this.phoneFidMapService = phoneFidMapService; this.phoneService = phoneService; this.flagsService = flagsService; this.personService = personService; @@ -60,21 +68,21 @@ public class SignalService { public boolean isPackageNotUnique(MonitoringRequest request) { String userId = request.getUserId(); - return mapper.isPackageNotUnique(userId.substring(0, 6), request.getPackageName()); + return userPackageService.isPackageNotUnique(userId.substring(0, 6), request.getPackageName()); } public Integer registerPackage(MonitoringRequest request) { - Integer packageId = mapper.registerPackage(request, LocalDateTime.now(), Status.PROCESSING.name()); + Integer packageId = userPackageService.insertPackage(request, LocalDateTime.now(), Status.PROCESSING); List subjects = request.getSubjects().getSubject(); for (int i = 0; i < subjects.size(); i += batchSize) { int end = Math.min(i + batchSize, subjects.size()); - mapper.registerSubjects(subjects.subList(i, end), packageId); + phoneFidMapService.registerSubjects(subjects.subList(i, end), packageId); } return packageId; } public List registerSubjectsFidAndDebts(Integer packageId) { - List subjects = mapper.findSubjectsData(packageId); + List subjects = phoneFidMapService.findSubjectsData(packageId); return updateFlags(subjects, packageId); } @@ -101,7 +109,7 @@ public class SignalService { int updateBatchSize = batchSize / 8; // 8 параметров на одну запись для обновления. Максимальное количество параметров ~65000 for (int j = 0; j < subjectToUpdate.size(); j += updateBatchSize) { int endIndex = Math.min(j + updateBatchSize, subjectToUpdate.size()); - mapper.updateSubjects(subjectToUpdate.subList(j, endIndex)); + phoneFidMapService.updateSubjects(subjectToUpdate.subList(j, endIndex)); } } @@ -109,15 +117,15 @@ public class SignalService { } public void rejectPackage(MonitoringRequest request) { - mapper.insertPackage(request, LocalDateTime.now(), Status.REJECTED.name()); + userPackageService.insertPackage(request, LocalDateTime.now(), Status.REJECTED); } public void setPackageStatus(Integer packageId, Status status) { - mapper.setPackageStatus(packageId, status.name()); + userPackageService.setPackageStatus(packageId, status); } public Signals buildSignals(Integer packageId, List fids) { - PackageData packageData = mapper.findPackageData(packageId); + PackageData packageData = userPackageService.findPackageData(packageId); Signals signals = new Signals(); signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы) signals.setId(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName()); // _ @@ -205,7 +213,7 @@ public class SignalService { activePackages.setStatus("OK"); activePackages.setMembercode(memberCode); Packages packages = new Packages(); - mapper.findPackageDataList(memberCode, Status.ON_MONITORING.name()).forEach(data -> { + userPackageService.findPackageDataList(memberCode, Status.ON_MONITORING).forEach(data -> { Package pack = new Package(); pack.setPackageName(data.getPackageName()); pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null); @@ -220,12 +228,12 @@ public class SignalService { } public boolean isPackageExists(String username, String packageName) { - return mapper.isPackageExists(username.substring(0, 6), packageName, Status.ON_MONITORING.name()); + return userPackageService.isPackageExists(username.substring(0, 6), packageName, Status.ON_MONITORING); } public MonitoringPackageDeleteResponse deletePackage(String username, String packageName) { LocalDateTime deactivatedAt = LocalDateTime.now(); - mapper.deletePackage(username.substring(0, 6), packageName, Status.DELETED.name(), Status.ON_MONITORING.name(), deactivatedAt); + userPackageService.deletePackage(username.substring(0, 6), packageName, Status.DELETED, Status.ON_MONITORING, deactivatedAt); MonitoringPackageDeleteResponse deleteResponse = new MonitoringPackageDeleteResponse(); deleteResponse.setStatus("Deleted"); @@ -235,18 +243,18 @@ public class SignalService { } public List findPackagesOnMonitoring() { - return mapper.findPackagesByStatus(Status.ON_MONITORING.name()); + return userPackageService.findPackagesByStatus(Status.ON_MONITORING); } public List findFullSubjectsData(Integer packageId) { - return mapper.findFullSubjectsData(packageId); + return phoneFidMapService.findFullSubjectsData(packageId); } public void setHits(List hits) { - mapper.setHits(hits); + hitsService.setHits(hits); } public void updateLastDownloadedReport(Integer id, String fileName) { - mapper.setPackageLastDownloadedReport(id, fileName); + userPackageService.setPackageLastDownloadedReport(id, fileName); } } diff --git a/src/main/java/ru/nbch/credit_tracker/service/signal/HitsService.java b/src/main/java/ru/nbch/credit_tracker/service/signal/HitsService.java new file mode 100644 index 0000000..654d885 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/service/signal/HitsService.java @@ -0,0 +1,21 @@ +package ru.nbch.credit_tracker.service.signal; + +import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.entities.dto.HitsData; +import ru.nbch.credit_tracker.mapper.signal.HitsMapper; + +import java.util.List; + +@Service +public class HitsService { + + private final HitsMapper mapper; + + public HitsService(HitsMapper mapper) { + this.mapper = mapper; + } + + public void setHits(List hits) { + mapper.setHits(hits); + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/service/signal/PhoneFidMapService.java b/src/main/java/ru/nbch/credit_tracker/service/signal/PhoneFidMapService.java new file mode 100644 index 0000000..f0050f7 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/service/signal/PhoneFidMapService.java @@ -0,0 +1,39 @@ +package ru.nbch.credit_tracker.service.signal; + +import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.entities.dto.SubjectData; +import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject; +import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper; + +import java.time.LocalDateTime; +import java.util.List; + +@Service +public class PhoneFidMapService { + + private final PhoneFidMapMapper mapper; + + public PhoneFidMapService(PhoneFidMapMapper mapper) { + this.mapper = mapper; + } + + public void registerSubjects(List subjects, Integer packageId) { + mapper.registerSubjects(subjects, packageId); + } + + public void registerSubjectsFidAndDebts(Integer id, Integer fid, Integer flagDebt5000, Integer flag90, LocalDateTime calculatedAt) { + mapper.registerSubjectsFidAndDebts(id, fid, flagDebt5000, flag90, calculatedAt); + } + + public List findSubjectsData(Integer packageId) { + return mapper.findSubjectsData(packageId); + } + + public List findFullSubjectsData( Integer packageId) { + return mapper.findFullSubjectsData(packageId); + } + + public void updateSubjects(List subjects) { + mapper.updateSubjects(subjects); + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/service/signal/UserPackageService.java b/src/main/java/ru/nbch/credit_tracker/service/signal/UserPackageService.java new file mode 100644 index 0000000..2bb1e22 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/service/signal/UserPackageService.java @@ -0,0 +1,56 @@ +package ru.nbch.credit_tracker.service.signal; + +import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.entities.dto.PackageData; +import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest; +import ru.nbch.credit_tracker.enums.Status; +import ru.nbch.credit_tracker.mapper.signal.UserPackageMapper; + +import java.time.LocalDateTime; +import java.util.List; + +@Service +public class UserPackageService { + + private final UserPackageMapper mapper; + + public UserPackageService(UserPackageMapper mapper) { + this.mapper = mapper; + } + + public boolean isPackageNotUnique(String userId, String packageName) { + return mapper.isPackageNotUnique(userId, packageName); + } + + public boolean isPackageExists(String userId, String packageName, Status status) { + return mapper.isPackageExists(userId, packageName, status.name()); + } + + public void deletePackage(String userId, String packageName, Status newStatus, Status previousStatus, LocalDateTime deactivatedAt) { + mapper.deletePackage(userId, packageName, newStatus.name(), previousStatus.name(), deactivatedAt); + } + + public Integer insertPackage(MonitoringRequest request, LocalDateTime creadedAt, Status status) { + return mapper.insertPackage(request, creadedAt, status.name()); + } + + public void setPackageStatus(Integer packageId, Status status) { + mapper.setPackageStatus(packageId, status.name()); + } + + public void setPackageLastDownloadedReport(Integer id, String fileName) { + mapper.setPackageLastDownloadedReport(id, fileName); + } + + public PackageData findPackageData(Integer id) { + return mapper.findPackageData(id); + } + + public List findPackageDataList(String userId, Status status) { + return mapper.findPackageDataList(userId, status.name()); + } + + public List findPackagesByStatus(Status status) { + return mapper.findPackagesByStatus(status.name()); + } +} diff --git a/src/main/resources/mybatis/mapper/signal/HitsMapper.xml b/src/main/resources/mybatis/mapper/signal/HitsMapper.xml new file mode 100644 index 0000000..0cda648 --- /dev/null +++ b/src/main/resources/mybatis/mapper/signal/HitsMapper.xml @@ -0,0 +1,16 @@ + + + + + + + INSERT INTO signals_hits (package_id, subject_id, signal_type, response_sent_at, report_file_name) + values + + (#{hit.packageId}, #{hit.subjectId}, #{hit.signalType}, #{hit.responseSentAt}, #{hit.reportFileName}) + + + + \ No newline at end of file diff --git a/src/main/resources/mybatis/mapper/signal/PhoneFidMapper.xml b/src/main/resources/mybatis/mapper/signal/PhoneFidMapper.xml new file mode 100644 index 0000000..07c498c --- /dev/null +++ b/src/main/resources/mybatis/mapper/signal/PhoneFidMapper.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + INSERT INTO signals_phone_fid_map (subject_id, phone, fid, package_id) + values + + (#{subject.id}, #{subject.clientId}, NULL, #{packageId}) + + + + + + + UPDATE signals_phone_fid_map + SET + package_id = #{subject.packageId}, + subject_id = #{subject.subjectId}, + phone = #{subject.phone}, + fid = #{subject.fid}, + flag_debt5000 = #{subject.flagDebt5000}, + flag_90_12 = #{subject.flag90days}, + calculated_at = #{subject.calculatedAt} + WHERE id = #{subject.id} + + + + + UPDATE signals_phone_fid_map + SET fid = #{fid}, flag_debt5000 = #{flagDebt5000}, flag_90_12 = #{flag90}, calculated_at = #{calculatedAt} + WHERE id = #{id} + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mybatis/mapper/signal/SignalMapper.xml b/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml similarity index 55% rename from src/main/resources/mybatis/mapper/signal/SignalMapper.xml rename to src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml index cfd25c2..e2dd615 100644 --- a/src/main/resources/mybatis/mapper/signal/SignalMapper.xml +++ b/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml @@ -3,18 +3,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - - + @@ -61,43 +50,6 @@ values (#{request.userId}, #{request.packageName}, #{creadedAt}, #{status}) - - INSERT INTO signals_phone_fid_map (subject_id, phone, fid, package_id) - values - - (#{subject.id}, #{subject.clientId}, NULL, #{packageId}) - - - - - INSERT INTO signals_hits (package_id, subject_id, signal_type, response_sent_at, report_file_name) - values - - (#{hit.packageId}, #{hit.subjectId}, #{hit.signalType}, #{hit.responseSentAt}, #{hit.reportFileName}) - - - - - - UPDATE signals_phone_fid_map - SET - package_id = #{subject.packageId}, - subject_id = #{subject.subjectId}, - phone = #{subject.phone}, - fid = #{subject.fid}, - flag_debt5000 = #{subject.flagDebt5000}, - flag_90_12 = #{subject.flag90days}, - calculated_at = #{subject.calculatedAt} - WHERE id = #{subject.id} - - - - - UPDATE signals_phone_fid_map - SET fid = #{fid}, flag_debt5000 = #{flagDebt5000}, flag_90_12 = #{flag90}, calculated_at = #{calculatedAt} - WHERE id = #{id} - - UPDATE signals_user_packages SET status = #{status} @@ -110,25 +62,6 @@ WHERE id = #{id} - - - - + - SELECT id, package_id, subject_id, diff --git a/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml b/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml index e2dd615..d2c3ed0 100644 --- a/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml +++ b/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml @@ -5,7 +5,7 @@ - + @@ -38,40 +38,34 @@ #{previousStatus} - - - INSERT INTO signals_user_packages (membercode, package_name, created_at, status) - values (#{request.userId}, #{request.packageName}, #{creadedAt}, #{status}) - - - + UPDATE signals_user_packages SET status = #{status} WHERE id = #{packageId} - + UPDATE signals_user_packages SET last_downloaded_report = #{fileName} WHERE id = #{id} - SELECT membercode, package_name FROM signals_user_packages WHERE id = #{id} LIMIT 1 - SELECT package_name, created_at FROM signals_user_packages WHERE membercode IS NOT NULL @@ -79,8 +73,8 @@ AND status = #{status} - SELECT id, membercode, package_name, created_at, last_downloaded_report FROM signals_user_packages WHERE status = #{status} From fb8da59b1b2ee17f4c53d98578a0bbb873c21f5e Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Tue, 1 Jul 2025 20:16:54 +0300 Subject: [PATCH 05/11] minor fix --- src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml b/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml index d2c3ed0..7a0cdc8 100644 --- a/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml +++ b/src/main/resources/mybatis/mapper/signal/UserPackageMapper.xml @@ -41,7 +41,7 @@ From 43897c6cbb599f512028b4977eec7baee4a8eaf8 Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Tue, 1 Jul 2025 20:23:01 +0300 Subject: [PATCH 06/11] Added SignalServerException; Update ExceptionUtils and GlobalExceptionHandler; Used ExceptionUtils in SignalFacade instead of throwing SignalErrorException --- .../config/rest/GlobalExceptionHandler.java | 34 +++---- .../exceptions/SignalClientException.java | 11 +-- .../exceptions/SignalErrorException.java | 29 ------ .../exceptions/SignalException.java | 17 ++++ .../exceptions/SignalServerException.java | 12 +++ .../credit_tracker/facade/SignalFacade.java | 99 +++++++++---------- .../utils/error/ExceptionUtils.java | 11 ++- .../utils/error/SimpleMessageResolver.java | 5 +- 8 files changed, 101 insertions(+), 117 deletions(-) delete mode 100644 src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java create mode 100644 src/main/java/ru/nbch/credit_tracker/exceptions/SignalException.java create mode 100644 src/main/java/ru/nbch/credit_tracker/exceptions/SignalServerException.java diff --git a/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java b/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java index c37e324..5f6ee25 100644 --- a/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java +++ b/src/main/java/ru/nbch/credit_tracker/config/rest/GlobalExceptionHandler.java @@ -1,39 +1,25 @@ package ru.nbch.credit_tracker.config.rest; -import java.nio.charset.Charset; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; -import ru.nbch.credit_tracker.entities.response.errors.CommonError; -import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError; -import ru.nbch.credit_tracker.entities.response.errors.MonitoringDownloadError; -import ru.nbch.credit_tracker.entities.response.errors.MonitoringError; -import ru.nbch.credit_tracker.entities.response.errors.MonitoringPackageDeleteError; -import ru.nbch.credit_tracker.entities.response.errors.MonitoringReportListError; +import ru.nbch.credit_tracker.entities.response.errors.*; import ru.nbch.credit_tracker.exceptions.SignalClientException; -import ru.nbch.credit_tracker.exceptions.SignalErrorException; +import ru.nbch.credit_tracker.exceptions.SignalException; import ru.nbch.credit_tracker.utils.error.SimpleMessageResolver; +import java.nio.charset.Charset; + @RestControllerAdvice public class GlobalExceptionHandler { private final SimpleMessageResolver messageResolver = new SimpleMessageResolver(); - @ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE) - public ResponseEntity handleInvalidUser(SignalErrorException ex) { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251"))); - if (ex.isUserError()) { - return new ResponseEntity<>(ex.getError(), headers, HttpStatus.BAD_REQUEST); - } else { - return new ResponseEntity<>(ex.getError(), headers, HttpStatus.INTERNAL_SERVER_ERROR); - } - } - @ExceptionHandler(value = SignalClientException.class, produces = MediaType.APPLICATION_XML_VALUE) - public ResponseEntity handleClientException(SignalClientException ex) { + @ExceptionHandler(value = SignalException.class, produces = MediaType.APPLICATION_XML_VALUE) + public ResponseEntity handleClientException(SignalException ex) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251"))); CommonError commonError = getCommonError(ex); @@ -41,10 +27,14 @@ public class GlobalExceptionHandler { commonError.setErrorCode(ex.getErrorMessage().getSubject().getErrorCode()); commonError.setErrorText(messageResolver.resolve(ex.getErrorMessage())); - return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST); + if (ex instanceof SignalClientException) { + return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST); + } else { + return new ResponseEntity<>(commonError, headers, HttpStatus.INTERNAL_SERVER_ERROR); + } } - private static CommonError getCommonError(SignalClientException ex) { + private static CommonError getCommonError(SignalException ex) { CommonError commonError; switch (ex.getErrorFormat()) { case MonitoringError -> commonError = new MonitoringError(); diff --git a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java index e6d85cb..ebf18f4 100644 --- a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java +++ b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalClientException.java @@ -5,14 +5,9 @@ import ru.nbch.credit_tracker.enums.EnumKeyMessage; import ru.nbch.credit_tracker.enums.XmlErrorFormat; @Getter -public class SignalClientException extends RuntimeException { +public class SignalClientException extends SignalException { - private final EnumKeyMessage errorMessage; - private final XmlErrorFormat errorFormat; - - public SignalClientException(EnumKeyMessage errorMessage, - XmlErrorFormat errorFormat) { - this.errorMessage = errorMessage; - this.errorFormat = errorFormat; + public SignalClientException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat) { + super(errorMessage, errorFormat); } } diff --git a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java deleted file mode 100644 index cad58f4..0000000 --- a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalErrorException.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.nbch.credit_tracker.exceptions; - -import lombok.Getter; -import ru.nbch.credit_tracker.entities.response.errors.CommonError; -import ru.nbch.credit_tracker.enums.SignalError; - -@Getter -public class SignalErrorException extends RuntimeException { - - private final boolean isUserError; - private final CommonError error; - - public SignalErrorException(SignalError signalError, String tag, CommonError error, boolean isUserError) { - this.isUserError = isUserError; - this.error = createErrorMessage(error, signalError, tag); - } - - private CommonError createErrorMessage(CommonError errorMessage, SignalError error, String tag) { - errorMessage.setStatus("error"); - errorMessage.setErrorCode(error.getCode()); - if (tag != null) { - errorMessage.setErrorText(error.getKey() + " " + tag); - } else { - errorMessage.setErrorText(error.getKey()); - } - return errorMessage; - } - -} diff --git a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalException.java b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalException.java new file mode 100644 index 0000000..38c9a1d --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalException.java @@ -0,0 +1,17 @@ +package ru.nbch.credit_tracker.exceptions; + +import lombok.Getter; +import ru.nbch.credit_tracker.enums.EnumKeyMessage; +import ru.nbch.credit_tracker.enums.XmlErrorFormat; + +@Getter +public class SignalException extends RuntimeException { + private final EnumKeyMessage errorMessage; + private final XmlErrorFormat errorFormat; + + public SignalException(EnumKeyMessage errorMessage, + XmlErrorFormat errorFormat) { + this.errorMessage = errorMessage; + this.errorFormat = errorFormat; + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/exceptions/SignalServerException.java b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalServerException.java new file mode 100644 index 0000000..46dd713 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/exceptions/SignalServerException.java @@ -0,0 +1,12 @@ +package ru.nbch.credit_tracker.exceptions; + +import ru.nbch.credit_tracker.enums.EnumKeyMessage; +import ru.nbch.credit_tracker.enums.XmlErrorFormat; + +public class SignalServerException extends SignalException { + + public SignalServerException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat) { + super(errorMessage, errorFormat); + } + +} diff --git a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java index 99091fa..ca1ffdc 100644 --- a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java +++ b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java @@ -12,7 +12,6 @@ import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActiveP 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.entities.response.active_packages.MonitoringActivePackagesResponse; -import ru.nbch.credit_tracker.entities.response.errors.*; import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse; @@ -21,7 +20,6 @@ import ru.nbch.credit_tracker.enums.SignalError; import ru.nbch.credit_tracker.enums.Status; import ru.nbch.credit_tracker.enums.XmlErrorFormat; import ru.nbch.credit_tracker.exceptions.SignalClientException; -import ru.nbch.credit_tracker.exceptions.SignalErrorException; import ru.nbch.credit_tracker.service.SignalService; import ru.nbch.credit_tracker.service.indic.PhoneService; import ru.nbch.credit_tracker.service.scoring.AuthorizationService; @@ -42,7 +40,8 @@ import java.util.concurrent.ExecutorService; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.excp; +import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp; +import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.serverExcp; @Slf4j @Service @@ -74,12 +73,8 @@ public class SignalFacade { public ResponseEntity setupMonitoring(MultipartFile file) { // первичные валидации - if (file.isEmpty()) { - throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); - } - - if (!isZipFile(file)) { - throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); + if (file.isEmpty() || !isZipFile(file)) { + throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError); } // Валидация Архива на количетсво файлов, размер и расширение @@ -90,10 +85,10 @@ public class SignalFacade { zipInputStream = new ZipInputStream(file.getInputStream()); Optional xmlFileEntry = ZipUtils.extractValidEntry(zipInputStream); if (xmlFileEntry.isEmpty()) { - throw excp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError); + throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError); } if (xmlFileEntry.get().getSize() > MAX_XML_FILE_SIZE) { - throw excp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError); + throw clientExcp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError); } zipInputStream.close(); @@ -108,7 +103,7 @@ public class SignalFacade { } log.error(e.getMessage(), e); //todo throw new SignalServerException(e); - throw excp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError); + throw clientExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError); } finally { if (zipInputStream != null) { try { @@ -124,7 +119,7 @@ public class SignalFacade { // валидация xml try { validateMonitoringRequest(monitoringRequest); - } catch (SignalErrorException e) { + } catch (SignalClientException e) { signalService.rejectPackage(monitoringRequest); throw e; } @@ -134,22 +129,22 @@ public class SignalFacade { AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword()); if (!authResult.isSuccess()) { signalService.rejectPackage(monitoringRequest); - throw new SignalErrorException(authResult.getError(), null, new MonitoringError(), true); + throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringError); } // проверка на уникальность пакета if (signalService.isPackageNotUnique(monitoringRequest)) { signalService.rejectPackage(monitoringRequest); - throw new SignalErrorException(SignalError.ERROR_007, null, new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_007, XmlErrorFormat.MonitoringError); } packageId = signalService.registerPackage(monitoringRequest); } catch (Exception e) { - if (e instanceof SignalErrorException) { - throw (SignalErrorException) e; + if (e instanceof SignalClientException) { + throw (SignalClientException) e; } log.error(e.getMessage(), e); - throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false); + throw serverExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError); } // в отдельном потоке запускаем поиск фидов и расчет флагов просрочек @@ -158,9 +153,9 @@ public class SignalFacade { return ResponseEntity.ok().body(new MonitoringResponse()); } - private void validateMonitoringRequest(MonitoringRequest request) throws SignalErrorException { + private void validateMonitoringRequest(MonitoringRequest request) throws SignalClientException { if (request == null) { - throw new SignalErrorException(SignalError.ERROR_011, null, new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_011, XmlErrorFormat.MonitoringError); } validateReruqredTags(request); @@ -168,44 +163,44 @@ public class SignalFacade { validateTagsTypes(request); } - private void validateReruqredTags(MonitoringRequest request) throws SignalErrorException { + private void validateReruqredTags(MonitoringRequest request) throws SignalClientException { if (request.getUserId() == null) { - throw new SignalErrorException(SignalError.ERROR_002, "UserId", new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "UserId"); } if (request.getPackageName() == null) { - throw new SignalErrorException(SignalError.ERROR_002, "PackageName", new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "PackageName"); } if (request.getPassword() == null) { - throw new SignalErrorException(SignalError.ERROR_002, "Password", new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Password"); } if (request.getSubjects() == null) { - throw new SignalErrorException(SignalError.ERROR_002, "Subjects", new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subjects"); } if (request.getSubjects().getSubject().isEmpty()) { - throw new SignalErrorException(SignalError.ERROR_002, "Subject", new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subject"); } } - private void validateTagsTypes(MonitoringRequest request) throws SignalErrorException { + private void validateTagsTypes(MonitoringRequest request) throws SignalClientException { if (!ValidationUtil.validatePackageName(request.getPackageName())) { - throw new SignalErrorException(SignalError.ERROR_008, null, new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_008, XmlErrorFormat.MonitoringError, "Subject"); } Set uniqueIds = new HashSet<>(); for (Subject subject : request.getSubjects().getSubject()) { if (!ValidationUtil.validatePhone(subject.getClientId())) { - throw new SignalErrorException(SignalError.ERROR_003, null, new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_003, XmlErrorFormat.MonitoringError); } if (!ValidationUtil.validateNPId(subject.getId())) { - throw new SignalErrorException(SignalError.ERROR_010, null, new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_010, XmlErrorFormat.MonitoringError); } // проверка на уникальность Id внутри одного пакета if (!uniqueIds.add(subject.getId())) { - throw new SignalErrorException(SignalError.ERROR_004, subject.getId(), new MonitoringError(), true); + throw clientExcp(SignalError.ERROR_004, XmlErrorFormat.MonitoringError, subject.getId()); } } } @@ -242,27 +237,27 @@ public class SignalFacade { try { AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword()); if (!authResult.isSuccess()) { - throw new SignalErrorException(authResult.getError(), null, new MonitoringActivePackagesError(), true); + throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringActivePackagesError); } MonitoringActivePackagesResponse response = signalService.findActivePackages(activePackagesRequest.getUserId()); if (response != null) { return ResponseEntity.ok(response); } else { - throw new SignalErrorException(SignalError.ERROR_015, null, new MonitoringActivePackagesError(), true); + throw clientExcp(SignalError.ERROR_015, XmlErrorFormat.MonitoringActivePackagesError); } } catch (Exception e) { - if (e instanceof SignalErrorException) { - throw (SignalErrorException) e; + if (e instanceof SignalClientException) { + throw (SignalClientException) e; } log.error(e.getMessage(), e); - throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringActivePackagesError(), false); + throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringActivePackagesError); } } public ResponseEntity deletePackage(String username, String packageName) { try { if (!signalService.isPackageExists(username, packageName)) { - throw new SignalErrorException(SignalError.ERROR_016, packageName, new MonitoringPackageDeleteError(), true); + throw clientExcp(SignalError.ERROR_016, XmlErrorFormat.MonitoringPackageDeleteError, packageName); } MonitoringPackageDeleteResponse response = signalService.deletePackage(username, packageName); @@ -270,18 +265,18 @@ public class SignalFacade { log.info("Package {} deleted", packageName); return ResponseEntity.ok(response); } catch (Exception e) { - if (e instanceof SignalErrorException) { - throw (SignalErrorException) e; + if (e instanceof SignalClientException) { + throw (SignalClientException) e; } log.error(e.getMessage(), e); - throw new SignalErrorException(SignalError.ERROR_017, null, new MonitoringPackageDeleteError(), false); + throw serverExcp(SignalError.ERROR_017, XmlErrorFormat.MonitoringPackageDeleteError); } } public ResponseEntity getReportList(String username, String packageName) { try { if (!signalService.isPackageExists(username, packageName)) { - throw new SignalErrorException(SignalError.ERROR_016, packageName, new MonitoringReportListError(), true); + throw clientExcp(SignalError.ERROR_016, XmlErrorFormat.MonitoringReportListError, packageName); } String memberCode = username.substring(0, 6); @@ -293,7 +288,7 @@ public class SignalFacade { MonitoringReportListResponse.Reports reports = new MonitoringReportListResponse.Reports(); File[] files = folder.listFiles(); if (files == null) { - throw new SignalErrorException(SignalError.ERROR_012, packageName, new MonitoringReportListError(), true); + throw clientExcp(SignalError.ERROR_012, XmlErrorFormat.MonitoringReportListError, packageName); } for (File file : files) { if (file.isFile() && file.getName().startsWith(filePrefix)) { @@ -302,7 +297,7 @@ public class SignalFacade { } if (reports.getReports().isEmpty()) { - throw new SignalErrorException(SignalError.ERROR_012, packageName, new MonitoringReportListError(), true); + throw clientExcp(SignalError.ERROR_012, XmlErrorFormat.MonitoringReportListError, packageName); } else { MonitoringReportListResponse response = new MonitoringReportListResponse(); response.setPackageName(packageName); @@ -311,14 +306,14 @@ public class SignalFacade { } } else { log.error("Пакет {} был найден в бд для memberCode {}, но ни одного архива не было найдено в папке {}", packageName, username, dirPath); - throw new SignalErrorException(SignalError.ERROR_013, packageName, new MonitoringReportListError(), true); + throw clientExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringReportListError, packageName); } } catch (Exception e) { - if (e instanceof SignalErrorException) { - throw (SignalErrorException) e; + if (e instanceof SignalClientException) { + throw (SignalClientException) e; } log.error(e.getMessage(), e); - throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringReportListError(), false); + throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringReportListError); } } @@ -334,15 +329,15 @@ public class SignalFacade { return ResponseEntity.ok().body(new FileUrlResource(file.getPath())); } } else { - throw new SignalErrorException(SignalError.ERROR_014, null, new MonitoringDownloadError(), true); + throw clientExcp(SignalError.ERROR_014, XmlErrorFormat.MonitoringDownloadError); } - throw new SignalErrorException(SignalError.ERROR_014, null, new MonitoringDownloadError(), true); + throw clientExcp(SignalError.ERROR_014, XmlErrorFormat.MonitoringDownloadError); } catch (Exception e) { - if (e instanceof SignalErrorException) { - throw (SignalErrorException) e; + if (e instanceof SignalClientException) { + throw (SignalClientException) e; } log.error(e.getMessage(), e); - throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringDownloadError(), false); + throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringDownloadError); } } } diff --git a/src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java b/src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java index 320aa87..a15457c 100644 --- a/src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java +++ b/src/main/java/ru/nbch/credit_tracker/utils/error/ExceptionUtils.java @@ -4,12 +4,15 @@ import ru.nbch.credit_tracker.enums.EnumKeyMessage; import ru.nbch.credit_tracker.enums.IEnumKeyCode; import ru.nbch.credit_tracker.enums.XmlErrorFormat; import ru.nbch.credit_tracker.exceptions.SignalClientException; +import ru.nbch.credit_tracker.exceptions.SignalServerException; public class ExceptionUtils { -// public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat) { -// return new SignalClientException(new EnumKeyMessage(enumKeyCode), xmlErrorFormat); -// } - public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) { + + public static SignalClientException clientExcp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) { return new SignalClientException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat); } + + public static SignalServerException serverExcp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) { + return new SignalServerException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat); + } } diff --git a/src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java b/src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java index c557a8a..d856415 100644 --- a/src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java +++ b/src/main/java/ru/nbch/credit_tracker/utils/error/SimpleMessageResolver.java @@ -1,12 +1,13 @@ package ru.nbch.credit_tracker.utils.error; -import java.util.Arrays; import ru.nbch.credit_tracker.enums.EnumKeyMessage; +import java.util.Arrays; + public class SimpleMessageResolver { public String resolve(EnumKeyMessage errorMessage) { if (errorMessage == null) return "null"; - return String.format("(%s) args %s", errorMessage.getSubject().getKey(), Arrays.toString(errorMessage.getArgs())); + return String.format("%s %s", errorMessage.getSubject().getKey(), Arrays.toString(errorMessage.getArgs())); } } From b4c44753984fff975ad732355620feb6557ed768 Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Wed, 2 Jul 2025 12:01:31 +0300 Subject: [PATCH 07/11] Moved monitoring request validation to ValidationUtil --- .../credit_tracker/facade/SignalFacade.java | 63 +------------------ .../credit_tracker/utils/ValidationUtil.java | 59 ++++++++++++++++- 2 files changed, 59 insertions(+), 63 deletions(-) diff --git a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java index ca1ffdc..57787e3 100644 --- a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java +++ b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java @@ -10,7 +10,6 @@ import org.springframework.web.multipart.MultipartFile; import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings; import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActivePackagesRequest; 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.entities.response.active_packages.MonitoringActivePackagesResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse; @@ -32,10 +31,8 @@ import ru.nbch.credit_tracker.utils.ZipUtils; import java.io.File; import java.io.IOException; -import java.util.HashSet; import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -102,15 +99,13 @@ public class SignalFacade { throw (SignalClientException) e; } log.error(e.getMessage(), e); - //todo throw new SignalServerException(e); - throw clientExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError); + throw serverExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError); } finally { if (zipInputStream != null) { try { zipInputStream.close(); } catch (IOException e) { - throw new RuntimeException(e); - //todo throw new SignalServerException(e); + throw serverExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError); } } } @@ -118,7 +113,7 @@ public class SignalFacade { // валидация xml try { - validateMonitoringRequest(monitoringRequest); + ValidationUtil.validateMonitoringRequest(monitoringRequest); } catch (SignalClientException e) { signalService.rejectPackage(monitoringRequest); throw e; @@ -153,58 +148,6 @@ public class SignalFacade { return ResponseEntity.ok().body(new MonitoringResponse()); } - private void validateMonitoringRequest(MonitoringRequest request) throws SignalClientException { - if (request == null) { - throw clientExcp(SignalError.ERROR_011, XmlErrorFormat.MonitoringError); - } - - validateReruqredTags(request); - - validateTagsTypes(request); - } - - private void validateReruqredTags(MonitoringRequest request) throws SignalClientException { - if (request.getUserId() == null) { - throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "UserId"); - } - - if (request.getPackageName() == null) { - throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "PackageName"); - } - - if (request.getPassword() == null) { - throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Password"); - } - - if (request.getSubjects() == null) { - throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subjects"); - } - - if (request.getSubjects().getSubject().isEmpty()) { - throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subject"); - } - } - - private void validateTagsTypes(MonitoringRequest request) throws SignalClientException { - if (!ValidationUtil.validatePackageName(request.getPackageName())) { - throw clientExcp(SignalError.ERROR_008, XmlErrorFormat.MonitoringError, "Subject"); - } - - Set uniqueIds = new HashSet<>(); - for (Subject subject : request.getSubjects().getSubject()) { - if (!ValidationUtil.validatePhone(subject.getClientId())) { - throw clientExcp(SignalError.ERROR_003, XmlErrorFormat.MonitoringError); - } - if (!ValidationUtil.validateNPId(subject.getId())) { - throw clientExcp(SignalError.ERROR_010, XmlErrorFormat.MonitoringError); - } - // проверка на уникальность Id внутри одного пакета - if (!uniqueIds.add(subject.getId())) { - throw clientExcp(SignalError.ERROR_004, XmlErrorFormat.MonitoringError, subject.getId()); - } - } - } - private void registerFidsAndDebts(Integer packageId, String packageName) { executor.execute(() -> { try { diff --git a/src/main/java/ru/nbch/credit_tracker/utils/ValidationUtil.java b/src/main/java/ru/nbch/credit_tracker/utils/ValidationUtil.java index e37458a..3695db8 100644 --- a/src/main/java/ru/nbch/credit_tracker/utils/ValidationUtil.java +++ b/src/main/java/ru/nbch/credit_tracker/utils/ValidationUtil.java @@ -1,29 +1,82 @@ package ru.nbch.credit_tracker.utils; +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.enums.SignalError; +import ru.nbch.credit_tracker.enums.XmlErrorFormat; +import ru.nbch.credit_tracker.exceptions.SignalClientException; + +import java.util.HashSet; +import java.util.Set; import java.util.regex.Pattern; +import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp; + public class ValidationUtil { private static String phoneRegex = "^\\d{9}$"; private static String packageNameRegex = "^[A-Z0-9_]{1,22}$"; private static String npIdRegex = "^\\S{1,36}$"; + public static void validateMonitoringRequest(MonitoringRequest request) throws SignalClientException { + if (request == null) { + throw clientExcp(SignalError.ERROR_011, XmlErrorFormat.MonitoringError); + } - public static boolean validatePhone(String input) { + if (request.getUserId() == null) { + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "UserId"); + } + + if (request.getPackageName() == null) { + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "PackageName"); + } + + if (request.getPassword() == null) { + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Password"); + } + + if (request.getSubjects() == null) { + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subjects"); + } + + if (request.getSubjects().getSubject().isEmpty()) { + throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subject"); + } + + if (!validatePackageName(request.getPackageName())) { + throw clientExcp(SignalError.ERROR_008, XmlErrorFormat.MonitoringError, "Subject"); + } + + Set uniqueIds = new HashSet<>(); + for (Subject subject : request.getSubjects().getSubject()) { + if (!validatePhone(subject.getClientId())) { + throw clientExcp(SignalError.ERROR_003, XmlErrorFormat.MonitoringError); + } + if (!validateNPId(subject.getId())) { + throw clientExcp(SignalError.ERROR_010, XmlErrorFormat.MonitoringError); + } + // проверка на уникальность Id внутри одного пакета + if (!uniqueIds.add(subject.getId())) { + throw clientExcp(SignalError.ERROR_004, XmlErrorFormat.MonitoringError, subject.getId()); + } + } + } + + private static boolean validatePhone(String input) { if(input == null) { return false; } return Pattern.matches(phoneRegex, input); } - public static boolean validatePackageName(String input) { + private static boolean validatePackageName(String input) { if(input == null) { return false; } return Pattern.matches(packageNameRegex, input); } - public static boolean validateNPId(String input) { + private static boolean validateNPId(String input) { if(input == null) { return false; } From 3358a8ee214aa2c1deac52be80fca43ff6c0efa0 Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Wed, 2 Jul 2025 12:15:43 +0300 Subject: [PATCH 08/11] Get rid of XmlUtilService; Created beans of IXmlProcessor and StaxXmlProcessor --- .../xml/XmlConfig.java} | 45 +++++-------------- .../credit_tracker/facade/SignalFacade.java | 10 ++--- .../service/MonitoringService.java | 13 +++--- .../service/signal/SignalRestService.java | 28 +++++------- 4 files changed, 31 insertions(+), 65 deletions(-) rename src/main/java/ru/nbch/credit_tracker/{service/xml/jaxb/XmlUtilService.java => config/xml/XmlConfig.java} (51%) diff --git a/src/main/java/ru/nbch/credit_tracker/service/xml/jaxb/XmlUtilService.java b/src/main/java/ru/nbch/credit_tracker/config/xml/XmlConfig.java similarity index 51% rename from src/main/java/ru/nbch/credit_tracker/service/xml/jaxb/XmlUtilService.java rename to src/main/java/ru/nbch/credit_tracker/config/xml/XmlConfig.java index 77253e7..263b036 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/xml/jaxb/XmlUtilService.java +++ b/src/main/java/ru/nbch/credit_tracker/config/xml/XmlConfig.java @@ -1,8 +1,8 @@ -package ru.nbch.credit_tracker.service.xml.jaxb; +package ru.nbch.credit_tracker.config.xml; import jakarta.xml.bind.JAXBException; -import org.springframework.stereotype.Service; -import org.xml.sax.SAXException; +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.response.errors.MonitoringError; import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.MonitoringSignalResponse; @@ -10,33 +10,22 @@ import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadRe import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport; import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse; import ru.nbch.credit_tracker.entities.signal_package.Signals; +import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor; +import ru.nbch.credit_tracker.service.xml.jaxb.XmlProcessorImplAnyClasses; import ru.nbch.credit_tracker.service.xml.stax.SgnlReportStatusStaxReader; 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 javax.xml.XMLConstants; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; -import javax.xml.transform.stax.StAXSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; -import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; +@Configuration +public class XmlConfig { -@Service -public class XmlUtilService { - - //сделать бином - public IXmlProcessor createJaxbProcessor() throws JAXBException { + @Bean + public IXmlProcessor xmlProcessor() throws JAXBException { return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"), // unmarshalling classes MonitoringRequest.class, @@ -49,24 +38,10 @@ public class XmlUtilService { MonitoringSignalResponse.class); } + @Bean public StaxXmlProcessor staxXmlProcessor() { List> staxReader = new ArrayList<>(); staxReader.add(new SgnlReportStatusStaxReader()); return new XmlProcessorStaxImpl(staxReader); } - - public void validateXMLByXSD(InputStream xmlStream, String xsdPath) throws IOException, XMLStreamException, SAXException { - SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI); - Schema schema = sf.newSchema(new File(xsdPath)); - - XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); - xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); - xmlInputFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); - xmlInputFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); - - Validator validator = schema.newValidator(); - XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlStream); - validator.validate(new StAXSource(xmlStreamReader)); - } - } diff --git a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java index 57787e3..e4ca4ce 100644 --- a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java +++ b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java @@ -24,7 +24,6 @@ import ru.nbch.credit_tracker.service.indic.PhoneService; import ru.nbch.credit_tracker.service.scoring.AuthorizationService; import ru.nbch.credit_tracker.service.signal.SignalRestService; import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor; -import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService; import ru.nbch.credit_tracker.utils.CTUtil; import ru.nbch.credit_tracker.utils.ValidationUtil; import ru.nbch.credit_tracker.utils.ZipUtils; @@ -49,7 +48,7 @@ public class SignalFacade { private final AuthorizationService authorizationService; private final SignalService signalService; private final SignalRestService signalRestService; - private final XmlUtilService xmlUtilService; + private final IXmlProcessor xmlProcessor; private final ExecutorService executor; @@ -58,13 +57,13 @@ public class SignalFacade { AuthorizationService authorizationService, SignalService signalService, SignalRestService signalRestService, - XmlUtilService xmlUtilService, + IXmlProcessor xmlProcessor, @Qualifier("executorService") ExecutorService executor) { this.config = config; this.authorizationService = authorizationService; this.signalService = signalService; this.signalRestService = signalRestService; - this.xmlUtilService = xmlUtilService; + this.xmlProcessor = xmlProcessor; this.executor = executor; } @@ -92,8 +91,7 @@ public class SignalFacade { zipInputStream = new ZipInputStream(file.getInputStream()); zipInputStream.getNextEntry(); - IXmlProcessor processor = xmlUtilService.createJaxbProcessor(); - monitoringRequest = processor.read(zipInputStream, MonitoringRequest.class); + monitoringRequest = xmlProcessor.read(zipInputStream, MonitoringRequest.class); } catch (Exception e) { if (e instanceof SignalClientException) { throw (SignalClientException) e; 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 c777b27..cb1b905 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/MonitoringService.java @@ -14,7 +14,6 @@ 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.jaxb.XmlUtilService; import ru.nbch.credit_tracker.utils.CTUtil; import java.io.ByteArrayInputStream; @@ -36,16 +35,16 @@ public class MonitoringService { private final SignalRestService signalRestService; private final SignalService signalService; - private final XmlUtilService xmlUtilService; + private final IXmlProcessor xmlProcessor; private final CreditTrackerSettings config; public MonitoringService(SignalRestService signalRestService, SignalService signalService, - XmlUtilService xmlUtilService, + IXmlProcessor xmlProcessor, CreditTrackerSettings config) { this.signalRestService = signalRestService; this.signalService = signalService; - this.xmlUtilService = xmlUtilService; + this.xmlProcessor = xmlProcessor; this.config = config; } @@ -160,8 +159,7 @@ public class MonitoringService { folder.mkdir(); } - IXmlProcessor processor = xmlUtilService.createJaxbProcessor(); - String xmlStr = processor.asString(response, true); + String xmlStr = xmlProcessor.asString(response, true); byte[] xmlBytes = xmlStr.getBytes(Charset.forName("windows-1251")); try (FileOutputStream fos = new FileOutputStream(filePath + fileName + ".zip"); @@ -206,8 +204,7 @@ public class MonitoringService { OnlineDownloadReport report; try (GZIPInputStream zipInputStream = new GZIPInputStream(new ByteArrayInputStream(archive))) { - IXmlProcessor processor = xmlUtilService.createJaxbProcessor(); - report = processor.read(zipInputStream, OnlineDownloadReport.class); + report = xmlProcessor.read(zipInputStream, OnlineDownloadReport.class); } catch (Exception e) { log.error(e.getMessage(), e); 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 33a0cb8..b53ee2b 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 @@ -15,7 +15,6 @@ import ru.nbch.credit_tracker.entities.response.external_errors.SgnlReport; import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport; import ru.nbch.credit_tracker.entities.signal_package.Signals; import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor; -import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService; import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor; import java.io.ByteArrayOutputStream; @@ -35,14 +34,17 @@ public class SignalRestService { private static String DOWNLOAD_REPORT_URI = "onlinedownload"; private final RestTemplate restTemplate; - private final XmlUtilService xmlUtilService; + private final IXmlProcessor xmlProcessor; + private final StaxXmlProcessor staxProcessor; private final String authToken; public SignalRestService(@Qualifier(value = "restTemplate") RestTemplate restTemplate, - XmlUtilService xmlUtilService, + IXmlProcessor xmlProcessor, + StaxXmlProcessor staxProcessor, CreditTrackerSettings config) throws Exception { this.restTemplate = restTemplate; - this.xmlUtilService = xmlUtilService; + this.xmlProcessor = xmlProcessor; + this.staxProcessor = staxProcessor; this.authToken = buildToken(config.getSignalsToken(), config.getSignalsuser()); } @@ -64,8 +66,7 @@ public class SignalRestService { // good response return true; } else if (response.getStatusCode().value() == 200 && response.getBody() != null) { - StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor(); - SgnlReport error = staxXmlProcessor.read(response.getBody(), SgnlReport.class); + SgnlReport error = staxProcessor.read(response.getBody(), SgnlReport.class); if (error.getError().getDescription() != null) { log.error("Ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", error.getError().getDescription()); } else { @@ -92,8 +93,7 @@ public class SignalRestService { ); String answer = response.getBody(); - StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor(); - SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class); + SgnlReport error = staxProcessor.read(answer, SgnlReport.class); if (error.getError().getDescription() != null) { log.error("Ошибка при удалении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription()); } @@ -116,15 +116,13 @@ public class SignalRestService { String answer = response.getBody(); - StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor(); - SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class); + SgnlReport error = staxProcessor.read(answer, SgnlReport.class); if (error.getError().getDescription() != null) { log.error("Ошибка при получении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription()); return null; } try { - IXmlProcessor processor = xmlUtilService.createJaxbProcessor(); - return processor.read(answer, SgnlOnlineReport.class); + return xmlProcessor.read(answer, SgnlOnlineReport.class); } catch (Exception e) { log.error("Ошибка при получении пакета из сервиса НБКИ. Код ошибки: {} packCode={}", response.getStatusCode().value(), packCode); return null; @@ -148,8 +146,7 @@ public class SignalRestService { byte[] answer = response.getBody(); if (isXmlError(response.getBody())) { - StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor(); - SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class); + SgnlReport error = staxProcessor.read(answer, SgnlReport.class); if (error.getError().getDescription() != null) { log.error("Ошибка при скачивание отчета. fNameReport={}. Описание: {}", reportName, error.getError().getDescription()); return null; @@ -175,8 +172,7 @@ public class SignalRestService { } private Resource compressFile(Signals signals) throws Exception { - IXmlProcessor processor = xmlUtilService.createJaxbProcessor(); - String requestData = processor.asString(signals, false); + String requestData = xmlProcessor.asString(signals, false); ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); try (GZIPOutputStream gzipStream = new GZIPOutputStream(byteStream)) { From bd2ad04a6574bf468c4f6e4972d86c891004300d Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Wed, 2 Jul 2025 13:09:33 +0300 Subject: [PATCH 09/11] Added tests for entry extracting and monitoring request validation --- .../nbch/credit_tracker/utils/UtilTest.java | 156 ++++++++++++++++++ .../monitoring_request/directory_request.zip | Bin 0 -> 154 bytes .../monitoring_request/empty_request.zip | 0 .../monitoring_request/invalid_id_request.zip | Bin 0 -> 415 bytes .../invalid_phone_request.zip | Bin 0 -> 422 bytes .../monitoring_request/invalid_xml.zip | Bin 0 -> 312 bytes .../monitoring_request/many_files_request.zip | Bin 0 -> 1134 bytes .../no_required_tag_request.zip | Bin 0 -> 376 bytes .../no_unique_ids_request.zip | Bin 0 -> 417 bytes .../monitoring_request/txt_request.zip | Bin 0 -> 156 bytes .../monitoring_request/valid_request.zip | Bin 0 -> 390 bytes 11 files changed, 156 insertions(+) create mode 100644 src/test/java/ru/nbch/credit_tracker/utils/UtilTest.java create mode 100644 src/test/resources/monitoring_request/directory_request.zip create mode 100644 src/test/resources/monitoring_request/empty_request.zip create mode 100644 src/test/resources/monitoring_request/invalid_id_request.zip create mode 100644 src/test/resources/monitoring_request/invalid_phone_request.zip create mode 100644 src/test/resources/monitoring_request/invalid_xml.zip create mode 100644 src/test/resources/monitoring_request/many_files_request.zip create mode 100644 src/test/resources/monitoring_request/no_required_tag_request.zip create mode 100644 src/test/resources/monitoring_request/no_unique_ids_request.zip create mode 100644 src/test/resources/monitoring_request/txt_request.zip create mode 100644 src/test/resources/monitoring_request/valid_request.zip diff --git a/src/test/java/ru/nbch/credit_tracker/utils/UtilTest.java b/src/test/java/ru/nbch/credit_tracker/utils/UtilTest.java new file mode 100644 index 0000000..c7dc696 --- /dev/null +++ b/src/test/java/ru/nbch/credit_tracker/utils/UtilTest.java @@ -0,0 +1,156 @@ +package ru.nbch.credit_tracker.utils; + +import jakarta.xml.bind.JAXBException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +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.enums.SignalError; +import ru.nbch.credit_tracker.exceptions.SignalClientException; +import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor; +import ru.nbch.credit_tracker.service.xml.jaxb.XmlProcessorImplAnyClasses; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.Optional; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +@SpringBootTest(classes = {UtilTest.TestConfig.class}) +public class UtilTest { + + private final IXmlProcessor xmlProcessor; + + @Autowired + public UtilTest(IXmlProcessor xmlProcessor) { + this.xmlProcessor = xmlProcessor; + } + + @Configuration + public static class TestConfig { + @Bean + public IXmlProcessor xmlProcessor() throws JAXBException { + return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"), + MonitoringRequest.class); + } + } + + private static Stream entryTestCases() { + return Stream.of( + Arguments.of( + "/monitoring_request/valid_request.zip", + true + ), + Arguments.of( + "/monitoring_request/directory_request.zip", + false + ) + , + Arguments.of( + "/monitoring_request/empty_request.zip", + false + ) + , + Arguments.of( + "/monitoring_request/many_files_request.zip", + false + ) + , + Arguments.of( + "/monitoring_request/txt_request.zip", + false + ) + ); + } + + @ParameterizedTest(name = "[{index}] PATH: [ {0} ] EXPECTED: [ {1} ]") + @MethodSource("entryTestCases") + void testExtractEntryFromZip(String path, boolean expected) { + ZipInputStream zipInputStream; + Optional xmlFileEntry; + try { + zipInputStream = new ZipInputStream(getClass().getResourceAsStream(path)); + xmlFileEntry = ZipUtils.extractValidEntry(zipInputStream); + Assertions.assertEquals(expected, xmlFileEntry.isPresent()); + zipInputStream.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static Stream validationTestCases() { + return Stream.of( + Arguments.of( + "/monitoring_request/valid_request.zip", + null, + null + ), + Arguments.of( + "/monitoring_request/invalid_xml.zip", + SignalError.ERROR_011, + Collections.emptyList().toArray(new Object[0]) + ) + , + Arguments.of( + "/monitoring_request/no_required_tag_request.zip", + SignalError.ERROR_002, + new Object[]{"Password"} + ), + Arguments.of( + "/monitoring_request/invalid_phone_request.zip", + SignalError.ERROR_003, + Collections.emptyList().toArray(new Object[0]) + ), + Arguments.of( + "/monitoring_request/invalid_id_request.zip", + SignalError.ERROR_010, + Collections.emptyList().toArray(new Object[0]) + ), + Arguments.of( + "/monitoring_request/no_unique_ids_request.zip", + SignalError.ERROR_004, + new Object[]{"abc125"} + ) + ); + } + + @ParameterizedTest(name = "[{index}] PATH: [ {0} ] SIGNALERROR: [ {1} ] ARGS [ {2} ]") + @MethodSource("validationTestCases") + void testMonitoringRequestValidation(String path, SignalError signalError, Object[] args) { + ZipInputStream zipInputStream = null; + MonitoringRequest monitoringRequest; + try { + zipInputStream = new ZipInputStream(getClass().getResourceAsStream(path)); + zipInputStream.getNextEntry(); + monitoringRequest = xmlProcessor.read(zipInputStream, MonitoringRequest.class); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + if (zipInputStream != null) { + try { + zipInputStream.close(); + } catch (IOException e) { + throw new RuntimeException(); + } + } + } + + SignalClientException ex = null; + try { + ValidationUtil.validateMonitoringRequest(monitoringRequest); + } catch (SignalClientException e) { + ex = e; + } + if (ex != null) { + Assertions.assertEquals(signalError, ex.getErrorMessage().getSubject()); + Assertions.assertArrayEquals(args, ex.getErrorMessage().getArgs()); + } + } +} diff --git a/src/test/resources/monitoring_request/directory_request.zip b/src/test/resources/monitoring_request/directory_request.zip new file mode 100644 index 0000000000000000000000000000000000000000..7ad23ba857b6fea2c7e0e355e5acf2faeba850c3 GIT binary patch literal 154 zcmWIWW@Zs#0D*~dkD|Z~D8U7!Q!Jfm_2z^`(3Scot h1__3s&ZW!rUf*VfDuPo1-mGjO4kHl80BH@d3;?cJ6W9O% literal 0 HcmV?d00001 diff --git a/src/test/resources/monitoring_request/empty_request.zip b/src/test/resources/monitoring_request/empty_request.zip new file mode 100644 index 0000000..e69de29 diff --git a/src/test/resources/monitoring_request/invalid_id_request.zip b/src/test/resources/monitoring_request/invalid_id_request.zip new file mode 100644 index 0000000000000000000000000000000000000000..0de7ae4ebac795fd1eb48b1a8fe2ade2ef3ea4fd GIT binary patch literal 415 zcmWIWW@Zs#U|`^2=*)N&b-?SY$y*@Lh>3wg3`l3@l_ln6ro;nLQEFjnYH^8PMQ+aA ziPrvy4MbYgKWQ&AXqMkNTWROI1>8KY9ql2@w0zfTIcIm@Q2kSr=d?)2lilWq-Se3G zx|L7Qe-x;9e%iaayCwFr3S0D!OE>;1t?bo}eY;*_x=!RPkF|464~9zE9lp+4b0JV> zwK@M)=argEb2cB8b9eoB#;pF--u1DeuNt&PUZ%_!o&Qr#?z8fXufM;&`&L@IKeebY z)%jA`zBy&`0W9}B9L-i;-ElqjvdF>6{B?Y6IS$R~nv0vdXDaQzUg*I->)5m1O@)R> zpRN?CcxZg5+jE6XdywVynI4hf^k3x2R9)U$te$)1! literal 0 HcmV?d00001 diff --git a/src/test/resources/monitoring_request/invalid_phone_request.zip b/src/test/resources/monitoring_request/invalid_phone_request.zip new file mode 100644 index 0000000000000000000000000000000000000000..f32304894634f65193fa43caa088df52d62d060f GIT binary patch literal 422 zcmWIWW@Zs#U|`^2xSa7Q%Hc7G$vYs=jER9k5=dv}l_ln6ro8-*vu*oByZWmruF1)t@)* zh&Hx7x=Arpdw&0HevPL5BMQ=2v+ii$7wK8v^7QEPOUuSa%xk(qx$0uuh-4B&Qxw&9+vXt^kVq{Z$>72 z23*0U0t_e+Pymy70*wo*gpomlLAvtve~Z_*8KHXMRDd@t8;HXQgxNq^6|4dPJdd7P literal 0 HcmV?d00001 diff --git a/src/test/resources/monitoring_request/invalid_xml.zip b/src/test/resources/monitoring_request/invalid_xml.zip new file mode 100644 index 0000000000000000000000000000000000000000..25fc1766e7819b937f36b42df2951c1c5b15895f GIT binary patch literal 312 zcmWIWW@Zs#U|`^2&`Wz1Wqq-5)9u9^k>#Z+GW?Z*6C&`BiFjWd5p> zTeCcwzFTxo)m(EW&E8Whcgfm23>?iVT1xx2xK&5DeR7?9?o_4VQN#M;RWTlohHYP^ zt~1NT9@!?=yZUR^&-=7k==9ld9}`Vy=Qs9R?8<#Lb^Y_ZyS4VL ze%Qs!%9s9hHS?N7%0Dz3AK5iSOqrng*?& z=ALz<*zu^<#H`Do^nz4>CH>=kdL+BOPa;dzcMF`_tUEZXQXWs>^SS1uB~2p zwy5@3rrx|-u@yV&6)vb4BZCCPdCU5l=C5xvLKVTO S0B=?{5Qh;6V}LXpSOoxU^@e)@ literal 0 HcmV?d00001 diff --git a/src/test/resources/monitoring_request/no_unique_ids_request.zip b/src/test/resources/monitoring_request/no_unique_ids_request.zip new file mode 100644 index 0000000000000000000000000000000000000000..ee9204970b1392e35382fd18f4dcf21fff2a790a GIT binary patch literal 417 zcmWIWW@Zs#U|`^2u*rB7^{u~t=}REbn2CWw5=iIe$Cu`17M7;QXQmX#7o`GO#U*+b zxjAbmTKgY15NS>Sq`m0P1NWRDmFuDU>T3 zJ*W8Z&!uX+&szO!KP8=hoOAbLPo8ZBOE<1A43duCb?d&7UZl~*iL)%Tn^qgtwC~sb zv0$-9SiIb-=|RC>H*5NA`?_S#nAM-&yFNDbRfD$3%ar+|`+su9edc{}^ZTQhAB%tO zNhoSbb-ol6oh`?qIbCycQ+Ks%)q3WMeIdIccUxWSQ>^=j-R@ZV^0etzGnF|67223#Se0t_P% rPymy7!ix*4gpomlA-<+2+~W0ZMyMV*72wUv2I4RRVK$If0IL81cv6~v literal 0 HcmV?d00001 diff --git a/src/test/resources/monitoring_request/txt_request.zip b/src/test/resources/monitoring_request/txt_request.zip new file mode 100644 index 0000000000000000000000000000000000000000..b635e012ec8c0577403f5cda9c34160f958b9bd4 GIT binary patch literal 156 zcmWIWW@h1H0D;Q5M^Rt~l;8%^MX80Qsl_FFB^4zB-i%E447il4Ks6~qX(WwY3=ly^ h1__2<>kr*}uWvI#Rl%tMZ&o%ChY<*4fwU%A1^^OF6zc#0 literal 0 HcmV?d00001 diff --git a/src/test/resources/monitoring_request/valid_request.zip b/src/test/resources/monitoring_request/valid_request.zip new file mode 100644 index 0000000000000000000000000000000000000000..e1ac937be152015ee36765e2f09b281a87fb1d38 GIT binary patch literal 390 zcmWIWW@Zs#U|`^2cvg2WimCS||0^KRn2CXb8%P(W7M7+Km*`dG=FFYwn14t?qV4?a z^%+&=9|AYbQb_x}h<$o$apycA-6I<`k2Jlm`}ZPimG>>#Z+GW?Z*6C&`BiFjWd5p> zTeCcwzFTxo)m(EW&E8Whcgfm23>?iVT1xx2xK&5DeR7?9?o_4VQN#M;RWTlohHYP^ zt~1NT9@!?=yZUR^&-=7k==9ld9}`Vy=Qs9R?8<#Lb^Y_ZyS4VL ze%Qs!%9s9hH Date: Wed, 2 Jul 2025 13:41:03 +0300 Subject: [PATCH 10/11] Refactored findActivePackages and deletePackage methods --- .../credit_tracker/facade/SignalFacade.java | 29 +++++++++++++++-- .../credit_tracker/service/SignalService.java | 32 ++----------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java index e4ca4ce..bc17fdc 100644 --- a/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java +++ b/src/main/java/ru/nbch/credit_tracker/facade/SignalFacade.java @@ -8,9 +8,12 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings; +import ru.nbch.credit_tracker.entities.dto.UserPackage; import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActivePackagesRequest; import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest; import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse; +import ru.nbch.credit_tracker.entities.response.active_packages.Package; +import ru.nbch.credit_tracker.entities.response.active_packages.Packages; import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse; import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse; @@ -30,6 +33,7 @@ import ru.nbch.credit_tracker.utils.ZipUtils; import java.io.File; import java.io.IOException; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutorService; @@ -180,8 +184,20 @@ public class SignalFacade { if (!authResult.isSuccess()) { throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringActivePackagesError); } - MonitoringActivePackagesResponse response = signalService.findActivePackages(activePackagesRequest.getUserId()); - if (response != null) { + List activePackages = signalService.findActivePackages(activePackagesRequest.getUserId()); + + if (!activePackages.isEmpty()) { + MonitoringActivePackagesResponse response = new MonitoringActivePackagesResponse(); + response.setStatus("OK"); + response.setMembercode(activePackagesRequest.getUserId().substring(0, 6)); + Packages packages = new Packages(); + activePackages.forEach(data -> { + Package pack = new Package(); + pack.setPackageName(data.getPackageName()); + pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null); + packages.getPackages().add(pack); + }); + response.setPackages(packages); return ResponseEntity.ok(response); } else { throw clientExcp(SignalError.ERROR_015, XmlErrorFormat.MonitoringActivePackagesError); @@ -200,7 +216,14 @@ public class SignalFacade { if (!signalService.isPackageExists(username, packageName)) { throw clientExcp(SignalError.ERROR_016, XmlErrorFormat.MonitoringPackageDeleteError, packageName); } - MonitoringPackageDeleteResponse response = signalService.deletePackage(username, packageName); + + LocalDateTime deactivatedAt = LocalDateTime.now(); + signalService.deletePackage(username, packageName, deactivatedAt); + + MonitoringPackageDeleteResponse response = new MonitoringPackageDeleteResponse(); + response.setStatus("Deleted"); + response.setPackageName(packageName); + response.setDeactivatedAt(deactivatedAt.toString()); signalRestService.deletePackage(username, packageName); log.info("Package {} deleted", packageName); 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 b020607..f12367f 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/SignalService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/SignalService.java @@ -9,10 +9,6 @@ import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; import ru.nbch.credit_tracker.entities.dto.UserPackage; 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.entities.response.active_packages.MonitoringActivePackagesResponse; -import ru.nbch.credit_tracker.entities.response.active_packages.Package; -import ru.nbch.credit_tracker.entities.response.active_packages.Packages; -import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse; import ru.nbch.credit_tracker.entities.signal_package.Auth; import ru.nbch.credit_tracker.entities.signal_package.Person; import ru.nbch.credit_tracker.entities.signal_package.Signals; @@ -218,38 +214,16 @@ public class SignalService { } - public MonitoringActivePackagesResponse findActivePackages(String userId) { - MonitoringActivePackagesResponse activePackages = new MonitoringActivePackagesResponse(); - activePackages.setStatus("OK"); - activePackages.setMembercode(userId.substring(0, 6)); - Packages packages = new Packages(); - userPackageService.findUserPackages(userId, Status.ON_MONITORING).forEach(data -> { - Package pack = new Package(); - pack.setPackageName(data.getPackageName()); - pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null); - packages.getPackages().add(pack); - }); - activePackages.setPackages(packages); - - if (packages.getPackages() == null || packages.getPackages().isEmpty()) { - return null; - } - return activePackages; + public List findActivePackages(String userId) { + return userPackageService.findUserPackages(userId, Status.ON_MONITORING); } public boolean isPackageExists(String username, String packageName) { return userPackageService.isPackageExists(username, packageName, Status.ON_MONITORING); } - public MonitoringPackageDeleteResponse deletePackage(String username, String packageName) { - LocalDateTime deactivatedAt = LocalDateTime.now(); + public void deletePackage(String username, String packageName, LocalDateTime deactivatedAt) { userPackageService.deletePackage(username, packageName, Status.DELETED, Status.ON_MONITORING, deactivatedAt); - - MonitoringPackageDeleteResponse deleteResponse = new MonitoringPackageDeleteResponse(); - deleteResponse.setStatus("Deleted"); - deleteResponse.setPackageName(packageName); - deleteResponse.setDeactivatedAt(deactivatedAt.toString()); - return deleteResponse; } public List findPackagesOnMonitoring() { From 79259170bc505581c27d8a8c6a38dd586bdd0d7d Mon Sep 17 00:00:00 2001 From: Mikhail Trofimov Date: Wed, 2 Jul 2025 15:44:49 +0300 Subject: [PATCH 11/11] Added PersonFactoryBuilder; Used lombok builder for creating subjects to update --- .../builder/PersonFactoryBuilder.java | 91 +++++++++++++++++++ .../credit_tracker/service/SignalService.java | 79 +++++----------- 2 files changed, 113 insertions(+), 57 deletions(-) create mode 100644 src/main/java/ru/nbch/credit_tracker/builder/PersonFactoryBuilder.java diff --git a/src/main/java/ru/nbch/credit_tracker/builder/PersonFactoryBuilder.java b/src/main/java/ru/nbch/credit_tracker/builder/PersonFactoryBuilder.java new file mode 100644 index 0000000..90fe789 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/builder/PersonFactoryBuilder.java @@ -0,0 +1,91 @@ +package ru.nbch.credit_tracker.builder; + +import org.apache.commons.lang3.StringUtils; +import ru.nbch.credit_tracker.entities.signal_package.Person; +import ru.nbch.credit_tracker.service.indic.PersonService; +import ru.nbch.credit_tracker.utils.CTUtil; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; + +public class PersonFactoryBuilder { + private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy"); + + private final static String DEFAULT_DATE = "01.01.2000"; + private final static String IP = "0"; + private final static String OKSM = "999"; + private final static String CONSENT_PURPOSE = "16"; + private final static String REPORT_USER = "АО «НБКИ»"; + private final static String LIABILITY = "1"; + private final static String CONSENT_PERIOD = "3"; + private final static String REPORT_USER_REG_NUM = "1057746710713"; + private final static String REPORT_USER_TAX_ID = "7703548386"; + private final static String CONSENT_HASH = "hash"; + private final static String CONSENT_DIV_CODE = "000-000"; + private final static String INQ_PURPOSE = "16"; + + + private PersonService.PersonData personData; + private String uid; + + public static PersonFactoryBuilder builder() { + return new PersonFactoryBuilder(); + } + + public PersonFactoryBuilder personData(PersonService.PersonData personData) { + this.personData = personData; + return this; + } + + public PersonFactoryBuilder uid(String uid) { + this.uid = uid; + return this; + } + + public Person build() { + if (personData == null) { + return null; + } + PersonService.NameData nameData = personData.getName(); + PersonService.PassportData passportData = personData.getPassport(); + Person person = new Person(); + person.setS(nameData.getLastName()); + person.setN(nameData.getFirstName()); + person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null); + person.setD(DATE_FORMAT.format(CTUtil.localDatetoDate(nameData.getBirthDate()))); + + person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum())); + person.setPd(passportData.getIssDate() != null ? DATE_FORMAT.format(CTUtil.localDatetoDate(passportData.getIssDate())) : DEFAULT_DATE); + person.setDt(StringUtils.isNotBlank(passportData.getIdType2()) ? passportData.getIdType2() : passportData.getIdType()); + person.setIp(IP); + person.setUid(uid); + person.setOksm(OKSM); + person.setConsentDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now()))); + person.setConsentPurpose(CONSENT_PURPOSE); + person.setReportUser(REPORT_USER); + person.setLiability(LIABILITY); + person.setConsentPeriod(CONSENT_PERIOD); + person.setAgrDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now()))); + person.setReportUserRegNum(REPORT_USER_REG_NUM); + person.setReportUserTaxID(REPORT_USER_TAX_ID); + person.setConsentHash(CONSENT_HASH); + + person.setCs(person.getS()); + person.setConsentN(person.getN()); + person.setConsentM(person.getM()); + person.setConsentBd(person.getD()); + person.setConsentPn(person.getPn()); + person.setConsentPd(person.getPd()); + person.setConsentDivCode(CONSENT_DIV_CODE); + person.setConsentDt(person.getDt()); + person.setInqPurpose(INQ_PURPOSE); + return person; + } + + private String getPn(String serNum, String idNum) { + String normSerNum = CTUtil.normalize(serNum); + String normIdNum = CTUtil.normalize(idNum); + return StringUtils.isNotBlank(normSerNum) ? normSerNum + normIdNum : normIdNum; + } +} 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 f12367f..a4866f6 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/SignalService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/SignalService.java @@ -1,8 +1,8 @@ package ru.nbch.credit_tracker.service; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import ru.nbch.credit_tracker.builder.PersonFactoryBuilder; import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings; import ru.nbch.credit_tracker.entities.dto.Hit; import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; @@ -19,11 +19,7 @@ import ru.nbch.credit_tracker.service.indic.PhoneService; 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.utils.CTUtil; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -34,8 +30,6 @@ import java.util.Objects; @Service public class SignalService { - private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy"); - private final CreditTrackerSettings config; private final HitsService hitsService; private final UserPackageService userPackageService; @@ -100,9 +94,24 @@ public class SignalService { PhoneFidMap subject; if (data.getFid() != null) { FlagsService.FlagsData flagsData = flagsDataMap.get(data.getFid()); - subject = new PhoneFidMap(data.getId(), packageId, data.getSubjectId(), data.getPhone(), data.getFid(), flagsData.getFlagDebt5000(), flagsData.getFlag90days(), calculatedAt); + subject = PhoneFidMap.builder() + .id(data.getId()) + .packageId(packageId) + .subjectId(data.getSubjectId()) + .phone(data.getPhone()) + .fid(data.getFid()) + .flagDebt5000(flagsData.getFlagDebt5000()) + .flag90days(flagsData.getFlag90days()) + .calculatedAt(calculatedAt) + .build(); } else { - subject = new PhoneFidMap(data.getId(), packageId, data.getSubjectId(), data.getPhone(), null, null, null, calculatedAt); + subject = PhoneFidMap.builder() + .id(data.getId()) + .packageId(packageId) + .subjectId(data.getSubjectId()) + .phone(data.getPhone()) + .calculatedAt(calculatedAt) + .build(); } subjectToUpdate.add(subject); }); @@ -158,7 +167,10 @@ public class SignalService { fidsPhoneData.forEach(data -> { if (data.getFid() != null) { PersonService.PersonData personData = personFidMap.get(data.getFid()); - Person person = getPerson(personData, data.getSubjectId()); + Person person = PersonFactoryBuilder.builder() + .personData(personData) + .uid(data.getSubjectId()) + .build(); if (person != null) { persons.add(person); } @@ -167,53 +179,6 @@ public class SignalService { return persons; } - private Person getPerson(PersonService.PersonData personData, String id) { - if (personData == null) { - return null; - } - PersonService.NameData nameData = personData.getName(); - PersonService.PassportData passportData = personData.getPassport(); - Person person = new Person(); - person.setS(nameData.getLastName()); - person.setN(nameData.getFirstName()); - person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null); - person.setD(DATE_FORMAT.format(CTUtil.localDatetoDate(nameData.getBirthDate()))); - - person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum())); - person.setPd(passportData.getIssDate() != null ? DATE_FORMAT.format(CTUtil.localDatetoDate(passportData.getIssDate())) : "01.01.2000"); - person.setDt(StringUtils.isNotBlank(passportData.getIdType2()) ? passportData.getIdType2() : passportData.getIdType()); - person.setIp("0"); - person.setUid(id); - person.setOksm("999"); - person.setConsentDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now()))); - person.setConsentPurpose("16"); - person.setReportUser("АО «НБКИ»"); - person.setLiability("1"); - person.setConsentPeriod("3"); - person.setAgrDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now()))); - person.setReportUserRegNum("1057746710713"); - person.setReportUserTaxID("7703548386"); - person.setConsentHash("hash"); - - person.setCs(person.getS()); - person.setConsentN(person.getN()); - person.setConsentM(person.getM()); - person.setConsentBd(person.getD()); - person.setConsentPn(person.getPn()); - person.setConsentPd(person.getPd()); - person.setConsentDivCode("000-000"); - person.setConsentDt(person.getDt()); - person.setInqPurpose("16"); - return person; - } - - private String getPn(String serNum, String idNum) { - String normSerNum = CTUtil.normalize(serNum); - String normIdNum = CTUtil.normalize(idNum); - return StringUtils.isNotBlank(normSerNum) ? normSerNum + normIdNum : normIdNum; - } - - public List findActivePackages(String userId) { return userPackageService.findUserPackages(userId, Status.ON_MONITORING); }