Compare commits
No commits in common. "79259170bc505581c27d8a8c6a38dd586bdd0d7d" and "392b99aca4d9b1fbc905a34932346bbb214aff2a" have entirely different histories.
79259170bc
...
392b99aca4
41 changed files with 636 additions and 935 deletions
|
|
@ -1,91 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,39 @@
|
|||
package ru.nbch.credit_tracker.config.rest;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.*;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringDownloadError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringPackageDeleteError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringReportListError;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalException;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
||||
import ru.nbch.credit_tracker.utils.error.SimpleMessageResolver;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
private final SimpleMessageResolver messageResolver = new SimpleMessageResolver();
|
||||
@ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||
public ResponseEntity<CommonError> handleInvalidUser(SignalErrorException ex) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251")));
|
||||
if (ex.isUserError()) {
|
||||
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.BAD_REQUEST);
|
||||
} else {
|
||||
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(value = SignalException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||
public ResponseEntity<CommonError> handleClientException(SignalException ex) {
|
||||
@ExceptionHandler(value = SignalClientException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||
public ResponseEntity<CommonError> handleClientException(SignalClientException ex) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251")));
|
||||
CommonError commonError = getCommonError(ex);
|
||||
|
|
@ -27,14 +41,10 @@ public class GlobalExceptionHandler {
|
|||
commonError.setErrorCode(ex.getErrorMessage().getSubject().getErrorCode());
|
||||
commonError.setErrorText(messageResolver.resolve(ex.getErrorMessage()));
|
||||
|
||||
if (ex instanceof SignalClientException) {
|
||||
return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST);
|
||||
} else {
|
||||
return new ResponseEntity<>(commonError, headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
private static CommonError getCommonError(SignalException ex) {
|
||||
private static CommonError getCommonError(SignalClientException ex) {
|
||||
CommonError commonError;
|
||||
switch (ex.getErrorFormat()) {
|
||||
case MonitoringError -> commonError = new MonitoringError();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import java.time.LocalDateTime;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Hit {
|
||||
public class HitsData {
|
||||
private Integer id;
|
||||
private Integer packageId;
|
||||
private String subjectId;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package ru.nbch.credit_tracker.entities.dto;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
|
@ -8,8 +7,7 @@ import java.time.LocalDateTime;
|
|||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class UserPackage {
|
||||
public class PackageData {
|
||||
private Integer id;
|
||||
private String userId;
|
||||
private String packageName;
|
||||
|
|
@ -1,6 +1,10 @@
|
|||
package ru.nbch.credit_tracker.entities.dto;
|
||||
|
||||
import lombok.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
|
|
@ -9,7 +13,7 @@ import java.time.LocalDateTime;
|
|||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class PhoneFidMap {
|
||||
public class SubjectData {
|
||||
private Integer id;
|
||||
private Integer packageId;
|
||||
private String subjectId;
|
||||
|
|
@ -5,9 +5,14 @@ import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
|||
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||
|
||||
@Getter
|
||||
public class SignalClientException extends SignalException {
|
||||
public class SignalClientException extends RuntimeException {
|
||||
|
||||
public SignalClientException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat) {
|
||||
super(errorMessage, errorFormat);
|
||||
private final EnumKeyMessage errorMessage;
|
||||
private final XmlErrorFormat errorFormat;
|
||||
|
||||
public SignalClientException(EnumKeyMessage errorMessage,
|
||||
XmlErrorFormat errorFormat) {
|
||||
this.errorMessage = errorMessage;
|
||||
this.errorFormat = errorFormat;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package ru.nbch.credit_tracker.exceptions;
|
||||
|
||||
import lombok.Getter;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
|
||||
import ru.nbch.credit_tracker.enums.SignalError;
|
||||
|
||||
@Getter
|
||||
public class SignalErrorException extends RuntimeException {
|
||||
|
||||
private final boolean isUserError;
|
||||
private final CommonError error;
|
||||
|
||||
public SignalErrorException(SignalError signalError, String tag, CommonError error, boolean isUserError) {
|
||||
this.isUserError = isUserError;
|
||||
this.error = createErrorMessage(error, signalError, tag);
|
||||
}
|
||||
|
||||
private CommonError createErrorMessage(CommonError errorMessage, SignalError error, String tag) {
|
||||
errorMessage.setStatus("error");
|
||||
errorMessage.setErrorCode(error.getCode());
|
||||
if (tag != null) {
|
||||
errorMessage.setErrorText(error.getKey() + " " + tag);
|
||||
} else {
|
||||
errorMessage.setErrorText(error.getKey());
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,14 @@
|
|||
package ru.nbch.credit_tracker.facade;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.core.io.FileUrlResource;
|
||||
|
|
@ -8,12 +17,15 @@ import org.springframework.http.ResponseEntity;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||
import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActivePackagesRequest;
|
||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
||||
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
|
||||
import ru.nbch.credit_tracker.entities.response.active_packages.Package;
|
||||
import ru.nbch.credit_tracker.entities.response.active_packages.Packages;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringActivePackagesError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringDownloadError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringPackageDeleteError;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringReportListError;
|
||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse;
|
||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse;
|
||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
||||
|
|
@ -22,26 +34,17 @@ import ru.nbch.credit_tracker.enums.SignalError;
|
|||
import ru.nbch.credit_tracker.enums.Status;
|
||||
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
||||
import ru.nbch.credit_tracker.service.SignalService;
|
||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||
import ru.nbch.credit_tracker.utils.ValidationUtil;
|
||||
import ru.nbch.credit_tracker.utils.ZipUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.serverExcp;
|
||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.excp;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
|
|
@ -52,7 +55,7 @@ public class SignalFacade {
|
|||
private final AuthorizationService authorizationService;
|
||||
private final SignalService signalService;
|
||||
private final SignalRestService signalRestService;
|
||||
private final IXmlProcessor xmlProcessor;
|
||||
private final XmlUtilService xmlUtilService;
|
||||
|
||||
private final ExecutorService executor;
|
||||
|
||||
|
|
@ -61,20 +64,24 @@ public class SignalFacade {
|
|||
AuthorizationService authorizationService,
|
||||
SignalService signalService,
|
||||
SignalRestService signalRestService,
|
||||
IXmlProcessor xmlProcessor,
|
||||
XmlUtilService xmlUtilService,
|
||||
@Qualifier("executorService") ExecutorService executor) {
|
||||
this.config = config;
|
||||
this.authorizationService = authorizationService;
|
||||
this.signalService = signalService;
|
||||
this.signalRestService = signalRestService;
|
||||
this.xmlProcessor = xmlProcessor;
|
||||
this.xmlUtilService = xmlUtilService;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
public ResponseEntity<MonitoringResponse> setupMonitoring(MultipartFile file) {
|
||||
// первичные валидации
|
||||
if (file.isEmpty() || !isZipFile(file)) {
|
||||
throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||
if (file.isEmpty()) {
|
||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (!isZipFile(file)) {
|
||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
// Валидация Архива на количетсво файлов, размер и расширение
|
||||
|
|
@ -85,29 +92,32 @@ public class SignalFacade {
|
|||
zipInputStream = new ZipInputStream(file.getInputStream());
|
||||
Optional<ZipEntry> xmlFileEntry = ZipUtils.extractValidEntry(zipInputStream);
|
||||
if (xmlFileEntry.isEmpty()) {
|
||||
throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||
throw excp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||
}
|
||||
if (xmlFileEntry.get().getSize() > MAX_XML_FILE_SIZE) {
|
||||
throw clientExcp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError);
|
||||
throw excp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError);
|
||||
}
|
||||
|
||||
zipInputStream.close();
|
||||
zipInputStream = new ZipInputStream(file.getInputStream());
|
||||
zipInputStream.getNextEntry();
|
||||
|
||||
monitoringRequest = xmlProcessor.read(zipInputStream, MonitoringRequest.class);
|
||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||
monitoringRequest = processor.read(zipInputStream, MonitoringRequest.class);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SignalClientException) {
|
||||
throw (SignalClientException) e;
|
||||
}
|
||||
log.error(e.getMessage(), e);
|
||||
throw serverExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError);
|
||||
//todo throw new SignalServerException(e);
|
||||
throw excp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError);
|
||||
} finally {
|
||||
if (zipInputStream != null) {
|
||||
try {
|
||||
zipInputStream.close();
|
||||
} catch (IOException e) {
|
||||
throw serverExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError);
|
||||
throw new RuntimeException(e);
|
||||
//todo throw new SignalServerException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -115,8 +125,8 @@ public class SignalFacade {
|
|||
|
||||
// валидация xml
|
||||
try {
|
||||
ValidationUtil.validateMonitoringRequest(monitoringRequest);
|
||||
} catch (SignalClientException e) {
|
||||
validateMonitoringRequest(monitoringRequest);
|
||||
} catch (SignalErrorException e) {
|
||||
signalService.rejectPackage(monitoringRequest);
|
||||
throw e;
|
||||
}
|
||||
|
|
@ -126,22 +136,22 @@ public class SignalFacade {
|
|||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword());
|
||||
if (!authResult.isSuccess()) {
|
||||
signalService.rejectPackage(monitoringRequest);
|
||||
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringError);
|
||||
throw new SignalErrorException(authResult.getError(), null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
// проверка на уникальность пакета
|
||||
if (signalService.isPackageNotUnique(monitoringRequest)) {
|
||||
signalService.rejectPackage(monitoringRequest);
|
||||
throw clientExcp(SignalError.ERROR_007, XmlErrorFormat.MonitoringError);
|
||||
throw new SignalErrorException(SignalError.ERROR_007, null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
packageId = signalService.registerPackage(monitoringRequest);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SignalClientException) {
|
||||
throw (SignalClientException) e;
|
||||
if (e instanceof SignalErrorException) {
|
||||
throw (SignalErrorException) e;
|
||||
}
|
||||
log.error(e.getMessage(), e);
|
||||
throw serverExcp(SignalError.ERROR_100, XmlErrorFormat.MonitoringError);
|
||||
throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false);
|
||||
}
|
||||
|
||||
// в отдельном потоке запускаем поиск фидов и расчет флагов просрочек
|
||||
|
|
@ -150,6 +160,58 @@ public class SignalFacade {
|
|||
return ResponseEntity.ok().body(new MonitoringResponse());
|
||||
}
|
||||
|
||||
private void validateMonitoringRequest(MonitoringRequest request) throws SignalErrorException {
|
||||
if (request == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_011, null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
validateReruqredTags(request);
|
||||
|
||||
validateTagsTypes(request);
|
||||
}
|
||||
|
||||
private void validateReruqredTags(MonitoringRequest request) throws SignalErrorException {
|
||||
if (request.getUserId() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "UserId", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getPackageName() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "PackageName", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getPassword() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "Password", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getSubjects() == null) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "Subjects", new MonitoringError(), true);
|
||||
}
|
||||
|
||||
if (request.getSubjects().getSubject().isEmpty()) {
|
||||
throw new SignalErrorException(SignalError.ERROR_002, "Subject", new MonitoringError(), true);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTagsTypes(MonitoringRequest request) throws SignalErrorException {
|
||||
if (!ValidationUtil.validatePackageName(request.getPackageName())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_008, null, new MonitoringError(), true);
|
||||
}
|
||||
|
||||
Set<String> uniqueIds = new HashSet<>();
|
||||
for (Subject subject : request.getSubjects().getSubject()) {
|
||||
if (!ValidationUtil.validatePhone(subject.getClientId())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_003, null, new MonitoringError(), true);
|
||||
}
|
||||
if (!ValidationUtil.validateNPId(subject.getId())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_010, null, new MonitoringError(), true);
|
||||
}
|
||||
// проверка на уникальность Id внутри одного пакета
|
||||
if (!uniqueIds.add(subject.getId())) {
|
||||
throw new SignalErrorException(SignalError.ERROR_004, subject.getId(), new MonitoringError(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerFidsAndDebts(Integer packageId, String packageName) {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
|
|
@ -159,14 +221,14 @@ public class SignalFacade {
|
|||
// TODO validate xsd?
|
||||
if (signalRestService.update(signals)) {
|
||||
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
||||
} else {
|
||||
log.info("Package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
||||
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
||||
}
|
||||
});
|
||||
|
|
@ -182,65 +244,46 @@ public class SignalFacade {
|
|||
try {
|
||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
||||
if (!authResult.isSuccess()) {
|
||||
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringActivePackagesError);
|
||||
throw new SignalErrorException(authResult.getError(), null, new MonitoringActivePackagesError(), true);
|
||||
}
|
||||
List<UserPackage> activePackages = signalService.findActivePackages(activePackagesRequest.getUserId());
|
||||
|
||||
if (!activePackages.isEmpty()) {
|
||||
MonitoringActivePackagesResponse response = new MonitoringActivePackagesResponse();
|
||||
response.setStatus("OK");
|
||||
response.setMembercode(activePackagesRequest.getUserId().substring(0, 6));
|
||||
Packages packages = new Packages();
|
||||
activePackages.forEach(data -> {
|
||||
Package pack = new Package();
|
||||
pack.setPackageName(data.getPackageName());
|
||||
pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null);
|
||||
packages.getPackages().add(pack);
|
||||
});
|
||||
response.setPackages(packages);
|
||||
MonitoringActivePackagesResponse response = signalService.findActivePackages(activePackagesRequest.getUserId());
|
||||
if (response != null) {
|
||||
return ResponseEntity.ok(response);
|
||||
} else {
|
||||
throw clientExcp(SignalError.ERROR_015, XmlErrorFormat.MonitoringActivePackagesError);
|
||||
throw new SignalErrorException(SignalError.ERROR_015, null, new MonitoringActivePackagesError(), true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SignalClientException) {
|
||||
throw (SignalClientException) e;
|
||||
if (e instanceof SignalErrorException) {
|
||||
throw (SignalErrorException) e;
|
||||
}
|
||||
log.error(e.getMessage(), e);
|
||||
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringActivePackagesError);
|
||||
throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringActivePackagesError(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public ResponseEntity<MonitoringPackageDeleteResponse> deletePackage(String username, String packageName) {
|
||||
try {
|
||||
if (!signalService.isPackageExists(username, packageName)) {
|
||||
throw clientExcp(SignalError.ERROR_016, XmlErrorFormat.MonitoringPackageDeleteError, packageName);
|
||||
throw new SignalErrorException(SignalError.ERROR_016, packageName, new MonitoringPackageDeleteError(), true);
|
||||
}
|
||||
|
||||
LocalDateTime deactivatedAt = LocalDateTime.now();
|
||||
signalService.deletePackage(username, packageName, deactivatedAt);
|
||||
|
||||
MonitoringPackageDeleteResponse response = new MonitoringPackageDeleteResponse();
|
||||
response.setStatus("Deleted");
|
||||
response.setPackageName(packageName);
|
||||
response.setDeactivatedAt(deactivatedAt.toString());
|
||||
MonitoringPackageDeleteResponse response = signalService.deletePackage(username, packageName);
|
||||
|
||||
signalRestService.deletePackage(username, packageName);
|
||||
log.info("Package {} deleted", packageName);
|
||||
return ResponseEntity.ok(response);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SignalClientException) {
|
||||
throw (SignalClientException) e;
|
||||
if (e instanceof SignalErrorException) {
|
||||
throw (SignalErrorException) e;
|
||||
}
|
||||
log.error(e.getMessage(), e);
|
||||
throw serverExcp(SignalError.ERROR_017, XmlErrorFormat.MonitoringPackageDeleteError);
|
||||
throw new SignalErrorException(SignalError.ERROR_017, null, new MonitoringPackageDeleteError(), false);
|
||||
}
|
||||
}
|
||||
|
||||
public ResponseEntity<MonitoringReportListResponse> getReportList(String username, String packageName) {
|
||||
try {
|
||||
if (!signalService.isPackageExists(username, packageName)) {
|
||||
throw clientExcp(SignalError.ERROR_016, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||
throw new SignalErrorException(SignalError.ERROR_016, packageName, new MonitoringReportListError(), true);
|
||||
}
|
||||
|
||||
String memberCode = username.substring(0, 6);
|
||||
|
|
@ -252,7 +295,7 @@ public class SignalFacade {
|
|||
MonitoringReportListResponse.Reports reports = new MonitoringReportListResponse.Reports();
|
||||
File[] files = folder.listFiles();
|
||||
if (files == null) {
|
||||
throw clientExcp(SignalError.ERROR_012, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||
throw new SignalErrorException(SignalError.ERROR_012, packageName, new MonitoringReportListError(), true);
|
||||
}
|
||||
for (File file : files) {
|
||||
if (file.isFile() && file.getName().startsWith(filePrefix)) {
|
||||
|
|
@ -261,7 +304,7 @@ public class SignalFacade {
|
|||
}
|
||||
|
||||
if (reports.getReports().isEmpty()) {
|
||||
throw clientExcp(SignalError.ERROR_012, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||
throw new SignalErrorException(SignalError.ERROR_012, packageName, new MonitoringReportListError(), true);
|
||||
} else {
|
||||
MonitoringReportListResponse response = new MonitoringReportListResponse();
|
||||
response.setPackageName(packageName);
|
||||
|
|
@ -270,14 +313,14 @@ public class SignalFacade {
|
|||
}
|
||||
} else {
|
||||
log.error("Пакет {} был найден в бд для memberCode {}, но ни одного архива не было найдено в папке {}", packageName, username, dirPath);
|
||||
throw clientExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||
throw new SignalErrorException(SignalError.ERROR_013, packageName, new MonitoringReportListError(), true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SignalClientException) {
|
||||
throw (SignalClientException) e;
|
||||
if (e instanceof SignalErrorException) {
|
||||
throw (SignalErrorException) e;
|
||||
}
|
||||
log.error(e.getMessage(), e);
|
||||
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringReportListError);
|
||||
throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringReportListError(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -293,15 +336,15 @@ public class SignalFacade {
|
|||
return ResponseEntity.ok().body(new FileUrlResource(file.getPath()));
|
||||
}
|
||||
} else {
|
||||
throw clientExcp(SignalError.ERROR_014, XmlErrorFormat.MonitoringDownloadError);
|
||||
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);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof SignalClientException) {
|
||||
throw (SignalClientException) e;
|
||||
if (e instanceof SignalErrorException) {
|
||||
throw (SignalErrorException) e;
|
||||
}
|
||||
log.error(e.getMessage(), e);
|
||||
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringDownloadError);
|
||||
throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringDownloadError(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +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.Hit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface HitsMapper {
|
||||
|
||||
void insertHits(@Param("hits") List<Hit> hits);
|
||||
|
||||
}
|
||||
|
|
@ -1,21 +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.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);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
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);
|
||||
}
|
||||
|
|
@ -1,31 +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.UserPackage;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface UserPackageMapper {
|
||||
|
||||
boolean isPackageNotUnique(@Param("userId") String userId, @Param("packageName") String packageName);
|
||||
|
||||
boolean isPackageExists(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String status);
|
||||
|
||||
void deletePackage(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String newStatus, @Param("previousStatus") String previousStatus, @Param("deactivatedAt") LocalDateTime deactivatedAt);
|
||||
|
||||
Integer insertPackage(@Param("userPackage") UserPackage userPackage);
|
||||
|
||||
void updatePackageStatus(@Param("packageId") Integer packageId, @Param("status") String status);
|
||||
|
||||
void updatePackageLastDownloadedReport(@Param("id") Integer id, @Param("fileName") String fileName);
|
||||
|
||||
UserPackage findPackage(@Param("id") Integer id);
|
||||
|
||||
List<UserPackage> findUserPackages(@Param("userId") String userId, @Param("status") String status);
|
||||
|
||||
List<UserPackage> findAllPackagesByStatus(@Param("status") String status);
|
||||
|
||||
}
|
||||
|
|
@ -3,9 +3,9 @@ package ru.nbch.credit_tracker.service;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||
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.response.monitoring_signal_response.*;
|
||||
import ru.nbch.credit_tracker.entities.response.online_download.Inquiry;
|
||||
import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadReport;
|
||||
|
|
@ -14,6 +14,7 @@ import ru.nbch.credit_tracker.entities.response.online_report.Report;
|
|||
import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport;
|
||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
|
@ -35,16 +36,16 @@ public class MonitoringService {
|
|||
|
||||
private final SignalRestService signalRestService;
|
||||
private final SignalService signalService;
|
||||
private final IXmlProcessor xmlProcessor;
|
||||
private final XmlUtilService xmlUtilService;
|
||||
private final CreditTrackerSettings config;
|
||||
|
||||
public MonitoringService(SignalRestService signalRestService,
|
||||
SignalService signalService,
|
||||
IXmlProcessor xmlProcessor,
|
||||
XmlUtilService xmlUtilService,
|
||||
CreditTrackerSettings config) {
|
||||
this.signalRestService = signalRestService;
|
||||
this.signalService = signalService;
|
||||
this.xmlProcessor = xmlProcessor;
|
||||
this.xmlUtilService = xmlUtilService;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
|
|
@ -56,13 +57,13 @@ public class MonitoringService {
|
|||
|
||||
private void monitor() {
|
||||
log.info("Start monitoring");
|
||||
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||
for (UserPackage userPackage : packages) {
|
||||
log.info("Processing package {}", userPackage.getPackageName());
|
||||
SgnlOnlineReport onlineReports = signalRestService.getReports(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName());
|
||||
List<PackageData> packages = signalService.findPackagesOnMonitoring();
|
||||
for (PackageData packageData : packages) {
|
||||
log.info("Processing package {}", packageData.getPackageName());
|
||||
SgnlOnlineReport onlineReports = signalRestService.getReports(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName());
|
||||
|
||||
if (onlineReports == null) {
|
||||
log.info("No reports found for package {}", userPackage.getPackageName());
|
||||
log.info("No reports found for package {}", packageData.getPackageName());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +71,7 @@ public class MonitoringService {
|
|||
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать
|
||||
|
||||
if (fileNames.isEmpty()) {
|
||||
log.info("No new report found for package {}", userPackage.getPackageName());
|
||||
log.info("No new report found for package {}", packageData.getPackageName());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -78,16 +79,16 @@ public class MonitoringService {
|
|||
.orElseGet(Collections::emptyList)
|
||||
.stream().max(Comparator.comparing(CTUtil::parseDateFromReportFileName)); // отфильтровали только те имена, которые парсятся в дату, так что null тут не придет
|
||||
|
||||
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(userPackage.getLastDownloadedReport());
|
||||
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(packageData.getLastDownloadedReport());
|
||||
|
||||
if (userPackage.getLastDownloadedReport() != null) {
|
||||
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", userPackage.getPackageName(), userPackage.getLastDownloadedReport());
|
||||
if (packageData.getLastDownloadedReport() != null) {
|
||||
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", packageData.getPackageName(), packageData.getLastDownloadedReport());
|
||||
} else {
|
||||
log.info("Last Downloaded Report Name is empty");
|
||||
}
|
||||
|
||||
OnlineDownloadReport report = null;
|
||||
if (userPackage.getLastDownloadedReport() == null && newReport.isPresent()) {
|
||||
if (packageData.getLastDownloadedReport() == null && newReport.isPresent()) {
|
||||
report = loadReport(newReport.get()); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным
|
||||
} else if (lastDownloadedReportDate != null && newReport.isPresent()) {
|
||||
LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport.get());
|
||||
|
|
@ -96,28 +97,28 @@ public class MonitoringService {
|
|||
}
|
||||
}
|
||||
if (report == null) {
|
||||
log.info("Report was not loaded for package {}", userPackage.getPackageName());
|
||||
log.info("Report was not loaded for package {}", packageData.getPackageName());
|
||||
continue;
|
||||
}
|
||||
|
||||
MonitoringSignalResponse response = generateResponse(userPackage, report.getPersons().getPersons());
|
||||
String fileName = createResponseFile(userPackage, response);
|
||||
MonitoringSignalResponse response = generateResponse(packageData, report.getPersons().getPersons());
|
||||
String fileName = createResponseFile(packageData, response);
|
||||
if (fileName != null) {
|
||||
log.info("New report fileName: {}", fileName);
|
||||
updateSignalHits(userPackage, response, fileName);
|
||||
signalService.updateLastDownloadedReport(userPackage.getId(), newReport.get());
|
||||
updateSignalHits(packageData, response, fileName);
|
||||
signalService.updateLastDownloadedReport(packageData.getId(), newReport.get());
|
||||
} else {
|
||||
log.info("Report was not created for package {}", userPackage.getPackageName());
|
||||
log.info("Report was not created for package {}", packageData.getPackageName());
|
||||
}
|
||||
}
|
||||
log.info("Finish monitoring");
|
||||
}
|
||||
|
||||
private MonitoringSignalResponse generateResponse(UserPackage userPackage, List<Person> persons) {
|
||||
private MonitoringSignalResponse generateResponse(PackageData packageData, List<Person> persons) {
|
||||
MonitoringSignalResponse response = new MonitoringSignalResponse();
|
||||
response.setPackageName(userPackage.getPackageName()); // Имя пакета, переданного при установке
|
||||
response.setPackageName(packageData.getPackageName()); // Имя пакета, переданного при установке
|
||||
Subjects subjects = new Subjects();
|
||||
List<PhoneFidMap> phoneFidMapList = signalService.findFullSubjectsData(userPackage.getId());
|
||||
List<SubjectData> subjectDataList = signalService.findFullSubjectsData(packageData.getId());
|
||||
for (Person person : persons) {
|
||||
Signals signals = new Signals();
|
||||
for (Inquiry inquiry : person.getInquiries()) {
|
||||
|
|
@ -134,7 +135,7 @@ public class MonitoringService {
|
|||
|
||||
// Если есть хотя бы один заполненный сигнал, значит заполняем остальные данные
|
||||
if (!signals.getSignals().isEmpty()) {
|
||||
phoneFidMapList.stream().filter(p -> p.getSubjectId().equals(person.getUid())).findFirst().ifPresent(subjectData -> {
|
||||
subjectDataList.stream().filter(p -> p.getSubjectId().equals(person.getUid())).findFirst().ifPresent(subjectData -> {
|
||||
Subject subject = new Subject();
|
||||
subject.setId(subjectData.getSubjectId()); // Уникальный идентификатор субъекта (равен Id из XML-пакета при установке мониторинга)
|
||||
subject.setClientId(subjectData.getPhone());
|
||||
|
|
@ -149,17 +150,18 @@ public class MonitoringService {
|
|||
return response;
|
||||
}
|
||||
|
||||
private String createResponseFile(UserPackage userPackage, MonitoringSignalResponse response) {
|
||||
private String createResponseFile(PackageData packageData, MonitoringSignalResponse response) {
|
||||
try {
|
||||
String fileName = CTUtil.generateResponseReportFileName(userPackage.getUserId(), userPackage.getPackageName());
|
||||
String filePath = config.getLoadDir() + File.separator + userPackage.getUserId().substring(0, 6) + File.separator;
|
||||
String fileName = CTUtil.generateResponseReportFileName(packageData.getUserId(), packageData.getPackageName());
|
||||
String filePath = config.getLoadDir() + File.separator + packageData.getUserId().substring(0, 6) + File.separator;
|
||||
|
||||
File folder = new File(filePath);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdir();
|
||||
}
|
||||
|
||||
String xmlStr = xmlProcessor.asString(response, true);
|
||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||
String xmlStr = processor.asString(response, true);
|
||||
|
||||
byte[] xmlBytes = xmlStr.getBytes(Charset.forName("windows-1251"));
|
||||
try (FileOutputStream fos = new FileOutputStream(filePath + fileName + ".zip");
|
||||
|
|
@ -177,23 +179,23 @@ public class MonitoringService {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void updateSignalHits(UserPackage userPackage, MonitoringSignalResponse response, String reportFileName) {
|
||||
log.info("Updating signal hits for {}", userPackage.getPackageName());
|
||||
private void updateSignalHits(PackageData packageData, MonitoringSignalResponse response, String reportFileName) {
|
||||
log.info("Updating signal hits for {}", packageData.getPackageName());
|
||||
LocalDateTime responseSentAt = LocalDateTime.now();
|
||||
List<Hit> hits = new ArrayList<>();
|
||||
List<HitsData> hits = new ArrayList<>();
|
||||
response.getSubjects().getSubjects().forEach(subject -> {
|
||||
subject.getSignals().getSignals().forEach(signal -> {
|
||||
Hit hit = new Hit();
|
||||
hit.setPackageId(userPackage.getId());
|
||||
hit.setSubjectId(subject.getId());
|
||||
hit.setSignalType(1);
|
||||
hit.setResponseSentAt(responseSentAt);
|
||||
hit.setReportFileName(reportFileName);
|
||||
hits.add(hit);
|
||||
HitsData hitsData = new HitsData();
|
||||
hitsData.setPackageId(packageData.getId());
|
||||
hitsData.setSubjectId(subject.getId());
|
||||
hitsData.setSignalType(1);
|
||||
hitsData.setResponseSentAt(responseSentAt);
|
||||
hitsData.setReportFileName(reportFileName);
|
||||
hits.add(hitsData);
|
||||
});
|
||||
});
|
||||
signalService.insertHits(hits);
|
||||
log.info("Signal hits updated for package {}", userPackage.getPackageName());
|
||||
signalService.setHits(hits);
|
||||
log.info("Signal hits updated for package {}", packageData.getPackageName());
|
||||
}
|
||||
|
||||
private OnlineDownloadReport loadReport(String reportName) {
|
||||
|
|
@ -204,7 +206,8 @@ public class MonitoringService {
|
|||
OnlineDownloadReport report;
|
||||
try (GZIPInputStream zipInputStream = new GZIPInputStream(new ByteArrayInputStream(archive))) {
|
||||
|
||||
report = xmlProcessor.read(zipInputStream, OnlineDownloadReport.class);
|
||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||
report = processor.read(zipInputStream, OnlineDownloadReport.class);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -1,25 +1,31 @@
|
|||
package ru.nbch.credit_tracker.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.builder.PersonFactoryBuilder;
|
||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||
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 ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
|
||||
import ru.nbch.credit_tracker.entities.response.active_packages.Package;
|
||||
import ru.nbch.credit_tracker.entities.response.active_packages.Packages;
|
||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Auth;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Person;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||
import ru.nbch.credit_tracker.enums.Status;
|
||||
import ru.nbch.credit_tracker.mapper.signal.SignalMapper;
|
||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
||||
import ru.nbch.credit_tracker.service.indic.PersonService;
|
||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||
import ru.nbch.credit_tracker.service.signal.HitsService;
|
||||
import ru.nbch.credit_tracker.service.signal.PhoneFidMapService;
|
||||
import ru.nbch.credit_tracker.service.signal.UserPackageService;
|
||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -30,10 +36,10 @@ import java.util.Objects;
|
|||
@Service
|
||||
public class SignalService {
|
||||
|
||||
private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy");
|
||||
|
||||
private final CreditTrackerSettings config;
|
||||
private final HitsService hitsService;
|
||||
private final UserPackageService userPackageService;
|
||||
private final PhoneFidMapService phoneFidMapService;
|
||||
private final SignalMapper mapper;
|
||||
private final PhoneService phoneService;
|
||||
private final FlagsService flagsService;
|
||||
private final PersonService personService;
|
||||
|
|
@ -41,77 +47,53 @@ public class SignalService {
|
|||
private final int batchSize = 10000;
|
||||
|
||||
public SignalService(CreditTrackerSettings config,
|
||||
HitsService hitsService,
|
||||
UserPackageService userPackageService,
|
||||
PhoneFidMapService phoneFidMapService,
|
||||
SignalMapper mapper,
|
||||
PhoneService phoneService,
|
||||
FlagsService flagsService,
|
||||
PersonService personService) {
|
||||
this.config = config;
|
||||
this.hitsService = hitsService;
|
||||
this.userPackageService = userPackageService;
|
||||
this.phoneFidMapService = phoneFidMapService;
|
||||
this.mapper = mapper;
|
||||
this.phoneService = phoneService;
|
||||
this.flagsService = flagsService;
|
||||
this.personService = personService;
|
||||
}
|
||||
|
||||
public boolean isPackageNotUnique(MonitoringRequest request) {
|
||||
return userPackageService.isPackageNotUnique(request.getUserId(), request.getPackageName());
|
||||
String userId = request.getUserId();
|
||||
return mapper.isPackageNotUnique(userId.substring(0, 6), request.getPackageName());
|
||||
}
|
||||
|
||||
public Integer registerPackage(MonitoringRequest request) {
|
||||
UserPackage userPackage = UserPackage.builder()
|
||||
.userId(request.getUserId())
|
||||
.packageName(request.getPackageName())
|
||||
.createdAt(LocalDateTime.now())
|
||||
.status(Status.PROCESSING.name())
|
||||
.build();
|
||||
Integer packageId = userPackageService.insertPackage(userPackage);
|
||||
Integer packageId = mapper.registerPackage(request, LocalDateTime.now(), Status.PROCESSING.name());
|
||||
List<Subject> subjects = request.getSubjects().getSubject();
|
||||
for (int i = 0; i < subjects.size(); i += batchSize) {
|
||||
int end = Math.min(i + batchSize, subjects.size());
|
||||
phoneFidMapService.registerSubjects(subjects.subList(i, end), packageId); // TODO преобразовывать список в List<PhoneFidMap> ?
|
||||
mapper.registerSubjects(subjects.subList(i, end), packageId);
|
||||
}
|
||||
return packageId;
|
||||
}
|
||||
|
||||
public List<PhoneService.FidsPhoneData> registerSubjectsFidAndDebts(Integer packageId) {
|
||||
List<PhoneFidMap> subjects = phoneFidMapService.findPhoneFidMaps(packageId);
|
||||
List<SubjectData> subjects = mapper.findSubjectsData(packageId);
|
||||
return updateFlags(subjects, packageId);
|
||||
}
|
||||
|
||||
public List<PhoneService.FidsPhoneData> updateFlags(List<PhoneFidMap> subjects, Integer packageId) {
|
||||
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(subjects);
|
||||
public List<PhoneService.FidsPhoneData> updateFlags(List<SubjectData> subjects, Integer packageId) {
|
||||
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(subjects, true);
|
||||
LocalDateTime calculatedAt = LocalDateTime.now();
|
||||
for (int i = 0; i < fidsPhoneDataList.size(); i += batchSize) {
|
||||
int end = Math.min(i + batchSize, fidsPhoneDataList.size());
|
||||
List<PhoneService.FidsPhoneData> currentList = fidsPhoneDataList.subList(i, end);
|
||||
Map<Integer, FlagsService.FlagsData> flagsDataMap = flagsService.findFlags(currentList.stream().map(PhoneService.FidsPhoneData::getFid).filter(Objects::nonNull).toList());
|
||||
List<PhoneFidMap> subjectToUpdate = new ArrayList<>();
|
||||
List<SubjectData> subjectToUpdate = new ArrayList<>();
|
||||
|
||||
currentList.forEach(data -> {
|
||||
PhoneFidMap subject;
|
||||
SubjectData subject;
|
||||
if (data.getFid() != null) {
|
||||
FlagsService.FlagsData flagsData = flagsDataMap.get(data.getFid());
|
||||
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();
|
||||
subject = new SubjectData(data.getId(), packageId, data.getSubjectId(), data.getPhone(), data.getFid(), flagsData.getFlagDebt5000(), flagsData.getFlag90days(), calculatedAt);
|
||||
} else {
|
||||
subject = PhoneFidMap.builder()
|
||||
.id(data.getId())
|
||||
.packageId(packageId)
|
||||
.subjectId(data.getSubjectId())
|
||||
.phone(data.getPhone())
|
||||
.calculatedAt(calculatedAt)
|
||||
.build();
|
||||
subject = new SubjectData(data.getId(), packageId, data.getSubjectId(), data.getPhone(), null, null, null, calculatedAt);
|
||||
}
|
||||
subjectToUpdate.add(subject);
|
||||
});
|
||||
|
|
@ -119,7 +101,7 @@ public class SignalService {
|
|||
int updateBatchSize = batchSize / 8; // 8 параметров на одну запись для обновления. Максимальное количество параметров ~65000
|
||||
for (int j = 0; j < subjectToUpdate.size(); j += updateBatchSize) {
|
||||
int endIndex = Math.min(j + updateBatchSize, subjectToUpdate.size());
|
||||
phoneFidMapService.updatePhoneFidMaps(subjectToUpdate.subList(j, endIndex));
|
||||
mapper.updateSubjects(subjectToUpdate.subList(j, endIndex));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,24 +109,18 @@ public class SignalService {
|
|||
}
|
||||
|
||||
public void rejectPackage(MonitoringRequest request) {
|
||||
UserPackage userPackage = UserPackage.builder()
|
||||
.userId(request.getUserId())
|
||||
.packageName(request.getPackageName())
|
||||
.createdAt(LocalDateTime.now())
|
||||
.status(Status.REJECTED.name())
|
||||
.build();
|
||||
userPackageService.insertPackage(userPackage);
|
||||
mapper.insertPackage(request, LocalDateTime.now(), Status.REJECTED.name());
|
||||
}
|
||||
|
||||
public void updatePackageStatus(Integer packageId, Status status) {
|
||||
userPackageService.updatePackageStatus(packageId, status);
|
||||
public void setPackageStatus(Integer packageId, Status status) {
|
||||
mapper.setPackageStatus(packageId, status.name());
|
||||
}
|
||||
|
||||
public Signals buildSignals(Integer packageId, List<PhoneService.FidsPhoneData> fids) {
|
||||
UserPackage userPackage = userPackageService.findPackage(packageId);
|
||||
PackageData packageData = mapper.findPackageData(packageId);
|
||||
Signals signals = new Signals();
|
||||
signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы)
|
||||
signals.setId(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName()); // <MEMBERCODE>_<PackageName>
|
||||
signals.setId(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName()); // <MEMBERCODE>_<PackageName>
|
||||
Auth auth = new Auth();
|
||||
auth.setUser(config.getSignalsuser());
|
||||
signals.setAuth(auth);
|
||||
|
|
@ -167,10 +143,7 @@ public class SignalService {
|
|||
fidsPhoneData.forEach(data -> {
|
||||
if (data.getFid() != null) {
|
||||
PersonService.PersonData personData = personFidMap.get(data.getFid());
|
||||
Person person = PersonFactoryBuilder.builder()
|
||||
.personData(personData)
|
||||
.uid(data.getSubjectId())
|
||||
.build();
|
||||
Person person = getPerson(personData, data.getSubjectId());
|
||||
if (person != null) {
|
||||
persons.add(person);
|
||||
}
|
||||
|
|
@ -179,31 +152,101 @@ public class SignalService {
|
|||
return persons;
|
||||
}
|
||||
|
||||
public List<UserPackage> findActivePackages(String userId) {
|
||||
return userPackageService.findUserPackages(userId, Status.ON_MONITORING);
|
||||
private Person getPerson(PersonService.PersonData personData, String id) {
|
||||
if (personData == null) {
|
||||
return null;
|
||||
}
|
||||
PersonService.NameData nameData = personData.getName();
|
||||
PersonService.PassportData passportData = personData.getPassport();
|
||||
Person person = new Person();
|
||||
person.setS(nameData.getLastName());
|
||||
person.setN(nameData.getFirstName());
|
||||
person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null);
|
||||
person.setD(DATE_FORMAT.format(CTUtil.localDatetoDate(nameData.getBirthDate())));
|
||||
|
||||
person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum()));
|
||||
person.setPd(passportData.getIssDate() != null ? DATE_FORMAT.format(CTUtil.localDatetoDate(passportData.getIssDate())) : "01.01.2000");
|
||||
person.setDt(StringUtils.isNotBlank(passportData.getIdType2()) ? passportData.getIdType2() : passportData.getIdType());
|
||||
person.setIp("0");
|
||||
person.setUid(id);
|
||||
person.setOksm("999");
|
||||
person.setConsentDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
|
||||
person.setConsentPurpose("16");
|
||||
person.setReportUser("АО «НБКИ»");
|
||||
person.setLiability("1");
|
||||
person.setConsentPeriod("3");
|
||||
person.setAgrDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
|
||||
person.setReportUserRegNum("1057746710713");
|
||||
person.setReportUserTaxID("7703548386");
|
||||
person.setConsentHash("hash");
|
||||
|
||||
person.setCs(person.getS());
|
||||
person.setConsentN(person.getN());
|
||||
person.setConsentM(person.getM());
|
||||
person.setConsentBd(person.getD());
|
||||
person.setConsentPn(person.getPn());
|
||||
person.setConsentPd(person.getPd());
|
||||
person.setConsentDivCode("000-000");
|
||||
person.setConsentDt(person.getDt());
|
||||
person.setInqPurpose("16");
|
||||
return person;
|
||||
}
|
||||
|
||||
private String getPn(String serNum, String idNum) {
|
||||
String normSerNum = CTUtil.normalize(serNum);
|
||||
String normIdNum = CTUtil.normalize(idNum);
|
||||
return StringUtils.isNotBlank(normSerNum) ? normSerNum + normIdNum : normIdNum;
|
||||
}
|
||||
|
||||
|
||||
public MonitoringActivePackagesResponse findActivePackages(String userId) {
|
||||
String memberCode = userId.substring(0, 6);
|
||||
MonitoringActivePackagesResponse activePackages = new MonitoringActivePackagesResponse();
|
||||
activePackages.setStatus("OK");
|
||||
activePackages.setMembercode(memberCode);
|
||||
Packages packages = new Packages();
|
||||
mapper.findPackageDataList(memberCode, Status.ON_MONITORING.name()).forEach(data -> {
|
||||
Package pack = new Package();
|
||||
pack.setPackageName(data.getPackageName());
|
||||
pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null);
|
||||
packages.getPackages().add(pack);
|
||||
});
|
||||
activePackages.setPackages(packages);
|
||||
|
||||
if (packages.getPackages() == null || packages.getPackages().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return activePackages;
|
||||
}
|
||||
|
||||
public boolean isPackageExists(String username, String packageName) {
|
||||
return userPackageService.isPackageExists(username, packageName, Status.ON_MONITORING);
|
||||
return mapper.isPackageExists(username.substring(0, 6), packageName, Status.ON_MONITORING.name());
|
||||
}
|
||||
|
||||
public void deletePackage(String username, String packageName, LocalDateTime deactivatedAt) {
|
||||
userPackageService.deletePackage(username, packageName, Status.DELETED, Status.ON_MONITORING, deactivatedAt);
|
||||
public MonitoringPackageDeleteResponse deletePackage(String username, String packageName) {
|
||||
LocalDateTime deactivatedAt = LocalDateTime.now();
|
||||
mapper.deletePackage(username.substring(0, 6), packageName, Status.DELETED.name(), Status.ON_MONITORING.name(), deactivatedAt);
|
||||
|
||||
MonitoringPackageDeleteResponse deleteResponse = new MonitoringPackageDeleteResponse();
|
||||
deleteResponse.setStatus("Deleted");
|
||||
deleteResponse.setPackageName(packageName);
|
||||
deleteResponse.setDeactivatedAt(deactivatedAt.toString());
|
||||
return deleteResponse;
|
||||
}
|
||||
|
||||
public List<UserPackage> findPackagesOnMonitoring() {
|
||||
return userPackageService.findAllPackagesByStatus(Status.ON_MONITORING);
|
||||
public List<PackageData> findPackagesOnMonitoring() {
|
||||
return mapper.findPackagesByStatus(Status.ON_MONITORING.name());
|
||||
}
|
||||
|
||||
public List<PhoneFidMap> findFullSubjectsData(Integer packageId) {
|
||||
return phoneFidMapService.findFullPhoneFidMap(packageId);
|
||||
public List<SubjectData> findFullSubjectsData(Integer packageId) {
|
||||
return mapper.findFullSubjectsData(packageId);
|
||||
}
|
||||
|
||||
public void insertHits(List<Hit> hits) {
|
||||
hitsService.insertHits(hits);
|
||||
public void setHits(List<HitsData> hits) {
|
||||
mapper.setHits(hits);
|
||||
}
|
||||
|
||||
public void updateLastDownloadedReport(Integer id, String fileName) {
|
||||
userPackageService.updatePackageLastDownloadedReport(id, fileName);
|
||||
mapper.setPackageLastDownloadedReport(id, fileName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package ru.nbch.credit_tracker.service;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||
import ru.nbch.credit_tracker.enums.Status;
|
||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||
|
|
@ -42,32 +42,32 @@ public class UpdatingFlagsService {
|
|||
|
||||
private void update() {
|
||||
log.info("Start updating flags");
|
||||
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||
for (UserPackage userPackage : packages) {
|
||||
log.info("Updating flags for Package {}", userPackage.getPackageName());
|
||||
List<PhoneFidMap> subjects = signalService.findFullSubjectsData(userPackage.getId())
|
||||
List<PackageData> packages = signalService.findPackagesOnMonitoring();
|
||||
for (PackageData packageData : packages) {
|
||||
log.info("Updating flags for Package {}", packageData.getPackageName());
|
||||
List<SubjectData> subjects = signalService.findFullSubjectsData(packageData.getId())
|
||||
.stream().filter(subject -> subject.getCalculatedAt() != null && hasDaysPassed(subject.getCalculatedAt())).toList();
|
||||
updateFlags(userPackage.getId(), subjects, userPackage.getPackageName());
|
||||
updateFlags(packageData.getId(), subjects, packageData.getPackageName());
|
||||
}
|
||||
log.info("Finish updating flags");
|
||||
}
|
||||
|
||||
private void updateFlags(Integer packageId, List<PhoneFidMap> subjects, String packageName) {
|
||||
private void updateFlags(Integer packageId, List<SubjectData> subjects, String packageName) {
|
||||
try {
|
||||
signalService.updatePackageStatus(packageId, Status.PROCESSING);
|
||||
signalService.setPackageStatus(packageId, Status.PROCESSING);
|
||||
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.updateFlags(subjects, packageId);
|
||||
if (!phoneFidsData.isEmpty()) {
|
||||
Signals signals = signalService.buildSignals(packageId, phoneFidsData);
|
||||
if (signalRestService.update(signals)) {
|
||||
log.info("Flags were updated successfully. PackageId: {} PackageName: {}. Package status changed to ON_MONITORING", packageId, packageName);
|
||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
||||
} else {
|
||||
log.info("Updated package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
||||
}
|
||||
} else {
|
||||
log.info("No flags were updated for package id {}. Package status changed to ON_MONITORING", packageId);
|
||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Ошибка при поиске фидов или перерасчете флагов просрочек. Package_id {}", packageId, e);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
||||
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
|
@ -20,12 +20,16 @@ public class PhoneService {
|
|||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public List<FidsPhoneData> findFidsPhoneData(List<PhoneFidMap> subjects) {
|
||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects) {
|
||||
return findFidsPhoneData(subjects, false);
|
||||
}
|
||||
|
||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects, boolean processNullFids) {
|
||||
List<FidsPhoneData> fidsPhoneDataList = new ArrayList<>();
|
||||
int batchSize = 10000;
|
||||
for (int i = 0; i < subjects.size(); i += batchSize) {
|
||||
int end = Math.min(i + batchSize, subjects.size());
|
||||
List<PhoneFidMap> currentSubjects = subjects.subList(i, end);
|
||||
List<SubjectData> currentSubjects = subjects.subList(i, end);
|
||||
List<String> phones = currentSubjects.stream().map(subject -> "9" + subject.getPhone()).toList();
|
||||
List<FidsData> fidsData = mapper.findFids(phones);
|
||||
|
||||
|
|
@ -36,7 +40,7 @@ public class PhoneService {
|
|||
Integer fid = fidsMap.get(phone);
|
||||
if (fid != null) {
|
||||
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), fid, subject.getPhone(), subject.getSubjectId()));
|
||||
} else {
|
||||
} else if (processNullFids) {
|
||||
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), null, subject.getPhone(), subject.getSubjectId()));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
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,6 +15,7 @@ import ru.nbch.credit_tracker.entities.response.external_errors.SgnlReport;
|
|||
import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
|
@ -34,17 +35,14 @@ public class SignalRestService {
|
|||
private static String DOWNLOAD_REPORT_URI = "onlinedownload";
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
private final IXmlProcessor xmlProcessor;
|
||||
private final StaxXmlProcessor staxProcessor;
|
||||
private final XmlUtilService xmlUtilService;
|
||||
private final String authToken;
|
||||
|
||||
public SignalRestService(@Qualifier(value = "restTemplate") RestTemplate restTemplate,
|
||||
IXmlProcessor xmlProcessor,
|
||||
StaxXmlProcessor staxProcessor,
|
||||
XmlUtilService xmlUtilService,
|
||||
CreditTrackerSettings config) throws Exception {
|
||||
this.restTemplate = restTemplate;
|
||||
this.xmlProcessor = xmlProcessor;
|
||||
this.staxProcessor = staxProcessor;
|
||||
this.xmlUtilService = xmlUtilService;
|
||||
this.authToken = buildToken(config.getSignalsToken(), config.getSignalsuser());
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +64,8 @@ public class SignalRestService {
|
|||
// good response
|
||||
return true;
|
||||
} else if (response.getStatusCode().value() == 200 && response.getBody() != null) {
|
||||
SgnlReport error = staxProcessor.read(response.getBody(), SgnlReport.class);
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(response.getBody(), SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при постановке пакета на мониторинг в официальный сервис сигналов: {}", error.getError().getDescription());
|
||||
} else {
|
||||
|
|
@ -93,7 +92,8 @@ public class SignalRestService {
|
|||
);
|
||||
String answer = response.getBody();
|
||||
|
||||
SgnlReport error = staxProcessor.read(answer, SgnlReport.class);
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при удалении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
||||
}
|
||||
|
|
@ -116,13 +116,15 @@ public class SignalRestService {
|
|||
|
||||
String answer = response.getBody();
|
||||
|
||||
SgnlReport error = staxProcessor.read(answer, SgnlReport.class);
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при получении пакета из сервиса НБКИ. packCode={}. Описание: {}", packCode, error.getError().getDescription());
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return xmlProcessor.read(answer, SgnlOnlineReport.class);
|
||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||
return processor.read(answer, SgnlOnlineReport.class);
|
||||
} catch (Exception e) {
|
||||
log.error("Ошибка при получении пакета из сервиса НБКИ. Код ошибки: {} packCode={}", response.getStatusCode().value(), packCode);
|
||||
return null;
|
||||
|
|
@ -146,7 +148,8 @@ public class SignalRestService {
|
|||
|
||||
byte[] answer = response.getBody();
|
||||
if (isXmlError(response.getBody())) {
|
||||
SgnlReport error = staxProcessor.read(answer, SgnlReport.class);
|
||||
StaxXmlProcessor staxXmlProcessor = xmlUtilService.staxXmlProcessor();
|
||||
SgnlReport error = staxXmlProcessor.read(answer, SgnlReport.class);
|
||||
if (error.getError().getDescription() != null) {
|
||||
log.error("Ошибка при скачивание отчета. fNameReport={}. Описание: {}", reportName, error.getError().getDescription());
|
||||
return null;
|
||||
|
|
@ -172,7 +175,8 @@ public class SignalRestService {
|
|||
}
|
||||
|
||||
private Resource compressFile(Signals signals) throws Exception {
|
||||
String requestData = xmlProcessor.asString(signals, false);
|
||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
||||
String requestData = processor.asString(signals, false);
|
||||
|
||||
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzipStream = new GZIPOutputStream(byteStream)) {
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
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,8 +1,8 @@
|
|||
package ru.nbch.credit_tracker.config.xml;
|
||||
package ru.nbch.credit_tracker.service.xml.jaxb;
|
||||
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.xml.sax.SAXException;
|
||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
||||
import ru.nbch.credit_tracker.entities.response.errors.MonitoringError;
|
||||
import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.MonitoringSignalResponse;
|
||||
|
|
@ -10,22 +10,33 @@ import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadRe
|
|||
import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport;
|
||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlProcessorImplAnyClasses;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.SgnlReportStatusStaxReader;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.StaxReader;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||
import ru.nbch.credit_tracker.service.xml.stax.XmlProcessorStaxImpl;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.transform.stax.StAXSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class XmlConfig {
|
||||
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
|
||||
|
||||
@Bean
|
||||
public IXmlProcessor xmlProcessor() throws JAXBException {
|
||||
@Service
|
||||
public class XmlUtilService {
|
||||
|
||||
//сделать бином
|
||||
public IXmlProcessor createJaxbProcessor() throws JAXBException {
|
||||
return new XmlProcessorImplAnyClasses(Charset.forName("windows-1251"),
|
||||
// unmarshalling classes
|
||||
MonitoringRequest.class,
|
||||
|
|
@ -38,10 +49,24 @@ public class XmlConfig {
|
|||
MonitoringSignalResponse.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StaxXmlProcessor staxXmlProcessor() {
|
||||
List<StaxReader<?>> staxReader = new ArrayList<>();
|
||||
staxReader.add(new SgnlReportStatusStaxReader());
|
||||
return new XmlProcessorStaxImpl(staxReader);
|
||||
}
|
||||
|
||||
public void validateXMLByXSD(InputStream xmlStream, String xsdPath) throws IOException, XMLStreamException, SAXException {
|
||||
SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
|
||||
Schema schema = sf.newSchema(new File(xsdPath));
|
||||
|
||||
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
|
||||
xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||
xmlInputFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
|
||||
xmlInputFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
|
||||
|
||||
Validator validator = schema.newValidator();
|
||||
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlStream);
|
||||
validator.validate(new StAXSource(xmlStreamReader));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,82 +1,29 @@
|
|||
package ru.nbch.credit_tracker.utils;
|
||||
|
||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
||||
import ru.nbch.credit_tracker.enums.SignalError;
|
||||
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
||||
|
||||
public class ValidationUtil {
|
||||
|
||||
private static String phoneRegex = "^\\d{9}$";
|
||||
private static String packageNameRegex = "^[A-Z0-9_]{1,22}$";
|
||||
private static String npIdRegex = "^\\S{1,36}$";
|
||||
|
||||
public static void validateMonitoringRequest(MonitoringRequest request) throws SignalClientException {
|
||||
if (request == null) {
|
||||
throw clientExcp(SignalError.ERROR_011, XmlErrorFormat.MonitoringError);
|
||||
}
|
||||
|
||||
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) {
|
||||
public static boolean validatePhone(String input) {
|
||||
if(input == null) {
|
||||
return false;
|
||||
}
|
||||
return Pattern.matches(phoneRegex, input);
|
||||
}
|
||||
|
||||
private static boolean validatePackageName(String input) {
|
||||
public static boolean validatePackageName(String input) {
|
||||
if(input == null) {
|
||||
return false;
|
||||
}
|
||||
return Pattern.matches(packageNameRegex, input);
|
||||
}
|
||||
|
||||
private static boolean validateNPId(String input) {
|
||||
public static boolean validateNPId(String input) {
|
||||
if(input == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,15 +4,12 @@ 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) {
|
||||
// public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat) {
|
||||
// return new SignalClientException(new EnumKeyMessage(enumKeyCode), xmlErrorFormat);
|
||||
// }
|
||||
public static SignalClientException excp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) {
|
||||
return new SignalClientException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat);
|
||||
}
|
||||
|
||||
public static SignalServerException serverExcp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) {
|
||||
return new SignalServerException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
package ru.nbch.credit_tracker.utils.error;
|
||||
|
||||
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||
|
||||
|
||||
public class SimpleMessageResolver {
|
||||
public String resolve(EnumKeyMessage errorMessage) {
|
||||
if (errorMessage == null) return "null";
|
||||
return String.format("%s %s", errorMessage.getSubject().getKey(), Arrays.toString(errorMessage.getArgs()));
|
||||
return String.format("(%s) args %s", errorMessage.getSubject().getKey(), Arrays.toString(errorMessage.getArgs()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +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.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>
|
||||
|
|
@ -1,63 +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.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>
|
||||
156
src/main/resources/mybatis/mapper/signal/SignalMapper.xml
Normal file
156
src/main/resources/mybatis/mapper/signal/SignalMapper.xml
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
<?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>
|
||||
|
|
@ -1,83 +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.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>
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue