Put finding fids and calculating debt flags into separate thread

This commit is contained in:
Mikhail Trofimov 2025-06-16 09:55:28 +03:00
parent c35498f8d5
commit 96e0f20ebd
3 changed files with 47 additions and 15 deletions

View file

@ -5,6 +5,9 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Configuration
public class RestConfig {
@ -15,4 +18,9 @@ public class RestConfig {
restTemplate.setErrorHandler(new ResponseErrorHandler());
return restTemplate;
}
@Bean(name = "executorService")
public ExecutorService executorService() {
return Executors.newCachedThreadPool();
}
}

View file

@ -1,6 +1,7 @@
package ru.nbch.credit_tracker.facade;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
@ -20,6 +21,7 @@ import ru.nbch.credit_tracker.service.xml.IXmlProcessor;
import ru.nbch.credit_tracker.service.xml.XmlUtilService;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -35,18 +37,23 @@ public class SignalFacade {
private final FailureAnswerGenerator failureAnswerGenerator;
private final XmlUtilService xmlUtilService;
private final ExecutorService executor;
public SignalFacade(CreditTrackerSettings config,
AuthorizationService authorizationService,
SignalService signalService,
SignalRestService signalRestService,
FailureAnswerGenerator failureAnswerGenerator,
XmlUtilService xmlUtilService) {
XmlUtilService xmlUtilService,
@Qualifier("executorService") ExecutorService executor) {
this.config = config;
this.authorizationService = authorizationService;
this.signalService = signalService;
this.signalRestService = signalRestService;
this.failureAnswerGenerator = failureAnswerGenerator;
this.xmlUtilService = xmlUtilService;
this.executor = executor;
}
public ResponseEntity<Resource> setupMonitoring(MultipartFile file) {
@ -101,6 +108,7 @@ public class SignalFacade {
// Теперь знаем, что в архиве лежит ровно один файл с раширением xml и он весит меньше 2гб. Можно валидировать сам xml
// Пробуем распарсить xml
MonitoringRequest monitoringRequest;
Integer packageId;
try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
zipInputStream.getNextEntry();
@ -132,25 +140,16 @@ public class SignalFacade {
return getBadResponse(SignalError.ERROR_007);
}
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.registerPackage(monitoringRequest);
if(!phoneFidsData.isEmpty()) {
Signals signals = signalService.buildSignals(monitoringRequest, phoneFidsData);
// TODO validate?
String response = signalRestService.update(signals);
if (response == null) {
signalService.setPackageStatus(monitoringRequest, Status.ON_MONITORING);
} else {
signalService.setPackageStatus(monitoringRequest, Status.ERROR);
return getBadResponse(SignalError.ERROR_100); // TODO ??? Ошибка от офф сервиса или вынос этой логики?
}
}
packageId = signalService.registerPackage(monitoringRequest);
} catch (Exception e) {
log.error(e.getMessage(), e);
String errorPath = failureAnswerGenerator.generateFailureAnswer(SignalError.ERROR_100);
return ResponseEntity.internalServerError().body(new PathResource(errorPath));
}
// в отдельном потоке запускаем поиск фидов и расчет флагов просрочек
registerFidsAndDebts(monitoringRequest, packageId);
return ResponseEntity.ok().body(new PathResource("D:\\folder_name\\legal.xml")); // TODO generate success response
}
@ -196,6 +195,27 @@ public class SignalFacade {
return null;
}
private void registerFidsAndDebts(MonitoringRequest monitoringRequest, Integer packageId) {
executor.execute(() -> {
try {
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.registerSubjectsFidAndDebts(monitoringRequest, packageId);
if(!phoneFidsData.isEmpty()) {
Signals signals = signalService.buildSignals(monitoringRequest, phoneFidsData);
// TODO validate xsd?
String response = null;
// response = signalRestService.update(signals);
if (response == null) {
signalService.setPackageStatus(monitoringRequest, Status.ON_MONITORING);
} else {
signalService.setPackageStatus(monitoringRequest, Status.ERROR);
}
}
} catch (Exception e) {
log.error("Ошибка при поиске фидов или расчете флагов просрочек", e);
}
});
}
private boolean isZipFile(MultipartFile file) {
return file.getContentType() != null &&
(file.getContentType().equals("application/zip") || file.getContentType().equals("application/x-zip-compressed")) ||

View file

@ -44,9 +44,13 @@ public class SignalService {
return mapper.isPackageNotUnique(userId.substring(0, 6), request.getPackageName());
}
public List<PhoneService.FidsPhoneData> registerPackage(MonitoringRequest request) {
public Integer registerPackage(MonitoringRequest request) {
Integer packageId = mapper.registerPackage(request, LocalDateTime.now(), Status.PROCESSING.name());
mapper.registerSubjects(request.getSubjects().getSubject(), packageId);
return packageId;
}
public List<PhoneService.FidsPhoneData> registerSubjectsFidAndDebts(MonitoringRequest request, Integer packageId) {
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(request.getSubjects().getSubject());
fidsPhoneDataList.forEach(phoneData -> {
FlagsService.FlagsFidData flagsData = flagsService.findFlags(phoneData.getFid());