Compare commits
11 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79259170bc | ||
|
|
8a7a313c1d | ||
|
|
bd2ad04a65 | ||
|
|
3358a8ee21 | ||
|
|
b4c4475398 | ||
|
|
43897c6cbb | ||
|
|
fb8da59b1b | ||
|
|
ead8638d3e | ||
|
|
9c4e5ed13c | ||
|
|
b80ec82ab9 | ||
|
|
392b99aca4 |
46 changed files with 1198 additions and 640 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,22 +6,44 @@ 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.exceptions.SignalErrorException;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.*;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalException;
|
||||
import ru.nbch.credit_tracker.utils.error.SimpleMessageResolver;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
@ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||
public ResponseEntity<CommonError> handleInvalidUser(SignalErrorException ex) {
|
||||
private final SimpleMessageResolver messageResolver = new SimpleMessageResolver();
|
||||
|
||||
@ExceptionHandler(value = SignalException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||
public ResponseEntity<CommonError> handleClientException(SignalException 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);
|
||||
CommonError commonError = getCommonError(ex);
|
||||
commonError.setStatus("error");
|
||||
commonError.setErrorCode(ex.getErrorMessage().getSubject().getErrorCode());
|
||||
commonError.setErrorText(messageResolver.resolve(ex.getErrorMessage()));
|
||||
|
||||
if (ex instanceof SignalClientException) {
|
||||
return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST);
|
||||
} else {
|
||||
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return new ResponseEntity<>(commonError, headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
private static CommonError getCommonError(SignalException 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,32 +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,
|
||||
|
|
@ -48,24 +38,10 @@ public class XmlUtilService {
|
|||
MonitoringSignalResponse.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StaxXmlProcessor staxXmlProcessor() {
|
||||
List<StaxReader<?>> 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import java.time.LocalDateTime;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
public class HitsData {
|
||||
public class Hit {
|
||||
private Integer id;
|
||||
private Integer packageId;
|
||||
private String subjectId;
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
package ru.nbch.credit_tracker.entities.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
|
@ -11,7 +8,8 @@ import java.time.LocalDateTime;
|
|||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SubjectData {
|
||||
@Builder
|
||||
public class PhoneFidMap {
|
||||
private Integer id;
|
||||
private Integer packageId;
|
||||
private String subjectId;
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package ru.nbch.credit_tracker.entities.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
|
@ -7,7 +8,8 @@ import java.time.LocalDateTime;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
public class PackageData {
|
||||
@Builder
|
||||
public class UserPackage {
|
||||
private Integer id;
|
||||
private String userId;
|
||||
private String packageName;
|
||||
|
|
@ -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) + "}";
|
||||
}
|
||||
}
|
||||
102
src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java
Normal file
102
src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java
Normal file
|
|
@ -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 <T extends Enum<T> & IEnumKeyCode> boolean contains(String id, T... enumSet) {
|
||||
for (T e : enumSet) {
|
||||
if (Objects.equals(id, e.getKey()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static <T extends Enum<T> & IEnumKeyCode> boolean containsIgnoreCase(String id, T... enumSet) {
|
||||
for (T e : enumSet) {
|
||||
if (e.getKey() != null && e.getKey().equalsIgnoreCase(id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static <T extends Enum<T> & IEnumKeyCode> boolean contains(T e, T... enumSet) {
|
||||
for (T enumEl : enumSet) {
|
||||
if (enumEl.equals(e))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет что среди всех Enum данного класса, присутствует элемент с данным id
|
||||
* id может быть null
|
||||
*/
|
||||
static <T extends Enum<T> & IEnumKeyCode> boolean contains(String key, Class<T> enumClass) {
|
||||
for (T e : enumClass.getEnumConstants()) {
|
||||
if (Objects.equals(key, e.getKey()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает Enum по id, если в заданном классе такой определен
|
||||
* id может быть null
|
||||
*
|
||||
* @return Enum если нашел, иначе <tt>null</tt>
|
||||
*/
|
||||
static <T extends Enum<T> & IEnumKeyCode> T getEnumByKey(Class<T> enumClass, String key) {
|
||||
for (T e : enumClass.getEnumConstants()) {
|
||||
if (Objects.equals(key, e.getKey()))
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static <T extends Enum<T> & IEnumKeyCode> T getEnumByKeyOrUndefined(Class<T> enumClass, String key) {
|
||||
T enumByKey = getEnumByKey(enumClass, key);
|
||||
return enumByKey == null ? getUndefined(enumClass) : enumByKey;
|
||||
}
|
||||
|
||||
static <T extends Enum<T> & IEnumKeyCode> T getUndefined(Class<T> 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";
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package ru.nbch.credit_tracker.enums;
|
||||
|
||||
public enum XmlErrorFormat {
|
||||
MonitoringActivePackagesError,
|
||||
MonitoringDownloadError,
|
||||
MonitoringError,
|
||||
MonitoringPackageDeleteError,
|
||||
MonitoringReportListError
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
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 SignalException {
|
||||
|
||||
public SignalClientException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat) {
|
||||
super(errorMessage, errorFormat);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.getMessage() + " " + tag);
|
||||
} else {
|
||||
errorMessage.setErrorText(error.getMessage());
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,35 +8,41 @@ 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.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.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;
|
||||
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.exceptions.SignalErrorException;
|
||||
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||
import ru.nbch.credit_tracker.service.SignalService;
|
||||
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;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.serverExcp;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SignalFacade {
|
||||
|
|
@ -46,7 +52,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;
|
||||
|
||||
|
|
@ -55,89 +61,62 @@ 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;
|
||||
}
|
||||
|
||||
public ResponseEntity<MonitoringResponse> 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);
|
||||
}
|
||||
|
||||
// Валидация Архива на количетсво файлов, размер и расширение
|
||||
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<ZipEntry> xmlFileEntry = ZipUtils.extractValidEntry(zipInputStream);
|
||||
if (xmlFileEntry.isEmpty()) {
|
||||
throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||
}
|
||||
if (xmlFileEntry.get().getSize() > MAX_XML_FILE_SIZE) {
|
||||
throw clientExcp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError);
|
||||
}
|
||||
|
||||
zipInputStream.close();
|
||||
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 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);
|
||||
} finally {
|
||||
if (zipInputStream != null) {
|
||||
try {
|
||||
zipInputStream.close();
|
||||
} catch (IOException e) {
|
||||
throw serverExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// валидация xml
|
||||
try {
|
||||
validateMonitoringRequest(monitoringRequest);
|
||||
} catch (SignalErrorException e) {
|
||||
ValidationUtil.validateMonitoringRequest(monitoringRequest);
|
||||
} catch (SignalClientException e) {
|
||||
signalService.rejectPackage(monitoringRequest);
|
||||
throw e;
|
||||
}
|
||||
|
|
@ -147,22 +126,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);
|
||||
}
|
||||
|
||||
// в отдельном потоке запускаем поиск фидов и расчет флагов просрочек
|
||||
|
|
@ -171,58 +150,6 @@ public class SignalFacade {
|
|||
return ResponseEntity.ok().body(new MonitoringResponse());
|
||||
}
|
||||
|
||||
private void validateMonitoringRequest(MonitoringRequest request) throws SignalErrorException {
|
||||
if (request == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_011, null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
validateReruqredTags(request);
|
||||
|
||||
validateTagsTypes(request);
|
||||
}
|
||||
|
||||
private void validateReruqredTags(MonitoringRequest request) throws SignalErrorException {
|
||||
if (request.getUserId() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "UserId", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getPackageName() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "PackageName", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getPassword() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "Password", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getSubjects() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "Subjects", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getSubjects().getSubject().isEmpty()) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "Subject", new MonitoringError(), true);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTagsTypes(MonitoringRequest request) throws SignalErrorException {
|
||||
if (!ValidationUtil.validatePackageName(request.getPackageName())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_008, null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
Set<String> uniqueIds = new HashSet<>();
|
||||
for (Subject subject : request.getSubjects().getSubject()) {
|
||||
if (!ValidationUtil.validatePhone(subject.getClientId())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_003, null, new MonitoringError(), true);
|
||||
}
|
||||
if (!ValidationUtil.validateNPId(subject.getId())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_010, null, new MonitoringError(), true);
|
||||
}
|
||||
// проверка на уникальность Id внутри одного пакета
|
||||
if (!uniqueIds.add(subject.getId())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_004, subject.getId(), new MonitoringError(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerFidsAndDebts(Integer packageId, String packageName) {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
|
|
@ -232,14 +159,14 @@ public class SignalFacade {
|
|||
// TODO validate xsd?
|
||||
if (signalRestService.update(signals)) {
|
||||
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||
} else {
|
||||
log.info("Package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
||||
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
||||
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
||||
}
|
||||
});
|
||||
|
|
@ -247,54 +174,73 @@ 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<MonitoringActivePackagesResponse> findActivePackages(MonitoringActivePackagesRequest activePackagesRequest) {
|
||||
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) {
|
||||
List<UserPackage> 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 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<MonitoringPackageDeleteResponse> 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);
|
||||
|
||||
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);
|
||||
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<MonitoringReportListResponse> 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);
|
||||
|
|
@ -306,7 +252,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)) {
|
||||
|
|
@ -315,7 +261,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);
|
||||
|
|
@ -324,14 +270,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -347,15 +293,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.Hit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface HitsMapper {
|
||||
|
||||
void insertHits(@Param("hits") List<Hit> hits);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
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.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface PhoneFidMapMapper {
|
||||
|
||||
void registerSubjects(@Param("subjects") List<Subject> subjects, @Param("packageId") Integer packageId);
|
||||
|
||||
List<PhoneFidMap> findPhoneFidMaps(@Param("packageId") Integer packageId);
|
||||
|
||||
List<PhoneFidMap> findFullPhoneFidMap(@Param("packageId") Integer packageId);
|
||||
|
||||
void updatePhoneFidMaps(@Param("subjects") List<PhoneFidMap> subjects);
|
||||
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
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 {
|
||||
|
||||
boolean isPackageNotUnique(@Param("userId") String userId, @Param("packageName") String packageName);
|
||||
|
||||
boolean isPackageExists(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String status);
|
||||
|
||||
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<Subject> 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);
|
||||
|
||||
void setPackageStatus(@Param("packageId") Integer packageId, @Param("status") String status);
|
||||
|
||||
List<SubjectData> findSubjectsData(@Param("packageId") Integer packageId);
|
||||
|
||||
List<SubjectData> findFullSubjectsData(@Param("packageId") Integer packageId);
|
||||
|
||||
PackageData findPackageData(@Param("id") Integer id);
|
||||
|
||||
List<PackageData> findPackageDataList(@Param("userId") String userId, @Param("status") String status);
|
||||
|
||||
List<PackageData> findPackagesByStatus(@Param("status") String status);
|
||||
|
||||
void setHits(@Param("hits") List<HitsData> hits);
|
||||
|
||||
void updateSubjects(@Param("subjects") List<SubjectData> subjects);
|
||||
|
||||
void setPackageLastDownloadedReport(@Param("id") Integer id, @Param("fileName") String fileName);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
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.UserPackage;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface UserPackageMapper {
|
||||
|
||||
boolean isPackageNotUnique(@Param("userId") String userId, @Param("packageName") String packageName);
|
||||
|
||||
boolean isPackageExists(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String status);
|
||||
|
||||
void deletePackage(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String newStatus, @Param("previousStatus") String previousStatus, @Param("deactivatedAt") LocalDateTime deactivatedAt);
|
||||
|
||||
Integer insertPackage(@Param("userPackage") UserPackage userPackage);
|
||||
|
||||
void updatePackageStatus(@Param("packageId") Integer packageId, @Param("status") String status);
|
||||
|
||||
void updatePackageLastDownloadedReport(@Param("id") Integer id, @Param("fileName") String fileName);
|
||||
|
||||
UserPackage findPackage(@Param("id") Integer id);
|
||||
|
||||
List<UserPackage> findUserPackages(@Param("userId") String userId, @Param("status") String status);
|
||||
|
||||
List<UserPackage> findAllPackagesByStatus(@Param("status") String status);
|
||||
|
||||
}
|
||||
|
|
@ -3,9 +3,9 @@ package ru.nbch.credit_tracker.service;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
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.dto.Hit;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||
import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.*;
|
||||
import ru.nbch.credit_tracker.entities.response.online_download.Inquiry;
|
||||
import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadReport;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -57,13 +56,13 @@ public class MonitoringService {
|
|||
|
||||
private void monitor() {
|
||||
log.info("Start monitoring");
|
||||
List<PackageData> packages = signalService.findPackagesOnMonitoring();
|
||||
for (PackageData packageData : packages) {
|
||||
log.info("Processing package {}", packageData.getPackageName());
|
||||
SgnlOnlineReport onlineReports = signalRestService.getReports(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName());
|
||||
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||
for (UserPackage userPackage : packages) {
|
||||
log.info("Processing package {}", userPackage.getPackageName());
|
||||
SgnlOnlineReport onlineReports = signalRestService.getReports(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName());
|
||||
|
||||
if (onlineReports == null) {
|
||||
log.info("No reports found for package {}", packageData.getPackageName());
|
||||
log.info("No reports found for package {}", userPackage.getPackageName());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -71,7 +70,7 @@ public class MonitoringService {
|
|||
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать
|
||||
|
||||
if (fileNames.isEmpty()) {
|
||||
log.info("No new report found for package {}", packageData.getPackageName());
|
||||
log.info("No new report found for package {}", userPackage.getPackageName());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -79,16 +78,16 @@ public class MonitoringService {
|
|||
.orElseGet(Collections::emptyList)
|
||||
.stream().max(Comparator.comparing(CTUtil::parseDateFromReportFileName)); // отфильтровали только те имена, которые парсятся в дату, так что null тут не придет
|
||||
|
||||
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(packageData.getLastDownloadedReport());
|
||||
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(userPackage.getLastDownloadedReport());
|
||||
|
||||
if (packageData.getLastDownloadedReport() != null) {
|
||||
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", packageData.getPackageName(), packageData.getLastDownloadedReport());
|
||||
if (userPackage.getLastDownloadedReport() != null) {
|
||||
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", userPackage.getPackageName(), userPackage.getLastDownloadedReport());
|
||||
} else {
|
||||
log.info("Last Downloaded Report Name is empty");
|
||||
}
|
||||
|
||||
OnlineDownloadReport report = null;
|
||||
if (packageData.getLastDownloadedReport() == null && newReport.isPresent()) {
|
||||
if (userPackage.getLastDownloadedReport() == null && newReport.isPresent()) {
|
||||
report = loadReport(newReport.get()); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным
|
||||
} else if (lastDownloadedReportDate != null && newReport.isPresent()) {
|
||||
LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport.get());
|
||||
|
|
@ -97,28 +96,28 @@ public class MonitoringService {
|
|||
}
|
||||
}
|
||||
if (report == null) {
|
||||
log.info("Report was not loaded for package {}", packageData.getPackageName());
|
||||
log.info("Report was not loaded for package {}", userPackage.getPackageName());
|
||||
continue;
|
||||
}
|
||||
|
||||
MonitoringSignalResponse response = generateResponse(packageData, report.getPersons().getPersons());
|
||||
String fileName = createResponseFile(packageData, response);
|
||||
MonitoringSignalResponse response = generateResponse(userPackage, report.getPersons().getPersons());
|
||||
String fileName = createResponseFile(userPackage, response);
|
||||
if (fileName != null) {
|
||||
log.info("New report fileName: {}", fileName);
|
||||
updateSignalHits(packageData, response, fileName);
|
||||
signalService.updateLastDownloadedReport(packageData.getId(), newReport.get());
|
||||
updateSignalHits(userPackage, response, fileName);
|
||||
signalService.updateLastDownloadedReport(userPackage.getId(), newReport.get());
|
||||
} else {
|
||||
log.info("Report was not created for package {}", packageData.getPackageName());
|
||||
log.info("Report was not created for package {}", userPackage.getPackageName());
|
||||
}
|
||||
}
|
||||
log.info("Finish monitoring");
|
||||
}
|
||||
|
||||
private MonitoringSignalResponse generateResponse(PackageData packageData, List<Person> persons) {
|
||||
private MonitoringSignalResponse generateResponse(UserPackage userPackage, List<Person> persons) {
|
||||
MonitoringSignalResponse response = new MonitoringSignalResponse();
|
||||
response.setPackageName(packageData.getPackageName()); // Имя пакета, переданного при установке
|
||||
response.setPackageName(userPackage.getPackageName()); // Имя пакета, переданного при установке
|
||||
Subjects subjects = new Subjects();
|
||||
List<SubjectData> subjectDataList = signalService.findFullSubjectsData(packageData.getId());
|
||||
List<PhoneFidMap> phoneFidMapList = signalService.findFullSubjectsData(userPackage.getId());
|
||||
for (Person person : persons) {
|
||||
Signals signals = new Signals();
|
||||
for (Inquiry inquiry : person.getInquiries()) {
|
||||
|
|
@ -135,7 +134,7 @@ public class MonitoringService {
|
|||
|
||||
// Если есть хотя бы один заполненный сигнал, значит заполняем остальные данные
|
||||
if (!signals.getSignals().isEmpty()) {
|
||||
subjectDataList.stream().filter(p -> p.getSubjectId().equals(person.getUid())).findFirst().ifPresent(subjectData -> {
|
||||
phoneFidMapList.stream().filter(p -> p.getSubjectId().equals(person.getUid())).findFirst().ifPresent(subjectData -> {
|
||||
Subject subject = new Subject();
|
||||
subject.setId(subjectData.getSubjectId()); // Уникальный идентификатор субъекта (равен Id из XML-пакета при установке мониторинга)
|
||||
subject.setClientId(subjectData.getPhone());
|
||||
|
|
@ -150,18 +149,17 @@ public class MonitoringService {
|
|||
return response;
|
||||
}
|
||||
|
||||
private String createResponseFile(PackageData packageData, MonitoringSignalResponse response) {
|
||||
private String createResponseFile(UserPackage userPackage, MonitoringSignalResponse response) {
|
||||
try {
|
||||
String fileName = CTUtil.generateResponseReportFileName(packageData.getUserId(), packageData.getPackageName());
|
||||
String filePath = config.getLoadDir() + File.separator + packageData.getUserId().substring(0, 6) + File.separator;
|
||||
String fileName = CTUtil.generateResponseReportFileName(userPackage.getUserId(), userPackage.getPackageName());
|
||||
String filePath = config.getLoadDir() + File.separator + userPackage.getUserId().substring(0, 6) + File.separator;
|
||||
|
||||
File folder = new File(filePath);
|
||||
if (!folder.exists()) {
|
||||
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");
|
||||
|
|
@ -179,23 +177,23 @@ public class MonitoringService {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void updateSignalHits(PackageData packageData, MonitoringSignalResponse response, String reportFileName) {
|
||||
log.info("Updating signal hits for {}", packageData.getPackageName());
|
||||
private void updateSignalHits(UserPackage userPackage, MonitoringSignalResponse response, String reportFileName) {
|
||||
log.info("Updating signal hits for {}", userPackage.getPackageName());
|
||||
LocalDateTime responseSentAt = LocalDateTime.now();
|
||||
List<HitsData> hits = new ArrayList<>();
|
||||
List<Hit> hits = new ArrayList<>();
|
||||
response.getSubjects().getSubjects().forEach(subject -> {
|
||||
subject.getSignals().getSignals().forEach(signal -> {
|
||||
HitsData hitsData = new HitsData();
|
||||
hitsData.setPackageId(packageData.getId());
|
||||
hitsData.setSubjectId(subject.getId());
|
||||
hitsData.setSignalType(1);
|
||||
hitsData.setResponseSentAt(responseSentAt);
|
||||
hitsData.setReportFileName(reportFileName);
|
||||
hits.add(hitsData);
|
||||
Hit hit = new Hit();
|
||||
hit.setPackageId(userPackage.getId());
|
||||
hit.setSubjectId(subject.getId());
|
||||
hit.setSignalType(1);
|
||||
hit.setResponseSentAt(responseSentAt);
|
||||
hit.setReportFileName(reportFileName);
|
||||
hits.add(hit);
|
||||
});
|
||||
});
|
||||
signalService.setHits(hits);
|
||||
log.info("Signal hits updated for package {}", packageData.getPackageName());
|
||||
signalService.insertHits(hits);
|
||||
log.info("Signal hits updated for package {}", userPackage.getPackageName());
|
||||
}
|
||||
|
||||
private OnlineDownloadReport loadReport(String reportName) {
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,31 +1,25 @@
|
|||
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.HitsData;
|
||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
||||
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||
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;
|
||||
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.utils.CTUtil;
|
||||
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 java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -36,10 +30,10 @@ 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 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,53 +41,77 @@ 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;
|
||||
}
|
||||
|
||||
public boolean isPackageNotUnique(MonitoringRequest request) {
|
||||
String userId = request.getUserId();
|
||||
return mapper.isPackageNotUnique(userId.substring(0, 6), request.getPackageName());
|
||||
return userPackageService.isPackageNotUnique(request.getUserId(), request.getPackageName());
|
||||
}
|
||||
|
||||
public Integer registerPackage(MonitoringRequest request) {
|
||||
Integer packageId = mapper.registerPackage(request, LocalDateTime.now(), Status.PROCESSING.name());
|
||||
UserPackage userPackage = UserPackage.builder()
|
||||
.userId(request.getUserId())
|
||||
.packageName(request.getPackageName())
|
||||
.createdAt(LocalDateTime.now())
|
||||
.status(Status.PROCESSING.name())
|
||||
.build();
|
||||
Integer packageId = userPackageService.insertPackage(userPackage);
|
||||
List<Subject> 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); // TODO преобразовывать список в List<PhoneFidMap> ?
|
||||
}
|
||||
return packageId;
|
||||
}
|
||||
|
||||
public List<PhoneService.FidsPhoneData> registerSubjectsFidAndDebts(Integer packageId) {
|
||||
List<SubjectData> subjects = mapper.findSubjectsData(packageId);
|
||||
List<PhoneFidMap> subjects = phoneFidMapService.findPhoneFidMaps(packageId);
|
||||
return updateFlags(subjects, packageId);
|
||||
}
|
||||
|
||||
public List<PhoneService.FidsPhoneData> updateFlags(List<SubjectData> subjects, Integer packageId) {
|
||||
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(subjects, true);
|
||||
public List<PhoneService.FidsPhoneData> updateFlags(List<PhoneFidMap> subjects, Integer packageId) {
|
||||
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(subjects);
|
||||
LocalDateTime calculatedAt = LocalDateTime.now();
|
||||
for (int i = 0; i < fidsPhoneDataList.size(); i += batchSize) {
|
||||
int end = Math.min(i + batchSize, fidsPhoneDataList.size());
|
||||
List<PhoneService.FidsPhoneData> currentList = fidsPhoneDataList.subList(i, end);
|
||||
Map<Integer, FlagsService.FlagsData> flagsDataMap = flagsService.findFlags(currentList.stream().map(PhoneService.FidsPhoneData::getFid).filter(Objects::nonNull).toList());
|
||||
List<SubjectData> subjectToUpdate = new ArrayList<>();
|
||||
List<PhoneFidMap> subjectToUpdate = new ArrayList<>();
|
||||
|
||||
currentList.forEach(data -> {
|
||||
SubjectData subject;
|
||||
PhoneFidMap subject;
|
||||
if (data.getFid() != null) {
|
||||
FlagsService.FlagsData flagsData = flagsDataMap.get(data.getFid());
|
||||
subject = new SubjectData(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 SubjectData(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);
|
||||
});
|
||||
|
|
@ -101,7 +119,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.updatePhoneFidMaps(subjectToUpdate.subList(j, endIndex));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,18 +127,24 @@ public class SignalService {
|
|||
}
|
||||
|
||||
public void rejectPackage(MonitoringRequest request) {
|
||||
mapper.insertPackage(request, LocalDateTime.now(), Status.REJECTED.name());
|
||||
UserPackage userPackage = UserPackage.builder()
|
||||
.userId(request.getUserId())
|
||||
.packageName(request.getPackageName())
|
||||
.createdAt(LocalDateTime.now())
|
||||
.status(Status.REJECTED.name())
|
||||
.build();
|
||||
userPackageService.insertPackage(userPackage);
|
||||
}
|
||||
|
||||
public void setPackageStatus(Integer packageId, Status status) {
|
||||
mapper.setPackageStatus(packageId, status.name());
|
||||
public void updatePackageStatus(Integer packageId, Status status) {
|
||||
userPackageService.updatePackageStatus(packageId, status);
|
||||
}
|
||||
|
||||
public Signals buildSignals(Integer packageId, List<PhoneService.FidsPhoneData> fids) {
|
||||
PackageData packageData = mapper.findPackageData(packageId);
|
||||
UserPackage userPackage = userPackageService.findPackage(packageId);
|
||||
Signals signals = new Signals();
|
||||
signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы)
|
||||
signals.setId(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName()); // <MEMBERCODE>_<PackageName>
|
||||
signals.setId(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName()); // <MEMBERCODE>_<PackageName>
|
||||
Auth auth = new Auth();
|
||||
auth.setUser(config.getSignalsuser());
|
||||
signals.setAuth(auth);
|
||||
|
|
@ -143,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);
|
||||
}
|
||||
|
|
@ -152,101 +179,31 @@ 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 MonitoringActivePackagesResponse findActivePackages(String userId) {
|
||||
String memberCode = userId.substring(0, 6);
|
||||
MonitoringActivePackagesResponse activePackages = new MonitoringActivePackagesResponse();
|
||||
activePackages.setStatus("OK");
|
||||
activePackages.setMembercode(memberCode);
|
||||
Packages packages = new Packages();
|
||||
mapper.findPackageDataList(memberCode, Status.ON_MONITORING.name()).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<UserPackage> findActivePackages(String userId) {
|
||||
return userPackageService.findUserPackages(userId, Status.ON_MONITORING);
|
||||
}
|
||||
|
||||
public boolean isPackageExists(String username, String packageName) {
|
||||
return mapper.isPackageExists(username.substring(0, 6), packageName, Status.ON_MONITORING.name());
|
||||
return userPackageService.isPackageExists(username, 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);
|
||||
|
||||
MonitoringPackageDeleteResponse deleteResponse = new MonitoringPackageDeleteResponse();
|
||||
deleteResponse.setStatus("Deleted");
|
||||
deleteResponse.setPackageName(packageName);
|
||||
deleteResponse.setDeactivatedAt(deactivatedAt.toString());
|
||||
return deleteResponse;
|
||||
public void deletePackage(String username, String packageName, LocalDateTime deactivatedAt) {
|
||||
userPackageService.deletePackage(username, packageName, Status.DELETED, Status.ON_MONITORING, deactivatedAt);
|
||||
}
|
||||
|
||||
public List<PackageData> findPackagesOnMonitoring() {
|
||||
return mapper.findPackagesByStatus(Status.ON_MONITORING.name());
|
||||
public List<UserPackage> findPackagesOnMonitoring() {
|
||||
return userPackageService.findAllPackagesByStatus(Status.ON_MONITORING);
|
||||
}
|
||||
|
||||
public List<SubjectData> findFullSubjectsData(Integer packageId) {
|
||||
return mapper.findFullSubjectsData(packageId);
|
||||
public List<PhoneFidMap> findFullSubjectsData(Integer packageId) {
|
||||
return phoneFidMapService.findFullPhoneFidMap(packageId);
|
||||
}
|
||||
|
||||
public void setHits(List<HitsData> hits) {
|
||||
mapper.setHits(hits);
|
||||
public void insertHits(List<Hit> hits) {
|
||||
hitsService.insertHits(hits);
|
||||
}
|
||||
|
||||
public void updateLastDownloadedReport(Integer id, String fileName) {
|
||||
mapper.setPackageLastDownloadedReport(id, fileName);
|
||||
userPackageService.updatePackageLastDownloadedReport(id, fileName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package ru.nbch.credit_tracker.service;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||
import ru.nbch.credit_tracker.enums.Status;
|
||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||
|
|
@ -42,32 +42,32 @@ public class UpdatingFlagsService {
|
|||
|
||||
private void update() {
|
||||
log.info("Start updating flags");
|
||||
List<PackageData> packages = signalService.findPackagesOnMonitoring();
|
||||
for (PackageData packageData : packages) {
|
||||
log.info("Updating flags for Package {}", packageData.getPackageName());
|
||||
List<SubjectData> subjects = signalService.findFullSubjectsData(packageData.getId())
|
||||
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||
for (UserPackage userPackage : packages) {
|
||||
log.info("Updating flags for Package {}", userPackage.getPackageName());
|
||||
List<PhoneFidMap> subjects = signalService.findFullSubjectsData(userPackage.getId())
|
||||
.stream().filter(subject -> subject.getCalculatedAt() != null && hasDaysPassed(subject.getCalculatedAt())).toList();
|
||||
updateFlags(packageData.getId(), subjects, packageData.getPackageName());
|
||||
updateFlags(userPackage.getId(), subjects, userPackage.getPackageName());
|
||||
}
|
||||
log.info("Finish updating flags");
|
||||
}
|
||||
|
||||
private void updateFlags(Integer packageId, List<SubjectData> subjects, String packageName) {
|
||||
private void updateFlags(Integer packageId, List<PhoneFidMap> subjects, String packageName) {
|
||||
try {
|
||||
signalService.setPackageStatus(packageId, Status.PROCESSING);
|
||||
signalService.updatePackageStatus(packageId, Status.PROCESSING);
|
||||
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.updateFlags(subjects, packageId);
|
||||
if (!phoneFidsData.isEmpty()) {
|
||||
Signals signals = signalService.buildSignals(packageId, phoneFidsData);
|
||||
if (signalRestService.update(signals)) {
|
||||
log.info("Flags were updated successfully. PackageId: {} PackageName: {}. Package status changed to ON_MONITORING", packageId, packageName);
|
||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||
} else {
|
||||
log.info("Updated package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
||||
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||
}
|
||||
} else {
|
||||
log.info("No flags were updated for package id {}. Package status changed to ON_MONITORING", packageId);
|
||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Ошибка при поиске фидов или перерасчете флагов просрочек. Package_id {}", packageId, e);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
|
@ -20,16 +20,12 @@ public class PhoneService {
|
|||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects) {
|
||||
return findFidsPhoneData(subjects, false);
|
||||
}
|
||||
|
||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects, boolean processNullFids) {
|
||||
public List<FidsPhoneData> findFidsPhoneData(List<PhoneFidMap> subjects) {
|
||||
List<FidsPhoneData> fidsPhoneDataList = new ArrayList<>();
|
||||
int batchSize = 10000;
|
||||
for (int i = 0; i < subjects.size(); i += batchSize) {
|
||||
int end = Math.min(i + batchSize, subjects.size());
|
||||
List<SubjectData> currentSubjects = subjects.subList(i, end);
|
||||
List<PhoneFidMap> currentSubjects = subjects.subList(i, end);
|
||||
List<String> phones = currentSubjects.stream().map(subject -> "9" + subject.getPhone()).toList();
|
||||
List<FidsData> fidsData = mapper.findFids(phones);
|
||||
|
||||
|
|
@ -40,7 +36,7 @@ public class PhoneService {
|
|||
Integer fid = fidsMap.get(phone);
|
||||
if (fid != null) {
|
||||
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), fid, subject.getPhone(), subject.getSubjectId()));
|
||||
} else if (processNullFids) {
|
||||
} else {
|
||||
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), null, subject.getPhone(), subject.getSubjectId()));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package ru.nbch.credit_tracker.service.signal;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||
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 insertHits(List<Hit> hits) {
|
||||
mapper.insertHits(hits);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package ru.nbch.credit_tracker.service.signal;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
||||
import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class PhoneFidMapService {
|
||||
|
||||
private final PhoneFidMapMapper mapper;
|
||||
|
||||
public PhoneFidMapService(PhoneFidMapMapper mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public void registerSubjects(List<Subject> subjects, Integer packageId) {
|
||||
mapper.registerSubjects(subjects, packageId);
|
||||
}
|
||||
|
||||
public List<PhoneFidMap> findPhoneFidMaps(Integer packageId) {
|
||||
return mapper.findPhoneFidMaps(packageId);
|
||||
}
|
||||
|
||||
public List<PhoneFidMap> findFullPhoneFidMap(Integer packageId) {
|
||||
return mapper.findFullPhoneFidMap(packageId);
|
||||
}
|
||||
|
||||
public void updatePhoneFidMaps(List<PhoneFidMap> subjects) {
|
||||
mapper.updatePhoneFidMaps(subjects);
|
||||
}
|
||||
}
|
||||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
package ru.nbch.credit_tracker.service.signal;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||
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.substring(0, 6), packageName);
|
||||
}
|
||||
|
||||
public boolean isPackageExists(String userId, String packageName, Status status) {
|
||||
return mapper.isPackageExists(userId.substring(0, 6), packageName, status.name());
|
||||
}
|
||||
|
||||
public void deletePackage(String userId, String packageName, Status newStatus, Status previousStatus, LocalDateTime deactivatedAt) {
|
||||
mapper.deletePackage(userId.substring(0, 6), packageName, newStatus.name(), previousStatus.name(), deactivatedAt);
|
||||
}
|
||||
|
||||
public Integer insertPackage(UserPackage userPackage) {
|
||||
return mapper.insertPackage(userPackage);
|
||||
}
|
||||
|
||||
public void updatePackageStatus(Integer packageId, Status status) {
|
||||
mapper.updatePackageStatus(packageId, status.name());
|
||||
}
|
||||
|
||||
public void updatePackageLastDownloadedReport(Integer id, String fileName) {
|
||||
mapper.updatePackageLastDownloadedReport(id, fileName);
|
||||
}
|
||||
|
||||
public UserPackage findPackage(Integer id) {
|
||||
return mapper.findPackage(id);
|
||||
}
|
||||
|
||||
public List<UserPackage> findUserPackages(String userId, Status status) {
|
||||
return mapper.findUserPackages(userId.substring(0, 6), status.name());
|
||||
}
|
||||
|
||||
public List<UserPackage> findAllPackagesByStatus(Status status) {
|
||||
return mapper.findAllPackagesByStatus(status.name());
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String> 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;
|
||||
}
|
||||
|
|
|
|||
28
src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java
Normal file
28
src/main/java/ru/nbch/credit_tracker/utils/ZipUtils.java
Normal file
|
|
@ -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<ZipEntry> extractValidEntry(ZipInputStream inputStream) throws IOException {
|
||||
Optional<ZipEntry> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
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;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalServerException;
|
||||
|
||||
public class ExceptionUtils {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package ru.nbch.credit_tracker.utils.error;
|
||||
|
||||
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 %s", errorMessage.getSubject().getKey(), Arrays.toString(errorMessage.getArgs()));
|
||||
}
|
||||
}
|
||||
16
src/main/resources/mybatis/mapper/signal/HitsMapper.xml
Normal file
16
src/main/resources/mybatis/mapper/signal/HitsMapper.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="ru.nbch.credit_tracker.mapper.signal.HitsMapper">
|
||||
|
||||
<insert id="insertHits" parameterType="java.util.List">
|
||||
INSERT INTO signals_hits (package_id, subject_id, signal_type, response_sent_at, report_file_name)
|
||||
values
|
||||
<foreach collection="hits" item="hit" separator=",">
|
||||
(#{hit.packageId}, #{hit.subjectId}, #{hit.signalType}, #{hit.responseSentAt}, #{hit.reportFileName})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper">
|
||||
|
||||
<resultMap id="PhoneFidMapResultMap" type="ru.nbch.credit_tracker.entities.dto.PhoneFidMap">
|
||||
<result property="id" column="id"/>
|
||||
<result property="packageId" column="package_id"/>
|
||||
<result property="subjectId" column="subject_id"/>
|
||||
<result property="phone" column="phone"/>
|
||||
<result property="fid" column="fid"/>
|
||||
<result property="flagDebt5000" column="flag_debt5000"/>
|
||||
<result property="flag90days" column="flag_90_12"/>
|
||||
<result property="calculatedAt" column="calculated_at"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="registerSubjects" parameterType="java.util.List">
|
||||
INSERT INTO signals_phone_fid_map (subject_id, phone, fid, package_id)
|
||||
values
|
||||
<foreach collection="subjects" item="subject" separator=",">
|
||||
(#{subject.id}, #{subject.clientId}, NULL, #{packageId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
|
||||
<update id="updatePhoneFidMaps" parameterType="java.util.List">
|
||||
<foreach collection="subjects" item="subject" separator=";">
|
||||
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}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<select id="findPhoneFidMaps" resultMap="PhoneFidMapResultMap" resultType="java.util.List">
|
||||
SELECT id, subject_id, phone
|
||||
FROM signals_phone_fid_map
|
||||
WHERE package_id = #{packageId}
|
||||
</select>
|
||||
|
||||
<select id="findFullPhoneFidMap" resultMap="PhoneFidMapResultMap" resultType="java.util.List">
|
||||
SELECT id,
|
||||
package_id,
|
||||
subject_id,
|
||||
phone,
|
||||
fid,
|
||||
flag_90_12,
|
||||
flag_debt5000,
|
||||
calculated_at
|
||||
FROM signals_phone_fid_map
|
||||
WHERE package_id = #{packageId}
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="ru.nbch.credit_tracker.mapper.signal.SignalMapper">
|
||||
|
||||
<resultMap id="subjectDataResultMap" type="ru.nbch.credit_tracker.entities.dto.SubjectData">
|
||||
<result property="id" column="id"/>
|
||||
<result property="packageId" column="package_id"/>
|
||||
<result property="subjectId" column="subject_id"/>
|
||||
<result property="phone" column="phone"/>
|
||||
<result property="fid" column="fid"/>
|
||||
<result property="flagDebt5000" column="flag_debt5000"/>
|
||||
<result property="flag90days" column="flag_90_12"/>
|
||||
<result property="calculatedAt" column="calculated_at"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="packageDataResultMap" type="ru.nbch.credit_tracker.entities.dto.PackageData">
|
||||
<result property="id" column="id"/>
|
||||
<result property="userId" column="membercode"/>
|
||||
<result property="packageName" column="package_name"/>
|
||||
<result property="createdAt" column="created_at"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="lastDownloadedReport" column="last_downloaded_report"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="isPackageNotUnique" resultType="boolean">
|
||||
SELECT COUNT(*) > 0
|
||||
FROM signals_user_packages
|
||||
WHERE membercode IS NOT NULL
|
||||
AND LEFT(membercode, 6) = #{userId}
|
||||
AND package_name = #{packageName}
|
||||
</select>
|
||||
|
||||
<select id="isPackageExists" resultType="boolean">
|
||||
SELECT COUNT(*) > 0
|
||||
FROM signals_user_packages
|
||||
WHERE membercode IS NOT NULL
|
||||
AND LEFT(membercode, 6) = #{userId}
|
||||
AND package_name = #{packageName}
|
||||
AND status = #{status}
|
||||
</select>
|
||||
|
||||
<update id="deletePackage">
|
||||
UPDATE signals_user_packages
|
||||
SET status = #{status}, deactivated_at = #{deactivatedAt}
|
||||
WHERE membercode IS NOT NULL AND LEFT(membercode, 6) = #{userId} AND package_name = #{packageName} AND status =
|
||||
#{previousStatus}
|
||||
</update>
|
||||
|
||||
<select id="registerPackage" resultType="java.lang.Integer"
|
||||
parameterType="ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest">
|
||||
INSERT INTO signals_user_packages (membercode, package_name, created_at, status)
|
||||
values (#{request.userId}, #{request.packageName}, #{creadedAt}, #{status}) RETURNING id
|
||||
</select>
|
||||
|
||||
<insert id="insertPackage"
|
||||
parameterType="ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest">
|
||||
INSERT INTO signals_user_packages (membercode, package_name, created_at, status)
|
||||
values (#{request.userId}, #{request.packageName}, #{creadedAt}, #{status})
|
||||
</insert>
|
||||
|
||||
<insert id="registerSubjects" parameterType="java.util.List">
|
||||
INSERT INTO signals_phone_fid_map (subject_id, phone, fid, package_id)
|
||||
values
|
||||
<foreach collection="subjects" item="subject" separator=",">
|
||||
(#{subject.id}, #{subject.clientId}, NULL, #{packageId})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<insert id="setHits" parameterType="java.util.List">
|
||||
INSERT INTO signals_hits (package_id, subject_id, signal_type, response_sent_at, report_file_name)
|
||||
values
|
||||
<foreach collection="hits" item="hit" separator=",">
|
||||
(#{hit.packageId}, #{hit.subjectId}, #{hit.signalType}, #{hit.responseSentAt}, #{hit.reportFileName})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<update id="updateSubjects" parameterType="java.util.List">
|
||||
<foreach collection="subjects" item="subject" separator=";">
|
||||
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}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<update id="registerSubjectsFidAndDebts">
|
||||
UPDATE signals_phone_fid_map
|
||||
SET fid = #{fid}, flag_debt5000 = #{flagDebt5000}, flag_90_12 = #{flag90}, calculated_at = #{calculatedAt}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="setPackageStatus">
|
||||
UPDATE signals_user_packages
|
||||
SET status = #{status}
|
||||
WHERE id = #{packageId}
|
||||
</update>
|
||||
|
||||
<update id="setPackageLastDownloadedReport">
|
||||
UPDATE signals_user_packages
|
||||
SET last_downloaded_report = #{fileName}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="findSubjectsData" resultMap="subjectDataResultMap" resultType="java.util.List">
|
||||
SELECT id, subject_id, phone
|
||||
FROM signals_phone_fid_map
|
||||
WHERE package_id = #{packageId}
|
||||
</select>
|
||||
|
||||
<select id="findFullSubjectsData" resultMap="subjectDataResultMap" resultType="java.util.List">
|
||||
SELECT id,
|
||||
package_id,
|
||||
subject_id,
|
||||
phone,
|
||||
fid,
|
||||
flag_90_12,
|
||||
flag_debt5000,
|
||||
calculated_at
|
||||
FROM signals_phone_fid_map
|
||||
WHERE package_id = #{packageId}
|
||||
</select>
|
||||
|
||||
<select id="findPackageData" resultMap="packageDataResultMap"
|
||||
resultType="ru.nbch.credit_tracker.entities.dto.PackageData">
|
||||
SELECT membercode, package_name
|
||||
FROM signals_user_packages
|
||||
WHERE id = #{id}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="findPackageDataList" resultMap="packageDataResultMap"
|
||||
resultType="ru.nbch.credit_tracker.entities.dto.PackageData">
|
||||
SELECT package_name, created_at
|
||||
FROM signals_user_packages
|
||||
WHERE membercode IS NOT NULL
|
||||
AND LEFT(membercode, 6) = #{userId}
|
||||
AND status = #{status}
|
||||
</select>
|
||||
|
||||
<select id="findPackagesByStatus" resultMap="packageDataResultMap"
|
||||
resultType="ru.nbch.credit_tracker.entities.dto.PackageData">
|
||||
SELECT id, membercode, package_name, created_at, last_downloaded_report
|
||||
FROM signals_user_packages
|
||||
WHERE status = #{status}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="ru.nbch.credit_tracker.mapper.signal.UserPackageMapper">
|
||||
|
||||
<resultMap id="packageDataResultMap" type="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||
<result property="id" column="id"/>
|
||||
<result property="userId" column="membercode"/>
|
||||
<result property="packageName" column="package_name"/>
|
||||
<result property="createdAt" column="created_at"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="lastDownloadedReport" column="last_downloaded_report"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="isPackageNotUnique" resultType="boolean">
|
||||
SELECT COUNT(*) > 0
|
||||
FROM signals_user_packages
|
||||
WHERE membercode IS NOT NULL
|
||||
AND LEFT(membercode, 6) = #{userId}
|
||||
AND package_name = #{packageName}
|
||||
</select>
|
||||
|
||||
<select id="isPackageExists" resultType="boolean">
|
||||
SELECT COUNT(*) > 0
|
||||
FROM signals_user_packages
|
||||
WHERE membercode IS NOT NULL
|
||||
AND LEFT(membercode, 6) = #{userId}
|
||||
AND package_name = #{packageName}
|
||||
AND status = #{status}
|
||||
</select>
|
||||
|
||||
<update id="deletePackage">
|
||||
UPDATE signals_user_packages
|
||||
SET status = #{status}, deactivated_at = #{deactivatedAt}
|
||||
WHERE membercode IS NOT NULL AND LEFT(membercode, 6) = #{userId} AND package_name = #{packageName} AND status =
|
||||
#{previousStatus}
|
||||
</update>
|
||||
|
||||
<select id="insertPackage" resultType="java.lang.Integer"
|
||||
parameterType="ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest">
|
||||
INSERT INTO signals_user_packages (membercode, package_name, created_at, status)
|
||||
values (#{userPackage.userId}, #{userPackage.packageName}, #{userPackage.createdAt}, #{userPackage.status}) RETURNING id
|
||||
</select>
|
||||
|
||||
<update id="updatePackageStatus">
|
||||
UPDATE signals_user_packages
|
||||
SET status = #{status}
|
||||
WHERE id = #{packageId}
|
||||
</update>
|
||||
|
||||
<update id="updatePackageLastDownloadedReport">
|
||||
UPDATE signals_user_packages
|
||||
SET last_downloaded_report = #{fileName}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="findPackage" resultMap="packageDataResultMap"
|
||||
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||
SELECT membercode, package_name
|
||||
FROM signals_user_packages
|
||||
WHERE id = #{id}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="findUserPackages" resultMap="packageDataResultMap"
|
||||
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||
SELECT package_name, created_at
|
||||
FROM signals_user_packages
|
||||
WHERE membercode IS NOT NULL
|
||||
AND LEFT(membercode, 6) = #{userId}
|
||||
AND status = #{status}
|
||||
</select>
|
||||
|
||||
<select id="findAllPackagesByStatus" resultMap="packageDataResultMap"
|
||||
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||
SELECT id, membercode, package_name, created_at, last_downloaded_report
|
||||
FROM signals_user_packages
|
||||
WHERE status = #{status}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
156
src/test/java/ru/nbch/credit_tracker/utils/UtilTest.java
Normal file
156
src/test/java/ru/nbch/credit_tracker/utils/UtilTest.java
Normal file
|
|
@ -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<Arguments> 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<ZipEntry> 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<Arguments> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
src/test/resources/monitoring_request/directory_request.zip
Normal file
BIN
src/test/resources/monitoring_request/directory_request.zip
Normal file
Binary file not shown.
0
src/test/resources/monitoring_request/empty_request.zip
Normal file
0
src/test/resources/monitoring_request/empty_request.zip
Normal file
BIN
src/test/resources/monitoring_request/invalid_id_request.zip
Normal file
BIN
src/test/resources/monitoring_request/invalid_id_request.zip
Normal file
Binary file not shown.
BIN
src/test/resources/monitoring_request/invalid_phone_request.zip
Normal file
BIN
src/test/resources/monitoring_request/invalid_phone_request.zip
Normal file
Binary file not shown.
BIN
src/test/resources/monitoring_request/invalid_xml.zip
Normal file
BIN
src/test/resources/monitoring_request/invalid_xml.zip
Normal file
Binary file not shown.
BIN
src/test/resources/monitoring_request/many_files_request.zip
Normal file
BIN
src/test/resources/monitoring_request/many_files_request.zip
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/test/resources/monitoring_request/no_unique_ids_request.zip
Normal file
BIN
src/test/resources/monitoring_request/no_unique_ids_request.zip
Normal file
Binary file not shown.
BIN
src/test/resources/monitoring_request/txt_request.zip
Normal file
BIN
src/test/resources/monitoring_request/txt_request.zip
Normal file
Binary file not shown.
BIN
src/test/resources/monitoring_request/valid_request.zip
Normal file
BIN
src/test/resources/monitoring_request/valid_request.zip
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue