Merge branch 'review' into 'dev'
Refactoring after review See merge request nbki/credit_tracker!1
This commit is contained in:
commit
a72930d1af
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.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
|
import ru.nbch.credit_tracker.entities.response.errors.*;
|
||||||
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
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;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
@ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
private final SimpleMessageResolver messageResolver = new SimpleMessageResolver();
|
||||||
public ResponseEntity<CommonError> handleInvalidUser(SignalErrorException ex) {
|
|
||||||
|
@ExceptionHandler(value = SignalException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
|
public ResponseEntity<CommonError> handleClientException(SignalException ex) {
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251")));
|
headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251")));
|
||||||
if (ex.isUserError()) {
|
CommonError commonError = getCommonError(ex);
|
||||||
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.BAD_REQUEST);
|
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 {
|
} 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 jakarta.xml.bind.JAXBException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.xml.sax.SAXException;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||||
import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.MonitoringSignalResponse;
|
import ru.nbch.credit_tracker.entities.response.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.online_report.SgnlOnlineReport;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
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.SgnlReportStatusStaxReader;
|
||||||
import ru.nbch.credit_tracker.service.xml.stax.StaxReader;
|
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.StaxXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.service.xml.stax.XmlProcessorStaxImpl;
|
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.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
@Configuration
|
||||||
|
public class XmlConfig {
|
||||||
|
|
||||||
@Service
|
@Bean
|
||||||
public class XmlUtilService {
|
public IXmlProcessor xmlProcessor() throws JAXBException {
|
||||||
|
|
||||||
public IXmlProcessor createJaxbProcessor() throws JAXBException {
|
|
||||||
return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"),
|
return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"),
|
||||||
// unmarshalling classes
|
// unmarshalling classes
|
||||||
MonitoringRequest.class,
|
MonitoringRequest.class,
|
||||||
|
|
@ -48,24 +38,10 @@ public class XmlUtilService {
|
||||||
MonitoringSignalResponse.class);
|
MonitoringSignalResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
public StaxXmlProcessor staxXmlProcessor() {
|
public StaxXmlProcessor staxXmlProcessor() {
|
||||||
List<StaxReader<?>> staxReader = new ArrayList<>();
|
List<StaxReader<?>> staxReader = new ArrayList<>();
|
||||||
staxReader.add(new SgnlReportStatusStaxReader());
|
staxReader.add(new SgnlReportStatusStaxReader());
|
||||||
return new XmlProcessorStaxImpl(staxReader);
|
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
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class HitsData {
|
public class Hit {
|
||||||
private Integer id;
|
private Integer id;
|
||||||
private Integer packageId;
|
private Integer packageId;
|
||||||
private String subjectId;
|
private String subjectId;
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.entities.dto;
|
package ru.nbch.credit_tracker.entities.dto;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
|
@ -11,7 +8,8 @@ import java.time.LocalDateTime;
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class SubjectData {
|
@Builder
|
||||||
|
public class PhoneFidMap {
|
||||||
private Integer id;
|
private Integer id;
|
||||||
private Integer packageId;
|
private Integer packageId;
|
||||||
private String subjectId;
|
private String subjectId;
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.entities.dto;
|
package ru.nbch.credit_tracker.entities.dto;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
|
@ -7,7 +8,8 @@ import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class PackageData {
|
@Builder
|
||||||
|
public class UserPackage {
|
||||||
private Integer id;
|
private Integer id;
|
||||||
private String userId;
|
private String userId;
|
||||||
private String packageName;
|
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;
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
import lombok.Getter;
|
public enum SignalError implements IEnumKeyCode {
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum SignalError {
|
|
||||||
ERROR_001("001", "Ошибка распаковки архива"),
|
ERROR_001("001", "Ошибка распаковки архива"),
|
||||||
ERROR_002("002", "Отсутствует обязательный элемент: "),
|
ERROR_002("002", "Отсутствует обязательный элемент: "),
|
||||||
ERROR_003("003", "Элемент ClientId не соответствует формату XXXXXXXXX"),
|
ERROR_003("003", "Элемент ClientId не соответствует формату XXXXXXXXX"),
|
||||||
|
|
@ -31,4 +28,16 @@ public enum SignalError {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = message;
|
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.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
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.active_packages.MonitoringActivePackagesRequest;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
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.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.MonitoringPackageDeleteResponse;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse;
|
import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||||
import ru.nbch.credit_tracker.enums.SignalError;
|
import ru.nbch.credit_tracker.enums.SignalError;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
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.SignalService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||||
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
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.IXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
import ru.nbch.credit_tracker.utils.ValidationUtil;
|
import ru.nbch.credit_tracker.utils.ValidationUtil;
|
||||||
|
import ru.nbch.credit_tracker.utils.ZipUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashSet;
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
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
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class SignalFacade {
|
public class SignalFacade {
|
||||||
|
|
@ -46,7 +52,7 @@ public class SignalFacade {
|
||||||
private final AuthorizationService authorizationService;
|
private final AuthorizationService authorizationService;
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
private final XmlUtilService xmlUtilService;
|
private final IXmlProcessor xmlProcessor;
|
||||||
|
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
|
||||||
|
|
@ -55,89 +61,62 @@ public class SignalFacade {
|
||||||
AuthorizationService authorizationService,
|
AuthorizationService authorizationService,
|
||||||
SignalService signalService,
|
SignalService signalService,
|
||||||
SignalRestService signalRestService,
|
SignalRestService signalRestService,
|
||||||
XmlUtilService xmlUtilService,
|
IXmlProcessor xmlProcessor,
|
||||||
@Qualifier("executorService") ExecutorService executor) {
|
@Qualifier("executorService") ExecutorService executor) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.authorizationService = authorizationService;
|
this.authorizationService = authorizationService;
|
||||||
this.signalService = signalService;
|
this.signalService = signalService;
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
this.xmlUtilService = xmlUtilService;
|
this.xmlProcessor = xmlProcessor;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<MonitoringResponse> setupMonitoring(MultipartFile file) {
|
public ResponseEntity<MonitoringResponse> setupMonitoring(MultipartFile file) {
|
||||||
// первичные валидации
|
// первичные валидации
|
||||||
if (file.isEmpty()) {
|
if (file.isEmpty() || !isZipFile(file)) {
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||||
}
|
|
||||||
|
|
||||||
if (!isZipFile(file)) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Валидация Архива на количетсво файлов, размер и расширение
|
// Валидация Архива на количетсво файлов, размер и расширение
|
||||||
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;
|
MonitoringRequest monitoringRequest;
|
||||||
Integer packageId;
|
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();
|
zipInputStream.getNextEntry();
|
||||||
|
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
monitoringRequest = xmlProcessor.read(zipInputStream, MonitoringRequest.class);
|
||||||
monitoringRequest = processor.read(zipInputStream, MonitoringRequest.class);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), 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
|
// валидация xml
|
||||||
try {
|
try {
|
||||||
validateMonitoringRequest(monitoringRequest);
|
ValidationUtil.validateMonitoringRequest(monitoringRequest);
|
||||||
} catch (SignalErrorException e) {
|
} catch (SignalClientException e) {
|
||||||
signalService.rejectPackage(monitoringRequest);
|
signalService.rejectPackage(monitoringRequest);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
@ -147,22 +126,22 @@ public class SignalFacade {
|
||||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword());
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword());
|
||||||
if (!authResult.isSuccess()) {
|
if (!authResult.isSuccess()) {
|
||||||
signalService.rejectPackage(monitoringRequest);
|
signalService.rejectPackage(monitoringRequest);
|
||||||
throw new SignalErrorException(authResult.getError(), null, new MonitoringError(), true);
|
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// проверка на уникальность пакета
|
// проверка на уникальность пакета
|
||||||
if (signalService.isPackageNotUnique(monitoringRequest)) {
|
if (signalService.isPackageNotUnique(monitoringRequest)) {
|
||||||
signalService.rejectPackage(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);
|
packageId = signalService.registerPackage(monitoringRequest);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), 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());
|
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) {
|
private void registerFidsAndDebts(Integer packageId, String packageName) {
|
||||||
executor.execute(() -> {
|
executor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
|
|
@ -232,14 +159,14 @@ public class SignalFacade {
|
||||||
// TODO validate xsd?
|
// TODO validate xsd?
|
||||||
if (signalRestService.update(signals)) {
|
if (signalRestService.update(signals)) {
|
||||||
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
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 {
|
} else {
|
||||||
log.info("Package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
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) {
|
} catch (Exception e) {
|
||||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||||
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -255,46 +182,65 @@ public class SignalFacade {
|
||||||
try {
|
try {
|
||||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
||||||
if (!authResult.isSuccess()) {
|
if (!authResult.isSuccess()) {
|
||||||
throw new SignalErrorException(authResult.getError(), null, new MonitoringActivePackagesError(), true);
|
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringActivePackagesError);
|
||||||
}
|
}
|
||||||
MonitoringActivePackagesResponse response = signalService.findActivePackages(activePackagesRequest.getUserId());
|
List<UserPackage> activePackages = signalService.findActivePackages(activePackagesRequest.getUserId());
|
||||||
if (response != null) {
|
|
||||||
|
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);
|
return ResponseEntity.ok(response);
|
||||||
} else {
|
} else {
|
||||||
throw new SignalErrorException(SignalError.ERROR_015, null, new MonitoringActivePackagesError(), true);
|
throw clientExcp(SignalError.ERROR_015, XmlErrorFormat.MonitoringActivePackagesError);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), 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) {
|
public ResponseEntity<MonitoringPackageDeleteResponse> deletePackage(String username, String packageName) {
|
||||||
try {
|
try {
|
||||||
if (!signalService.isPackageExists(username, packageName)) {
|
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);
|
signalRestService.deletePackage(username, packageName);
|
||||||
log.info("Package {} deleted", packageName);
|
log.info("Package {} deleted", packageName);
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), 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) {
|
public ResponseEntity<MonitoringReportListResponse> getReportList(String username, String packageName) {
|
||||||
try {
|
try {
|
||||||
if (!signalService.isPackageExists(username, packageName)) {
|
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);
|
String memberCode = username.substring(0, 6);
|
||||||
|
|
@ -306,7 +252,7 @@ public class SignalFacade {
|
||||||
MonitoringReportListResponse.Reports reports = new MonitoringReportListResponse.Reports();
|
MonitoringReportListResponse.Reports reports = new MonitoringReportListResponse.Reports();
|
||||||
File[] files = folder.listFiles();
|
File[] files = folder.listFiles();
|
||||||
if (files == null) {
|
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) {
|
for (File file : files) {
|
||||||
if (file.isFile() && file.getName().startsWith(filePrefix)) {
|
if (file.isFile() && file.getName().startsWith(filePrefix)) {
|
||||||
|
|
@ -315,7 +261,7 @@ public class SignalFacade {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reports.getReports().isEmpty()) {
|
if (reports.getReports().isEmpty()) {
|
||||||
throw new SignalErrorException(SignalError.ERROR_012, packageName, new MonitoringReportListError(), true);
|
throw clientExcp(SignalError.ERROR_012, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||||
} else {
|
} else {
|
||||||
MonitoringReportListResponse response = new MonitoringReportListResponse();
|
MonitoringReportListResponse response = new MonitoringReportListResponse();
|
||||||
response.setPackageName(packageName);
|
response.setPackageName(packageName);
|
||||||
|
|
@ -324,14 +270,14 @@ public class SignalFacade {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("Пакет {} был найден в бд для memberCode {}, но ни одного архива не было найдено в папке {}", packageName, username, dirPath);
|
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) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), 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()));
|
return ResponseEntity.ok().body(new FileUrlResource(file.getPath()));
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), 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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.dto.HitsData;
|
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
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.monitoring_signal_response.*;
|
||||||
import ru.nbch.credit_tracker.entities.response.online_download.Inquiry;
|
import ru.nbch.credit_tracker.entities.response.online_download.Inquiry;
|
||||||
import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadReport;
|
import ru.nbch.credit_tracker.entities.response.online_download.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.entities.response.online_report.SgnlOnlineReport;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
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.IXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
@ -36,16 +35,16 @@ public class MonitoringService {
|
||||||
|
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final XmlUtilService xmlUtilService;
|
private final IXmlProcessor xmlProcessor;
|
||||||
private final CreditTrackerSettings config;
|
private final CreditTrackerSettings config;
|
||||||
|
|
||||||
public MonitoringService(SignalRestService signalRestService,
|
public MonitoringService(SignalRestService signalRestService,
|
||||||
SignalService signalService,
|
SignalService signalService,
|
||||||
XmlUtilService xmlUtilService,
|
IXmlProcessor xmlProcessor,
|
||||||
CreditTrackerSettings config) {
|
CreditTrackerSettings config) {
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
this.signalService = signalService;
|
this.signalService = signalService;
|
||||||
this.xmlUtilService = xmlUtilService;
|
this.xmlProcessor = xmlProcessor;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,13 +56,13 @@ public class MonitoringService {
|
||||||
|
|
||||||
private void monitor() {
|
private void monitor() {
|
||||||
log.info("Start monitoring");
|
log.info("Start monitoring");
|
||||||
List<PackageData> packages = signalService.findPackagesOnMonitoring();
|
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||||
for (PackageData packageData : packages) {
|
for (UserPackage userPackage : packages) {
|
||||||
log.info("Processing package {}", packageData.getPackageName());
|
log.info("Processing package {}", userPackage.getPackageName());
|
||||||
SgnlOnlineReport onlineReports = signalRestService.getReports(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName());
|
SgnlOnlineReport onlineReports = signalRestService.getReports(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName());
|
||||||
|
|
||||||
if (onlineReports == null) {
|
if (onlineReports == null) {
|
||||||
log.info("No reports found for package {}", packageData.getPackageName());
|
log.info("No reports found for package {}", userPackage.getPackageName());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +70,7 @@ public class MonitoringService {
|
||||||
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать
|
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать
|
||||||
|
|
||||||
if (fileNames.isEmpty()) {
|
if (fileNames.isEmpty()) {
|
||||||
log.info("No new report found for package {}", packageData.getPackageName());
|
log.info("No new report found for package {}", userPackage.getPackageName());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,16 +78,16 @@ public class MonitoringService {
|
||||||
.orElseGet(Collections::emptyList)
|
.orElseGet(Collections::emptyList)
|
||||||
.stream().max(Comparator.comparing(CTUtil::parseDateFromReportFileName)); // отфильтровали только те имена, которые парсятся в дату, так что null тут не придет
|
.stream().max(Comparator.comparing(CTUtil::parseDateFromReportFileName)); // отфильтровали только те имена, которые парсятся в дату, так что null тут не придет
|
||||||
|
|
||||||
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(packageData.getLastDownloadedReport());
|
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(userPackage.getLastDownloadedReport());
|
||||||
|
|
||||||
if (packageData.getLastDownloadedReport() != null) {
|
if (userPackage.getLastDownloadedReport() != null) {
|
||||||
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", packageData.getPackageName(), packageData.getLastDownloadedReport());
|
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", userPackage.getPackageName(), userPackage.getLastDownloadedReport());
|
||||||
} else {
|
} else {
|
||||||
log.info("Last Downloaded Report Name is empty");
|
log.info("Last Downloaded Report Name is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
OnlineDownloadReport report = null;
|
OnlineDownloadReport report = null;
|
||||||
if (packageData.getLastDownloadedReport() == null && newReport.isPresent()) {
|
if (userPackage.getLastDownloadedReport() == null && newReport.isPresent()) {
|
||||||
report = loadReport(newReport.get()); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным
|
report = loadReport(newReport.get()); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным
|
||||||
} else if (lastDownloadedReportDate != null && newReport.isPresent()) {
|
} else if (lastDownloadedReportDate != null && newReport.isPresent()) {
|
||||||
LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport.get());
|
LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport.get());
|
||||||
|
|
@ -97,28 +96,28 @@ public class MonitoringService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (report == null) {
|
if (report == null) {
|
||||||
log.info("Report was not loaded for package {}", packageData.getPackageName());
|
log.info("Report was not loaded for package {}", userPackage.getPackageName());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MonitoringSignalResponse response = generateResponse(packageData, report.getPersons().getPersons());
|
MonitoringSignalResponse response = generateResponse(userPackage, report.getPersons().getPersons());
|
||||||
String fileName = createResponseFile(packageData, response);
|
String fileName = createResponseFile(userPackage, response);
|
||||||
if (fileName != null) {
|
if (fileName != null) {
|
||||||
log.info("New report fileName: {}", fileName);
|
log.info("New report fileName: {}", fileName);
|
||||||
updateSignalHits(packageData, response, fileName);
|
updateSignalHits(userPackage, response, fileName);
|
||||||
signalService.updateLastDownloadedReport(packageData.getId(), newReport.get());
|
signalService.updateLastDownloadedReport(userPackage.getId(), newReport.get());
|
||||||
} else {
|
} 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");
|
log.info("Finish monitoring");
|
||||||
}
|
}
|
||||||
|
|
||||||
private MonitoringSignalResponse generateResponse(PackageData packageData, List<Person> persons) {
|
private MonitoringSignalResponse generateResponse(UserPackage userPackage, List<Person> persons) {
|
||||||
MonitoringSignalResponse response = new MonitoringSignalResponse();
|
MonitoringSignalResponse response = new MonitoringSignalResponse();
|
||||||
response.setPackageName(packageData.getPackageName()); // Имя пакета, переданного при установке
|
response.setPackageName(userPackage.getPackageName()); // Имя пакета, переданного при установке
|
||||||
Subjects subjects = new Subjects();
|
Subjects subjects = new Subjects();
|
||||||
List<SubjectData> subjectDataList = signalService.findFullSubjectsData(packageData.getId());
|
List<PhoneFidMap> phoneFidMapList = signalService.findFullSubjectsData(userPackage.getId());
|
||||||
for (Person person : persons) {
|
for (Person person : persons) {
|
||||||
Signals signals = new Signals();
|
Signals signals = new Signals();
|
||||||
for (Inquiry inquiry : person.getInquiries()) {
|
for (Inquiry inquiry : person.getInquiries()) {
|
||||||
|
|
@ -135,7 +134,7 @@ public class MonitoringService {
|
||||||
|
|
||||||
// Если есть хотя бы один заполненный сигнал, значит заполняем остальные данные
|
// Если есть хотя бы один заполненный сигнал, значит заполняем остальные данные
|
||||||
if (!signals.getSignals().isEmpty()) {
|
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 subject = new Subject();
|
||||||
subject.setId(subjectData.getSubjectId()); // Уникальный идентификатор субъекта (равен Id из XML-пакета при установке мониторинга)
|
subject.setId(subjectData.getSubjectId()); // Уникальный идентификатор субъекта (равен Id из XML-пакета при установке мониторинга)
|
||||||
subject.setClientId(subjectData.getPhone());
|
subject.setClientId(subjectData.getPhone());
|
||||||
|
|
@ -150,18 +149,17 @@ public class MonitoringService {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createResponseFile(PackageData packageData, MonitoringSignalResponse response) {
|
private String createResponseFile(UserPackage userPackage, MonitoringSignalResponse response) {
|
||||||
try {
|
try {
|
||||||
String fileName = CTUtil.generateResponseReportFileName(packageData.getUserId(), packageData.getPackageName());
|
String fileName = CTUtil.generateResponseReportFileName(userPackage.getUserId(), userPackage.getPackageName());
|
||||||
String filePath = config.getLoadDir() + File.separator + packageData.getUserId().substring(0, 6) + File.separator;
|
String filePath = config.getLoadDir() + File.separator + userPackage.getUserId().substring(0, 6) + File.separator;
|
||||||
|
|
||||||
File folder = new File(filePath);
|
File folder = new File(filePath);
|
||||||
if (!folder.exists()) {
|
if (!folder.exists()) {
|
||||||
folder.mkdir();
|
folder.mkdir();
|
||||||
}
|
}
|
||||||
|
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
String xmlStr = xmlProcessor.asString(response, true);
|
||||||
String xmlStr = processor.asString(response, true);
|
|
||||||
|
|
||||||
byte[] xmlBytes = xmlStr.getBytes(Charset.forName("windows-1251"));
|
byte[] xmlBytes = xmlStr.getBytes(Charset.forName("windows-1251"));
|
||||||
try (FileOutputStream fos = new FileOutputStream(filePath + fileName + ".zip");
|
try (FileOutputStream fos = new FileOutputStream(filePath + fileName + ".zip");
|
||||||
|
|
@ -179,23 +177,23 @@ public class MonitoringService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSignalHits(PackageData packageData, MonitoringSignalResponse response, String reportFileName) {
|
private void updateSignalHits(UserPackage userPackage, MonitoringSignalResponse response, String reportFileName) {
|
||||||
log.info("Updating signal hits for {}", packageData.getPackageName());
|
log.info("Updating signal hits for {}", userPackage.getPackageName());
|
||||||
LocalDateTime responseSentAt = LocalDateTime.now();
|
LocalDateTime responseSentAt = LocalDateTime.now();
|
||||||
List<HitsData> hits = new ArrayList<>();
|
List<Hit> hits = new ArrayList<>();
|
||||||
response.getSubjects().getSubjects().forEach(subject -> {
|
response.getSubjects().getSubjects().forEach(subject -> {
|
||||||
subject.getSignals().getSignals().forEach(signal -> {
|
subject.getSignals().getSignals().forEach(signal -> {
|
||||||
HitsData hitsData = new HitsData();
|
Hit hit = new Hit();
|
||||||
hitsData.setPackageId(packageData.getId());
|
hit.setPackageId(userPackage.getId());
|
||||||
hitsData.setSubjectId(subject.getId());
|
hit.setSubjectId(subject.getId());
|
||||||
hitsData.setSignalType(1);
|
hit.setSignalType(1);
|
||||||
hitsData.setResponseSentAt(responseSentAt);
|
hit.setResponseSentAt(responseSentAt);
|
||||||
hitsData.setReportFileName(reportFileName);
|
hit.setReportFileName(reportFileName);
|
||||||
hits.add(hitsData);
|
hits.add(hit);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
signalService.setHits(hits);
|
signalService.insertHits(hits);
|
||||||
log.info("Signal hits updated for package {}", packageData.getPackageName());
|
log.info("Signal hits updated for package {}", userPackage.getPackageName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private OnlineDownloadReport loadReport(String reportName) {
|
private OnlineDownloadReport loadReport(String reportName) {
|
||||||
|
|
@ -206,8 +204,7 @@ public class MonitoringService {
|
||||||
OnlineDownloadReport report;
|
OnlineDownloadReport report;
|
||||||
try (GZIPInputStream zipInputStream = new GZIPInputStream(new ByteArrayInputStream(archive))) {
|
try (GZIPInputStream zipInputStream = new GZIPInputStream(new ByteArrayInputStream(archive))) {
|
||||||
|
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
report = xmlProcessor.read(zipInputStream, OnlineDownloadReport.class);
|
||||||
report = processor.read(zipInputStream, OnlineDownloadReport.class);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,25 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
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.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.dto.HitsData;
|
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
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.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
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.Auth;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Person;
|
import ru.nbch.credit_tracker.entities.signal_package.Person;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
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.FlagsService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PersonService;
|
import ru.nbch.credit_tracker.service.indic.PersonService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
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.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -36,10 +30,10 @@ import java.util.Objects;
|
||||||
@Service
|
@Service
|
||||||
public class SignalService {
|
public class SignalService {
|
||||||
|
|
||||||
private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy");
|
|
||||||
|
|
||||||
private final CreditTrackerSettings config;
|
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 PhoneService phoneService;
|
||||||
private final FlagsService flagsService;
|
private final FlagsService flagsService;
|
||||||
private final PersonService personService;
|
private final PersonService personService;
|
||||||
|
|
@ -47,53 +41,77 @@ public class SignalService {
|
||||||
private final int batchSize = 10000;
|
private final int batchSize = 10000;
|
||||||
|
|
||||||
public SignalService(CreditTrackerSettings config,
|
public SignalService(CreditTrackerSettings config,
|
||||||
SignalMapper mapper,
|
HitsService hitsService,
|
||||||
|
UserPackageService userPackageService,
|
||||||
|
PhoneFidMapService phoneFidMapService,
|
||||||
PhoneService phoneService,
|
PhoneService phoneService,
|
||||||
FlagsService flagsService,
|
FlagsService flagsService,
|
||||||
PersonService personService) {
|
PersonService personService) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.mapper = mapper;
|
this.hitsService = hitsService;
|
||||||
|
this.userPackageService = userPackageService;
|
||||||
|
this.phoneFidMapService = phoneFidMapService;
|
||||||
this.phoneService = phoneService;
|
this.phoneService = phoneService;
|
||||||
this.flagsService = flagsService;
|
this.flagsService = flagsService;
|
||||||
this.personService = personService;
|
this.personService = personService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPackageNotUnique(MonitoringRequest request) {
|
public boolean isPackageNotUnique(MonitoringRequest request) {
|
||||||
String userId = request.getUserId();
|
return userPackageService.isPackageNotUnique(request.getUserId(), request.getPackageName());
|
||||||
return mapper.isPackageNotUnique(userId.substring(0, 6), request.getPackageName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer registerPackage(MonitoringRequest request) {
|
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();
|
List<Subject> subjects = request.getSubjects().getSubject();
|
||||||
for (int i = 0; i < subjects.size(); i += batchSize) {
|
for (int i = 0; i < subjects.size(); i += batchSize) {
|
||||||
int end = Math.min(i + batchSize, subjects.size());
|
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;
|
return packageId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PhoneService.FidsPhoneData> registerSubjectsFidAndDebts(Integer packageId) {
|
public List<PhoneService.FidsPhoneData> registerSubjectsFidAndDebts(Integer packageId) {
|
||||||
List<SubjectData> subjects = mapper.findSubjectsData(packageId);
|
List<PhoneFidMap> subjects = phoneFidMapService.findPhoneFidMaps(packageId);
|
||||||
return updateFlags(subjects, packageId);
|
return updateFlags(subjects, packageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PhoneService.FidsPhoneData> updateFlags(List<SubjectData> subjects, Integer packageId) {
|
public List<PhoneService.FidsPhoneData> updateFlags(List<PhoneFidMap> subjects, Integer packageId) {
|
||||||
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(subjects, true);
|
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(subjects);
|
||||||
LocalDateTime calculatedAt = LocalDateTime.now();
|
LocalDateTime calculatedAt = LocalDateTime.now();
|
||||||
for (int i = 0; i < fidsPhoneDataList.size(); i += batchSize) {
|
for (int i = 0; i < fidsPhoneDataList.size(); i += batchSize) {
|
||||||
int end = Math.min(i + batchSize, fidsPhoneDataList.size());
|
int end = Math.min(i + batchSize, fidsPhoneDataList.size());
|
||||||
List<PhoneService.FidsPhoneData> currentList = fidsPhoneDataList.subList(i, end);
|
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());
|
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 -> {
|
currentList.forEach(data -> {
|
||||||
SubjectData subject;
|
PhoneFidMap subject;
|
||||||
if (data.getFid() != null) {
|
if (data.getFid() != null) {
|
||||||
FlagsService.FlagsData flagsData = flagsDataMap.get(data.getFid());
|
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 {
|
} 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);
|
subjectToUpdate.add(subject);
|
||||||
});
|
});
|
||||||
|
|
@ -101,7 +119,7 @@ public class SignalService {
|
||||||
int updateBatchSize = batchSize / 8; // 8 параметров на одну запись для обновления. Максимальное количество параметров ~65000
|
int updateBatchSize = batchSize / 8; // 8 параметров на одну запись для обновления. Максимальное количество параметров ~65000
|
||||||
for (int j = 0; j < subjectToUpdate.size(); j += updateBatchSize) {
|
for (int j = 0; j < subjectToUpdate.size(); j += updateBatchSize) {
|
||||||
int endIndex = Math.min(j + updateBatchSize, subjectToUpdate.size());
|
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) {
|
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) {
|
public void updatePackageStatus(Integer packageId, Status status) {
|
||||||
mapper.setPackageStatus(packageId, status.name());
|
userPackageService.updatePackageStatus(packageId, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Signals buildSignals(Integer packageId, List<PhoneService.FidsPhoneData> fids) {
|
public Signals buildSignals(Integer packageId, List<PhoneService.FidsPhoneData> fids) {
|
||||||
PackageData packageData = mapper.findPackageData(packageId);
|
UserPackage userPackage = userPackageService.findPackage(packageId);
|
||||||
Signals signals = new Signals();
|
Signals signals = new Signals();
|
||||||
signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы)
|
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 auth = new Auth();
|
||||||
auth.setUser(config.getSignalsuser());
|
auth.setUser(config.getSignalsuser());
|
||||||
signals.setAuth(auth);
|
signals.setAuth(auth);
|
||||||
|
|
@ -143,7 +167,10 @@ public class SignalService {
|
||||||
fidsPhoneData.forEach(data -> {
|
fidsPhoneData.forEach(data -> {
|
||||||
if (data.getFid() != null) {
|
if (data.getFid() != null) {
|
||||||
PersonService.PersonData personData = personFidMap.get(data.getFid());
|
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) {
|
if (person != null) {
|
||||||
persons.add(person);
|
persons.add(person);
|
||||||
}
|
}
|
||||||
|
|
@ -152,101 +179,31 @@ public class SignalService {
|
||||||
return persons;
|
return persons;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Person getPerson(PersonService.PersonData personData, String id) {
|
public List<UserPackage> findActivePackages(String userId) {
|
||||||
if (personData == null) {
|
return userPackageService.findUserPackages(userId, Status.ON_MONITORING);
|
||||||
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 boolean isPackageExists(String username, String packageName) {
|
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) {
|
public void deletePackage(String username, String packageName, LocalDateTime deactivatedAt) {
|
||||||
LocalDateTime deactivatedAt = LocalDateTime.now();
|
userPackageService.deletePackage(username, packageName, Status.DELETED, Status.ON_MONITORING, deactivatedAt);
|
||||||
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 List<PackageData> findPackagesOnMonitoring() {
|
public List<UserPackage> findPackagesOnMonitoring() {
|
||||||
return mapper.findPackagesByStatus(Status.ON_MONITORING.name());
|
return userPackageService.findAllPackagesByStatus(Status.ON_MONITORING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SubjectData> findFullSubjectsData(Integer packageId) {
|
public List<PhoneFidMap> findFullSubjectsData(Integer packageId) {
|
||||||
return mapper.findFullSubjectsData(packageId);
|
return phoneFidMapService.findFullPhoneFidMap(packageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHits(List<HitsData> hits) {
|
public void insertHits(List<Hit> hits) {
|
||||||
mapper.setHits(hits);
|
hitsService.insertHits(hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLastDownloadedReport(Integer id, String fileName) {
|
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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||||
|
|
@ -42,32 +42,32 @@ public class UpdatingFlagsService {
|
||||||
|
|
||||||
private void update() {
|
private void update() {
|
||||||
log.info("Start updating flags");
|
log.info("Start updating flags");
|
||||||
List<PackageData> packages = signalService.findPackagesOnMonitoring();
|
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||||
for (PackageData packageData : packages) {
|
for (UserPackage userPackage : packages) {
|
||||||
log.info("Updating flags for Package {}", packageData.getPackageName());
|
log.info("Updating flags for Package {}", userPackage.getPackageName());
|
||||||
List<SubjectData> subjects = signalService.findFullSubjectsData(packageData.getId())
|
List<PhoneFidMap> subjects = signalService.findFullSubjectsData(userPackage.getId())
|
||||||
.stream().filter(subject -> subject.getCalculatedAt() != null && hasDaysPassed(subject.getCalculatedAt())).toList();
|
.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");
|
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 {
|
try {
|
||||||
signalService.setPackageStatus(packageId, Status.PROCESSING);
|
signalService.updatePackageStatus(packageId, Status.PROCESSING);
|
||||||
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.updateFlags(subjects, packageId);
|
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.updateFlags(subjects, packageId);
|
||||||
if (!phoneFidsData.isEmpty()) {
|
if (!phoneFidsData.isEmpty()) {
|
||||||
Signals signals = signalService.buildSignals(packageId, phoneFidsData);
|
Signals signals = signalService.buildSignals(packageId, phoneFidsData);
|
||||||
if (signalRestService.update(signals)) {
|
if (signalRestService.update(signals)) {
|
||||||
log.info("Flags were updated successfully. PackageId: {} PackageName: {}. Package status changed to ON_MONITORING", packageId, packageName);
|
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 {
|
} else {
|
||||||
log.info("Updated package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
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 {
|
} else {
|
||||||
log.info("No flags were updated for package id {}. Package status changed to ON_MONITORING", packageId);
|
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) {
|
} catch (Exception e) {
|
||||||
log.error("Ошибка при поиске фидов или перерасчете флагов просрочек. Package_id {}", packageId, e);
|
log.error("Ошибка при поиске фидов или перерасчете флагов просрочек. Package_id {}", packageId, e);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.springframework.stereotype.Service;
|
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 ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
|
@ -20,16 +20,12 @@ public class PhoneService {
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects) {
|
public List<FidsPhoneData> findFidsPhoneData(List<PhoneFidMap> subjects) {
|
||||||
return findFidsPhoneData(subjects, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects, boolean processNullFids) {
|
|
||||||
List<FidsPhoneData> fidsPhoneDataList = new ArrayList<>();
|
List<FidsPhoneData> fidsPhoneDataList = new ArrayList<>();
|
||||||
int batchSize = 10000;
|
int batchSize = 10000;
|
||||||
for (int i = 0; i < subjects.size(); i += batchSize) {
|
for (int i = 0; i < subjects.size(); i += batchSize) {
|
||||||
int end = Math.min(i + batchSize, subjects.size());
|
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<String> phones = currentSubjects.stream().map(subject -> "9" + subject.getPhone()).toList();
|
||||||
List<FidsData> fidsData = mapper.findFids(phones);
|
List<FidsData> fidsData = mapper.findFids(phones);
|
||||||
|
|
||||||
|
|
@ -40,7 +36,7 @@ public class PhoneService {
|
||||||
Integer fid = fidsMap.get(phone);
|
Integer fid = fidsMap.get(phone);
|
||||||
if (fid != null) {
|
if (fid != null) {
|
||||||
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), fid, subject.getPhone(), subject.getSubjectId()));
|
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()));
|
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.response.online_report.SgnlOnlineReport;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
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.IXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
|
||||||
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
@ -35,14 +34,17 @@ public class SignalRestService {
|
||||||
private static String DOWNLOAD_REPORT_URI = "onlinedownload";
|
private static String DOWNLOAD_REPORT_URI = "onlinedownload";
|
||||||
|
|
||||||
private final RestTemplate restTemplate;
|
private final RestTemplate restTemplate;
|
||||||
private final XmlUtilService xmlUtilService;
|
private final IXmlProcessor xmlProcessor;
|
||||||
|
private final StaxXmlProcessor staxProcessor;
|
||||||
private final String authToken;
|
private final String authToken;
|
||||||
|
|
||||||
public SignalRestService(@Qualifier(value = "restTemplate") RestTemplate restTemplate,
|
public SignalRestService(@Qualifier(value = "restTemplate") RestTemplate restTemplate,
|
||||||
XmlUtilService xmlUtilService,
|
IXmlProcessor xmlProcessor,
|
||||||
|
StaxXmlProcessor staxProcessor,
|
||||||
CreditTrackerSettings config) throws Exception {
|
CreditTrackerSettings config) throws Exception {
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
this.xmlUtilService = xmlUtilService;
|
this.xmlProcessor = xmlProcessor;
|
||||||
|
this.staxProcessor = staxProcessor;
|
||||||
this.authToken = buildToken(config.getSignalsToken(), config.getSignalsuser());
|
this.authToken = buildToken(config.getSignalsToken(), config.getSignalsuser());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,8 +66,7 @@ public class SignalRestService {
|
||||||
// good response
|
// good response
|
||||||
return true;
|
return true;
|
||||||
} else if (response.getStatusCode().value() == 200 && response.getBody() != null) {
|
} else if (response.getStatusCode().value() == 200 && response.getBody() != null) {
|
||||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
SgnlReport error = staxProcessor.read(response.getBody(), SgnlReport.class);
|
||||||
SgnlReport error = staxXmlProcessor.read(response.getBody(), SgnlReport.class);
|
|
||||||
if (error.getError().getDescription() != null) {
|
if (error.getError().getDescription() != null) {
|
||||||
log.error("Ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", error.getError().getDescription());
|
log.error("Ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", error.getError().getDescription());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -92,8 +93,7 @@ public class SignalRestService {
|
||||||
);
|
);
|
||||||
String answer = response.getBody();
|
String answer = response.getBody();
|
||||||
|
|
||||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
SgnlReport error = staxProcessor.read(answer, SgnlReport.class);
|
||||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
|
||||||
if (error.getError().getDescription() != null) {
|
if (error.getError().getDescription() != null) {
|
||||||
log.error("Ошибка при удалении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
log.error("Ошибка при удалении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
||||||
}
|
}
|
||||||
|
|
@ -116,15 +116,13 @@ public class SignalRestService {
|
||||||
|
|
||||||
String answer = response.getBody();
|
String answer = response.getBody();
|
||||||
|
|
||||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
SgnlReport error = staxProcessor.read(answer, SgnlReport.class);
|
||||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
|
||||||
if (error.getError().getDescription() != null) {
|
if (error.getError().getDescription() != null) {
|
||||||
log.error("Ошибка при получении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
log.error("Ошибка при получении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
return xmlProcessor.read(answer, SgnlOnlineReport.class);
|
||||||
return processor.read(answer, SgnlOnlineReport.class);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Ошибка при получении пакета из сервиса НБКИ. Код ошибки: {} packCode={}", response.getStatusCode().value(), packCode);
|
log.error("Ошибка при получении пакета из сервиса НБКИ. Код ошибки: {} packCode={}", response.getStatusCode().value(), packCode);
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -148,8 +146,7 @@ public class SignalRestService {
|
||||||
|
|
||||||
byte[] answer = response.getBody();
|
byte[] answer = response.getBody();
|
||||||
if (isXmlError(response.getBody())) {
|
if (isXmlError(response.getBody())) {
|
||||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
SgnlReport error = staxProcessor.read(answer, SgnlReport.class);
|
||||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
|
||||||
if (error.getError().getDescription() != null) {
|
if (error.getError().getDescription() != null) {
|
||||||
log.error("Ошибка при скачивание отчета. fNameReport={}. Описание: {}", reportName, error.getError().getDescription());
|
log.error("Ошибка при скачивание отчета. fNameReport={}. Описание: {}", reportName, error.getError().getDescription());
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -175,8 +172,7 @@ public class SignalRestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Resource compressFile(Signals signals) throws Exception {
|
private Resource compressFile(Signals signals) throws Exception {
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
String requestData = xmlProcessor.asString(signals, false);
|
||||||
String requestData = processor.asString(signals, false);
|
|
||||||
|
|
||||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||||
try (GZIPOutputStream gzipStream = new GZIPOutputStream(byteStream)) {
|
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;
|
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 java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
||||||
|
|
||||||
public class ValidationUtil {
|
public class ValidationUtil {
|
||||||
|
|
||||||
private static String phoneRegex = "^\\d{9}$";
|
private static String phoneRegex = "^\\d{9}$";
|
||||||
private static String packageNameRegex = "^[A-Z0-9_]{1,22}$";
|
private static String packageNameRegex = "^[A-Z0-9_]{1,22}$";
|
||||||
private static String npIdRegex = "^\\S{1,36}$";
|
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) {
|
if(input == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Pattern.matches(phoneRegex, input);
|
return Pattern.matches(phoneRegex, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validatePackageName(String input) {
|
private static boolean validatePackageName(String input) {
|
||||||
if(input == null) {
|
if(input == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Pattern.matches(packageNameRegex, input);
|
return Pattern.matches(packageNameRegex, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean validateNPId(String input) {
|
private static boolean validateNPId(String input) {
|
||||||
if(input == null) {
|
if(input == null) {
|
||||||
return false;
|
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