Compare commits

...
Sign in to create a new pull request.

7 commits

Author SHA1 Message Date
etreschenkov
3e7bfa51a0 http://jira.mfd.msk:8088/browse/BKI-3341 2025-12-03 15:47:58 +03:00
etreschenkov
99222c740e http://jira.mfd.msk:8088/browse/BKI-3288 2025-11-06 12:20:58 +03:00
etreschenkov
5dc5e72496 http://jira.mfd.msk:8088/browse/BKI-3288 2025-11-06 12:20:38 +03:00
etreschenkov
b85cda38ef http://jira.mfd.msk:8088/browse/BKI-3287 2025-11-05 17:31:21 +03:00
etreschenkov
14138b4455 http://jira.mfd.msk:8088/browse/BKI-3287 2025-11-05 17:14:46 +03:00
etreschenkov
786cc89718 http://jira.mfd.msk:8088/browse/BKI-3286 2025-11-05 12:36:38 +03:00
etreschenkov
6b0f8668ae http://jira.mfd.msk:8088/browse/BKI-3286 2025-11-05 12:29:12 +03:00
10 changed files with 73 additions and 84 deletions

View file

@ -66,7 +66,7 @@ ct.load-dir=/opt/app/reports
# min # min
ct.monitoring-interval=${MONITORING_INTERVAL:15} ct.monitoring-interval=${MONITORING_INTERVAL:15}
# days # days
ct.update-flags-interval=${UPDATE_FLAGS_INTERVAL:1} ct.update-flags-cron-expression=${UPDATE_FLAGS_CRON_EXPRESSION:0 0 22 * * *}
ct.days-to-update-flags=${DAYS_TO_UPDATE_FLAGS:30} ct.days-to-update-flags=${DAYS_TO_UPDATE_FLAGS:30}
ct.encoding=windows-1251 ct.encoding=windows-1251

View file

@ -1,5 +1,5 @@
#commons #commons
APP_VERSION=1.20 APP_VERSION=1.24
REGISTRY_URL=rh8-vm3.nbki.msk:5000 REGISTRY_URL=rh8-vm3.nbki.msk:5000
JMX_PORT= JMX_PORT=
JMX_HOSTNAME= JMX_HOSTNAME=
@ -71,7 +71,7 @@ SIGNALS_USER=0001ZZ000001
# min # min
MONITORING_INTERVAL=15 MONITORING_INTERVAL=15
# days # days
UPDATE_FLAGS_INTERVAL=1 UPDATE_FLAGS_CRON_EXPRESSION=0 22 * * *
DAYS_TO_UPDATE_FLAGS=30 DAYS_TO_UPDATE_FLAGS=30

View file

@ -10,7 +10,7 @@
</parent> </parent>
<groupId>ru.nbch</groupId> <groupId>ru.nbch</groupId>
<artifactId>credit-tracker</artifactId> <artifactId>credit-tracker</artifactId>
<version>1.20</version> <version>1.24</version>
<name>credit_tracker</name> <name>credit_tracker</name>
<description>Credit Tracker Application</description> <description>Credit Tracker Application</description>

View file

@ -15,9 +15,9 @@ public class CreditTrackerApplication {
UpdateProcessingPackagesService updateProcessingPackagesService = ctx.getBean(UpdateProcessingPackagesService.class); UpdateProcessingPackagesService updateProcessingPackagesService = ctx.getBean(UpdateProcessingPackagesService.class);
MonitoringService monitoringService = ctx.getBean(MonitoringService.class); MonitoringService monitoringService = ctx.getBean(MonitoringService.class);
UpdatingFlagsService updatingFlagsService = ctx.getBean(UpdatingFlagsService.class); UpdatingFlagsService updatingFlagsService = ctx.getBean(UpdatingFlagsService.class);
updateProcessingPackagesService.run();
monitoringService.run(); monitoringService.run();
updatingFlagsService.run(); updatingFlagsService.run();
updateProcessingPackagesService.run();
} }
} }

View file

@ -29,7 +29,7 @@ public class CreditTrackerSettings {
private Long maxXmlFileSize; private Long maxXmlFileSize;
private String loadDir; private String loadDir;
private Long monitoringInterval; private Long monitoringInterval;
private Long updateFlagsInterval; private String updateFlagsCronExpression;
private Long daysToUpdateFlags; private Long daysToUpdateFlags;
private String encoding; private String encoding;

View file

@ -21,4 +21,5 @@ public interface PhoneFidMapMapper {
PhoneFidMap findPhoneFidMapById(@Param("id") Long packageId); PhoneFidMap findPhoneFidMapById(@Param("id") Long packageId);
boolean hasNonNullFids(@Param("packageId") Long packageId); boolean hasNonNullFids(@Param("packageId") Long packageId);
boolean hasOldRow(@Param("packageId") Long packageId, @Param("daysCount") Integer daysCount);
} }

View file

@ -1,22 +1,18 @@
package ru.nbch.credit_tracker.service; package ru.nbch.credit_tracker.service;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
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.enums.Status;
import ru.nbch.credit_tracker.service.signal.SignalRestService;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.List; import java.util.List;
import java.util.concurrent.Executors; import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ScheduledExecutorService; import org.slf4j.MDC;
import java.util.concurrent.TimeUnit; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.function.Predicate; import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
import ru.nbch.credit_tracker.entities.dto.UserPackage;
import ru.nbch.credit_tracker.enums.Status;
import ru.nbch.credit_tracker.mapper.signal.PhoneFidMapMapper;
import ru.nbch.credit_tracker.service.signal.SignalRestService;
/** /**
* Сервис периодического обновления фидов и флагов просрочек по пакетам находящимся в статусе ON_MONITORING * Сервис периодического обновления фидов и флагов просрочек по пакетам находящимся в статусе ON_MONITORING
@ -30,31 +26,40 @@ public class UpdatingFlagsService {
private final SignalRestService signalRestService; private final SignalRestService signalRestService;
private final MonitoringErrorProcesingService monitoringErrorProcesingService; private final MonitoringErrorProcesingService monitoringErrorProcesingService;
private final Long daysToUpdateFlags; private final Long daysToUpdateFlags;
private final Long updateFlagsInterval; private final String updateFlagsCronExpression;
private final PhoneFidMapMapper phoneFidMapMapper;
public UpdatingFlagsService(SignalService signalService, public UpdatingFlagsService(SignalService signalService,
SignalRestService signalRestService, SignalRestService signalRestService,
MonitoringErrorProcesingService monitoringErrorProcesingService, MonitoringErrorProcesingService monitoringErrorProcesingService,
CreditTrackerSettings config) { CreditTrackerSettings config,
PhoneFidMapMapper phoneFidMapMapper) {
this.signalService = signalService; this.signalService = signalService;
this.signalRestService = signalRestService; this.signalRestService = signalRestService;
this.monitoringErrorProcesingService = monitoringErrorProcesingService; this.monitoringErrorProcesingService = monitoringErrorProcesingService;
this.daysToUpdateFlags = config.getDaysToUpdateFlags() != null ? config.getDaysToUpdateFlags() : 1; this.daysToUpdateFlags = config.getDaysToUpdateFlags() != null ? config.getDaysToUpdateFlags() : 1;
this.updateFlagsInterval = config.getUpdateFlagsInterval() != null ? config.getUpdateFlagsInterval() : 1; this.updateFlagsCronExpression = config.getUpdateFlagsCronExpression() != null ? config.getUpdateFlagsCronExpression() : "*/10 * * * * *";
this.phoneFidMapMapper = phoneFidMapMapper;
} }
public void run() { public void run() {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("updating-flags-")); ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.scheduleAtFixedRate(this::update, 0, updateFlagsInterval, TimeUnit.DAYS); scheduler.setPoolSize(1);
scheduler.initialize();
scheduler.schedule(this::update, new CronTrigger(updateFlagsCronExpression));
} }
private void update() { public void update() {
log.info("Start updating flags"); log.info("Start updating flags");
List<UserPackage> packages = signalService.findPackagesOnMonitoring(); List<UserPackage> packages = signalService.findPackagesOnMonitoring();
for (UserPackage userPackage : packages) { for (UserPackage userPackage : packages) {
log.info("Updating flags for Package {}", userPackage.getPackageName());
MDC.put("ru.nbch.credit_tracker.log.mdc.key", "[" + userPackage.getPackageName() +"]"); MDC.put("ru.nbch.credit_tracker.log.mdc.key", "[" + userPackage.getPackageName() +"]");
log.info("Check on updating flags for Package {}", userPackage.getPackageName());
boolean hasOldRow = phoneFidMapMapper.hasOldRow(userPackage.getId(), daysToUpdateFlags.intValue());
log.info("There are {} old rows", hasOldRow ? "exist" : "doesn't exist");
if (hasOldRow) {
updateFlags(userPackage); updateFlags(userPackage);
}
MDC.remove("ru.nbch.credit_tracker.log.mdc.key"); MDC.remove("ru.nbch.credit_tracker.log.mdc.key");
} }
log.info("Finish updating flags"); log.info("Finish updating flags");
@ -65,8 +70,7 @@ public class UpdatingFlagsService {
String packageName = userPackage.getPackageName(); String packageName = userPackage.getPackageName();
try { try {
signalService.updatePackageStatus(packageId, Status.PROCESSING); signalService.updatePackageStatus(packageId, Status.PROCESSING);
Predicate<PhoneFidMap> filter = subject -> subject.getCalculatedAt() != null && hasDaysPassed(subject.getCalculatedAt()); SignalService.UpdateResult updateResult = signalService.updateSubjects(packageId, null);
SignalService.UpdateResult updateResult = signalService.updateSubjects(packageId, filter);
if (updateResult.isUpdated()) { if (updateResult.isUpdated()) {
if (signalRestService.setupMonitoring(packageId)) { if (signalRestService.setupMonitoring(packageId)) {
LocalDateTime monitoringAt = userPackage.getMonitoringAt() != null ? userPackage.getMonitoringAt() : LocalDateTime.now(); LocalDateTime monitoringAt = userPackage.getMonitoringAt() != null ? userPackage.getMonitoringAt() : LocalDateTime.now();

View file

@ -11,70 +11,45 @@
</resultMap> </resultMap>
<select id="findFlagsDebt5000" resultMap="FlagsFidDataResultMap"> <select id="findFlagsDebt5000" resultMap="FlagsFidDataResultMap">
SELECT rp.FID as fid, SELECT
CASE FID as fid,
WHEN EXISTS (SELECT 1 (case when (sum(case when AMT_PAST_DUE > 5000 then 1 else 0 end) = 0) then 0 else 1 end) as flag
FROM RU_PASTDUEARREAR rp2 FROM
WHERE rp2.FID = rp.FID (select FID, AMT_PAST_DUE, rank() over (partition by FID, ACC_SERIAL_NUM order by REPORTED_DT desc) rn
AND rp2.ACC_SERIAL_NUM = rp.ACC_SERIAL_NUM
AND rp2.REPORTED_DT = rp.MAX_REP_DATE
AND rp2.AMT_PAST_DUE > 5000) THEN 1
ELSE 0
END as flag
FROM (SELECT FID,
ACC_SERIAL_NUM,
MAX(REPORTED_DT) as MAX_REP_DATE
FROM RU_PASTDUEARREAR FROM RU_PASTDUEARREAR
WHERE FID IN WHERE FID IN
<foreach item="fid" collection="fids" open="(" separator="," close=")"> <foreach item="fid" collection="fids" open="(" separator="," close=")">
#{fid} #{fid}
</foreach> </foreach>
GROUP BY FID, ACC_SERIAL_NUM) rp )
GROUP BY rp.FID, rp.ACC_SERIAL_NUM, rp.MAX_REP_DATE where rn=1
group by FID
WITH UR WITH UR
</select> </select>
<select id="findFlag90ByPastDueArrear" resultMap="FlagsFidDataResultMap"> <select id="findFlag90ByPastDueArrear" resultMap="FlagsFidDataResultMap">
SELECT rp.FID as fid, SELECT
CASE FID as fid,
WHEN EXISTS (SELECT 1 (case when (sum(case when (REPORTED_DT >= #{reportedDate} and DAYS_PAST_DUE > 90) then 1 else 0 end) = 0) then 0 else 1 end) as flag
FROM RU_PASTDUEARREAR rp2
WHERE rp2.FID = rp.FID
AND rp2.REPORTED_DT >= #{reportedDate}
AND rp2.DAYS_PAST_DUE > 90) THEN 1
ELSE 0
END as flag
FROM (SELECT FID,
DAYS_PAST_DUE
FROM RU_PASTDUEARREAR FROM RU_PASTDUEARREAR
WHERE FID IN WHERE FID IN
<foreach item="fid" collection="fids" open="(" separator="," close=")"> <foreach item="fid" collection="fids" open="(" separator="," close=")">
#{fid} #{fid}
</foreach> </foreach>
GROUP BY FID, DAYS_PAST_DUE) rp GROUP BY FID
GROUP BY rp.FID, rp.DAYS_PAST_DUE
WITH UR WITH UR
</select> </select>
<select id="findFlag90ByRuPaymt" resultMap="FlagsFidDataResultMap"> <select id="findFlag90ByRuPaymt" resultMap="FlagsFidDataResultMap">
SELECT rp.FID as fid, SELECT
CASE FID as fid,
WHEN EXISTS (SELECT 1 (case when (sum(case when (REPORTED_DT >= #{reportedDate} and DAYS_PAST_DUE > 90) then 1 else 0 end) = 0) then 0 else 1 end) as flag
FROM RU_PAYMT rp2
WHERE rp2.FID = rp.FID
AND rp2.REPORTED_DT >= #{reportedDate}
AND rp2.DAYS_PAST_DUE > 90) THEN 1
ELSE 0
END as flag
FROM (SELECT FID,
DAYS_PAST_DUE
FROM RU_PAYMT FROM RU_PAYMT
WHERE FID IN WHERE FID IN
<foreach item="fid" collection="fids" open="(" separator="," close=")"> <foreach item="fid" collection="fids" open="(" separator="," close=")">
#{fid} #{fid}
</foreach> </foreach>
GROUP BY FID, DAYS_PAST_DUE) rp GROUP BY FID
GROUP BY rp.FID, rp.DAYS_PAST_DUE
WITH UR WITH UR
</select> </select>
</mapper> </mapper>

View file

@ -88,5 +88,11 @@
where package_id = #{packageId} AND fid is not null where package_id = #{packageId} AND fid is not null
</select> </select>
<select id="hasOldRow" resultType="java.lang.Boolean">
select EXISTS(SELECT 1
FROM signals_phone_fid_map
WHERE package_id = #{packageId}
AND calculated_at &lt; now() - make_interval(days => #{daysCount})
)
</select>
</mapper> </mapper>

View file

@ -0,0 +1,3 @@
CREATE INDEX IF NOT EXISTS
idx_signals_phone_fid_map_calculated_at
ON signals_phone_fid_map (calculated_at);