Compare commits
32 commits
query_opti
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e7bfa51a0 | ||
|
|
99222c740e | ||
|
|
5dc5e72496 | ||
|
|
b85cda38ef | ||
|
|
14138b4455 | ||
|
|
786cc89718 | ||
|
|
6b0f8668ae | ||
|
|
7bb08ebb59 | ||
|
|
439b934c5c | ||
|
|
10257b9cb2 | ||
|
|
8784b4e4f3 | ||
|
|
60cb6e9e8c | ||
|
|
ddc4418b1f | ||
|
|
33723b60d5 | ||
|
|
d963533a87 | ||
|
|
9253dd3f19 | ||
|
|
f950f98536 | ||
|
|
3b9c2eaa15 | ||
|
|
b61970a71e | ||
|
|
83bcea13b1 | ||
|
|
10180bb471 | ||
|
|
9a44d8cd5e | ||
|
|
6571e4d90f | ||
|
|
dc89f17761 | ||
|
|
ea12395559 | ||
|
|
d02b471466 | ||
|
|
6b5f39c755 | ||
|
|
e6bf35f337 | ||
|
|
061c24b89c | ||
|
|
2c3b2822c2 | ||
|
|
98622d7817 | ||
|
|
f888f9af4c |
67 changed files with 1234 additions and 1763 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
FROM eclipse-temurin:17-jre-alpine
|
FROM eclipse-temurin:17-jre-alpine
|
||||||
MAINTAINER ru.nbch
|
MAINTAINER ru.nbch
|
||||||
RUN apk add gcompat bash
|
|
||||||
|
|
||||||
VOLUME /opt/app/logs/app
|
VOLUME /opt/app/logs/app
|
||||||
VOLUME /opt/app/logs/json
|
VOLUME /opt/app/logs/json
|
||||||
|
|
@ -14,6 +13,11 @@ COPY maven/start-credit-tracker.sh /opt/app/start-credit-tracker.sh
|
||||||
COPY maven/credit-tracker.properties /opt/app/credit-tracker.properties
|
COPY maven/credit-tracker.properties /opt/app/credit-tracker.properties
|
||||||
COPY maven/monitoring-request.xsd /opt/app/monitoring-request.xsd
|
COPY maven/monitoring-request.xsd /opt/app/monitoring-request.xsd
|
||||||
COPY maven/signal-package.xsd /opt/app/signal-package.xsd
|
COPY maven/signal-package.xsd /opt/app/signal-package.xsd
|
||||||
|
COPY maven/ca_nbki.cer /usr/local/share/ca-certificates/corp.crt
|
||||||
|
|
||||||
|
RUN apk add --no-cache ca-certificates \
|
||||||
|
&& update-ca-certificates \
|
||||||
|
RUN apk add gcompat bash
|
||||||
|
|
||||||
RUN chmod +x /opt/app/start-credit-tracker.sh
|
RUN chmod +x /opt/app/start-credit-tracker.sh
|
||||||
ENTRYPOINT ["/opt/app/start-credit-tracker.sh"]
|
ENTRYPOINT ["/opt/app/start-credit-tracker.sh"]
|
||||||
|
|
|
||||||
33
ca_nbki.cer
Normal file
33
ca_nbki.cer
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFpTCCA42gAwIBAgIQXRfulgQYrrRFEpmSkmctvzANBgkqhkiG9w0BAQsFADBH
|
||||||
|
MRMwEQYKCZImiZPyLGQBGRYDbXNrMRQwEgYKCZImiZPyLGQBGRYEbmJraTEaMBgG
|
||||||
|
A1UEAxMRTkJLSS1Sb290LUNBLTIwMzIwHhcNMTQwNTE1MDYxODMzWhcNMzcwMjAx
|
||||||
|
MTE1OTEyWjBHMRMwEQYKCZImiZPyLGQBGRYDbXNrMRQwEgYKCZImiZPyLGQBGRYE
|
||||||
|
bmJraTEaMBgGA1UEAxMRTkJLSS1Sb290LUNBLTIwMzIwggIiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4ICDwAwggIKAoICAQCjS1l6kx+tjX2PGmQcVw9wg0Q6SCeWbiz7rxAYZPqE
|
||||||
|
OGckXWWjtfUOc8BhD3+BnC4BQ414X1HP2OWQ97pa2LogTksbpNpJ0+p82IPAYxV+
|
||||||
|
zpI0FnW09FpzjtB6l/1kE9gKecjBoFG3xDhhFmpzCeK7tsKt94j84XPV/Zo82gYM
|
||||||
|
egmqhOfQZ+2HAChBj7gaBJALybFN34wkvN9bWdBPmK/j1jQikEAT8QE9qwcdmCKB
|
||||||
|
snHw+heYX4uJyZEkXEzW8GxQfTaAL+3d8HdRm1ZT/dN9KScF3Tp13LnQPCcixYoB
|
||||||
|
dF9Pd3P8JDAQX1KUVceLq6e75Q36EQaHHfEA8iQjaKlEzD049QbfAfCzKkSTnxHk
|
||||||
|
rOGwhm/h3ipwdAL4eqWkXfRriEvQU2fXGYXS0bhDT0/vBVAhHUMZ15/Oww0QSlc9
|
||||||
|
clpau6rYG4m/Fmm8LPyEHROenbNwu35TqLl+CUFES25aE2oZcH6+SyE5dDgpX9e1
|
||||||
|
Plt3fT6DuEDuT+rWvm0N8NVPNlQP/1lcbvP1oQrby07LToPatdKF9V5g8MX/19bP
|
||||||
|
BFsQsUHLlfffWMqqX8W/OPt5da3XL6U7Z8aBdhS7VAqqrvNhAbJBxgyJAzSfSwtZ
|
||||||
|
K5dZTKrJMZqmosUSIrLVr+9oXlbqJjKGNWQjwCfRQmPPkCpmpy1SRg8NPDoa3OVU
|
||||||
|
3wIDAQABo4GMMIGJMBMGCSsGAQQBgjcUAgQGHgQAQwBBMAsGA1UdDwQEAwIBhjAP
|
||||||
|
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSkqLxdQSQ2+UIWrqSnms7lhp5zLjAQ
|
||||||
|
BgkrBgEEAYI3FQEEAwIBATAjBgkrBgEEAYI3FQIEFgQUvM7jX4RA4XBrZqhNhpl6
|
||||||
|
EDcEMZEwDQYJKoZIhvcNAQELBQADggIBAINqzWxlGXFgMwSlWmH4ocDa0A3ip51C
|
||||||
|
nEaWB58aomzOZYHnNLXj4KiwY59TMDkiRiql4wWCw2AJBVv2//7JwOqrk8rixq02
|
||||||
|
95NVX9TNefMKY3oo/g9bSqEsxoHgOoXP0QiY4GrYwAL6Bl0d/V9KUw5+BzBx/DKo
|
||||||
|
ncWD6KHnwFPBnHhIWiFlRAy2dX55rg6YSpB5/IlTQxGTjeg0OjX5w0ZE3L/0GZBl
|
||||||
|
O5W2E0RvUSErbjzoisxrhG48Mo5TtoGTmazKHRDqRCuZVnV0uEL9XaUOOV3G+LlP
|
||||||
|
/ujADUkF4iiIgoynB0W30fpwEqQFBSUxe+KzMw10ojaYaSz2g/HEg9ZKxy1a/bDL
|
||||||
|
6Va+vUMrypg26+MFrEdUwpPuORV1chtah/t+OxSk1dO82cuhjmRHX79mRwqjmXUs
|
||||||
|
5I/fNey8JWLCAV+Acf24CepdeYzeBGdh94t9FqTWw7aJaN5vL9ghwyG7JT8ozAfp
|
||||||
|
wYa1vq3nq+7SiELenQYYEUl792V8OsRV6N9nJkoLC12R9HGHjxMja5O2+Sw9LU4p
|
||||||
|
TjQcJt+qhT/c5+i6tQMjJUCTpXtOkaEezwrPpbUcoluGsz9vxs84eDtHiwumUCGj
|
||||||
|
XgaMSjcnY35dgne/x3kXcLYazdUYDoyYOEkgKG7ncSFg0lnIgwtYpqW6tzL3t9KN
|
||||||
|
Tsm6UcBOJAnv
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -8,21 +8,45 @@ server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b
|
||||||
# datasources
|
# datasources
|
||||||
# indic
|
# indic
|
||||||
ct.indic-data-source-settings.driver=com.ibm.db2.jcc.DB2Driver
|
ct.indic-data-source-settings.driver=com.ibm.db2.jcc.DB2Driver
|
||||||
ct.indic-data-source-settings.url=${DB_URL_INDIC:jdbc:db2://10.230.227.100:2668/cprosd22:currentSchema=INDIC;}
|
ct.indic-data-source-settings.url=${DB_URL_INDIC:jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=INDIC;}
|
||||||
ct.indic-data-source-settings.username=${USERNAME_INDIC:ros9appl}
|
ct.indic-data-source-settings.username=${USERNAME_INDIC:tester}
|
||||||
ct.indic-data-source-settings.password=${PASSWORD_INDIC:R0s9Appl}
|
ct.indic-data-source-settings.password=${PASSWORD_INDIC:tester}
|
||||||
|
ct.indic-data-source-settings.maximum-pool-size=${MAXIMUM_POOL_SIZE_INDIC:10}
|
||||||
|
ct.indic-data-source-settings.minimum-idle=${MINIMUM_IDLE_INDIC:10}
|
||||||
|
ct.indic-data-source-settings.connection-timeout=${CONNECTION_TIMEOUT_INDIC:10000}
|
||||||
|
ct.indic-data-source-settings.validation-timeout=${VALIDATION_TIMEOUT_INDIC:5000}
|
||||||
|
ct.indic-data-source-settings.idle-timeout=${IDLE_TIMEOUT_INDIC:600000}
|
||||||
|
ct.indic-data-source-settings.max-lifetime=${MAX_LIFETIME_INDIC:1800000}
|
||||||
|
ct.indic-data-source-settings.keepalive-time=${KEEPALIVE_TIME_INDIC:0}
|
||||||
|
ct.indic-data-source-settings.leak-detection-threshold=${LEAK_DETECTION_THRESHOLD_INDIC:0}
|
||||||
|
|
||||||
# signal
|
# signal
|
||||||
ct.signal-data-source-settings.driver=org.postgresql.Driver
|
ct.signal-data-source-settings.driver=org.postgresql.Driver
|
||||||
ct.signal-data-source-settings.url=${DB_URL_SIGNAL:jdbc:postgresql://10.200.200.133:5432/credit_tracker}
|
ct.signal-data-source-settings.url=${DB_URL_SIGNAL:jdbc:postgresql://10.200.200.133:5432/credit_tracker}
|
||||||
ct.signal-data-source-settings.username=${USERNAME_SIGNAL:credit_tracker_user}
|
ct.signal-data-source-settings.username=${USERNAME_SIGNAL:credit_tracker_user}
|
||||||
ct.signal-data-source-settings.password=${PASSWORD_SIGNAL:-}
|
ct.signal-data-source-settings.password=${PASSWORD_SIGNAL:-}
|
||||||
|
ct.signal-data-source-settings.maximum-pool-size=${MAXIMUM_POOL_SIZE_SIGNAL:10}
|
||||||
|
ct.signal-data-source-settings.minimum-idle=${MINIMUM_IDLE_SIGNAL:10}
|
||||||
|
ct.signal-data-source-settings.connection-timeout=${CONNECTION_TIMEOUT_SIGNAL:10000}
|
||||||
|
ct.signal-data-source-settings.validation-timeout=${VALIDATION_TIMEOUT_SIGNAL:5000}
|
||||||
|
ct.signal-data-source-settings.idle-timeout=${IDLE_TIMEOUT_SIGNAL:600000}
|
||||||
|
ct.signal-data-source-settings.max-lifetime=${MAX_LIFETIME_SIGNAL:1800000}
|
||||||
|
ct.signal-data-source-settings.keepalive-time=${KEEPALIVE_TIME_SIGNAL:0}
|
||||||
|
ct.signal-data-source-settings.leak-detection-threshold=${LEAK_DETECTION_THRESHOLD_SIGNAL:0}
|
||||||
|
|
||||||
# scoring
|
# scoring
|
||||||
ct.scoring-data-source-settings.driver=com.ibm.db2.jcc.DB2Driver
|
ct.scoring-data-source-settings.driver=com.ibm.db2.jcc.DB2Driver
|
||||||
ct.scoring-data-source-settings.url=${DB_URL_SCORING:jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=TEST_2_INDIC;}
|
ct.scoring-data-source-settings.url=${DB_URL_SCORING:jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=TEST_2_INDIC;}
|
||||||
ct.scoring-data-source-settings.username=${USERNAME_SCORING:tester}
|
ct.scoring-data-source-settings.username=${USERNAME_SCORING:tester}
|
||||||
ct.scoring-data-source-settings.password=${PASSWORD_SCORING:tester}
|
ct.scoring-data-source-settings.password=${PASSWORD_SCORING:tester}
|
||||||
|
ct.scoring-data-source-settings.maximum-pool-size=${MAXIMUM_POOL_SIZE_SCORING:10}
|
||||||
|
ct.scoring-data-source-settings.minimum-idle=${MINIMUM_IDLE_SCORING:10}
|
||||||
|
ct.scoring-data-source-settings.connection-timeout=${CONNECTION_TIMEOUT_SCORING:10000}
|
||||||
|
ct.scoring-data-source-settings.validation-timeout=${VALIDATION_TIMEOUT_SCORING:5000}
|
||||||
|
ct.scoring-data-source-settings.idle-timeout=${IDLE_TIMEOUT_SCORING:600000}
|
||||||
|
ct.scoring-data-source-settings.max-lifetime=${MAX_LIFETIME_SCORING:1800000}
|
||||||
|
ct.scoring-data-source-settings.keepalive-time=${KEEPALIVE_TIME_SCORING:0}
|
||||||
|
ct.scoring-data-source-settings.leak-detection-threshold=${LEAK_DETECTION_THRESHOLD_SCORING:0}
|
||||||
|
|
||||||
ct.max_xml_file_size=${ACCEPTED_XML_SIZE:1024}
|
ct.max_xml_file_size=${ACCEPTED_XML_SIZE:1024}
|
||||||
spring.servlet.multipart.max-file-size=${ACCEPTED_ARCHIVE_SIZE:2048MB}
|
spring.servlet.multipart.max-file-size=${ACCEPTED_ARCHIVE_SIZE:2048MB}
|
||||||
|
|
@ -42,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
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#commons
|
#commons
|
||||||
APP_VERSION=1.15
|
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=
|
||||||
|
|
@ -24,16 +24,41 @@ SERVER_PORT=8099
|
||||||
DB_URL_INDIC=jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=INDIC;
|
DB_URL_INDIC=jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=INDIC;
|
||||||
USERNAME_INDIC=tester
|
USERNAME_INDIC=tester
|
||||||
PASSWORD_INDIC=tester
|
PASSWORD_INDIC=tester
|
||||||
|
MAXIMUM_POOL_SIZE_INDIC=10
|
||||||
|
MINIMUM_IDLE_INDIC=10
|
||||||
|
CONNECTION_TIMEOUT_INDIC=10000
|
||||||
|
VALIDATION_TIMEOUT_INDIC=5000
|
||||||
|
IDLE_TIMEOUT_INDIC=600000
|
||||||
|
MAX_LIFETIME_INDIC=1800000
|
||||||
|
KEEPALIVE_TIME_INDIC=0
|
||||||
|
LEAK_DETECTION_THRESHOLD_INDIC=0
|
||||||
|
|
||||||
|
|
||||||
# signal
|
# signal
|
||||||
DB_URL_SIGNAL=jdbc:postgresql://10.200.200.133:5432/credit_tracker
|
DB_URL_SIGNAL=jdbc:postgresql://10.200.200.133:5432/credit_tracker
|
||||||
USERNAME_SIGNAL=credit_tracker_user
|
USERNAME_SIGNAL=credit_tracker_user
|
||||||
PASSWORD_SIGNAL=
|
PASSWORD_SIGNAL=
|
||||||
|
MAXIMUM_POOL_SIZE_SIGNAL=10
|
||||||
|
MINIMUM_IDLE_SIGNAL=10
|
||||||
|
CONNECTION_TIMEOUT_SIGNAL=10000
|
||||||
|
VALIDATION_TIMEOUT_SIGNAL=5000
|
||||||
|
IDLE_TIMEOUT_SIGNAL=600000
|
||||||
|
MAX_LIFETIME_SIGNAL=1800000
|
||||||
|
KEEPALIVE_TIME_SIGNAL=0
|
||||||
|
LEAK_DETECTION_THRESHOLD_SIGNAL=0
|
||||||
|
|
||||||
# scoring
|
# scoring
|
||||||
DB_URL_SCORING=jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=TEST_2_INDIC;
|
DB_URL_SCORING=jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=TEST_2_INDIC;
|
||||||
USERNAME_SCORING=tester
|
USERNAME_SCORING=tester
|
||||||
PASSWORD_SCORING=tester
|
PASSWORD_SCORING=tester
|
||||||
|
MAXIMUM_POOL_SIZE_SCORING=10
|
||||||
|
MINIMUM_IDLE_SCORING=10
|
||||||
|
CONNECTION_TIMEOUT_SCORING=10000
|
||||||
|
VALIDATION_TIMEOUT_SCORING=5000
|
||||||
|
IDLE_TIMEOUT_SCORING=600000
|
||||||
|
MAX_LIFETIME_SCORING=1800000
|
||||||
|
KEEPALIVE_TIME_SCORING=0
|
||||||
|
LEAK_DETECTION_THRESHOLD_SCORING=0
|
||||||
|
|
||||||
# размер в mb
|
# размер в mb
|
||||||
ACCEPTED_XML_SIZE=1024
|
ACCEPTED_XML_SIZE=1024
|
||||||
|
|
@ -46,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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,36 @@ services:
|
||||||
- DB_URL_INDIC=${DB_URL_INDIC}
|
- DB_URL_INDIC=${DB_URL_INDIC}
|
||||||
- USERNAME_INDIC=${USERNAME_INDIC}
|
- USERNAME_INDIC=${USERNAME_INDIC}
|
||||||
- PASSWORD_INDIC=${PASSWORD_INDIC}
|
- PASSWORD_INDIC=${PASSWORD_INDIC}
|
||||||
|
- MAXIMUM_POOL_SIZE_INDIC=${MAXIMUM_POOL_SIZE_INDIC}
|
||||||
|
- MINIMUM_IDLE_INDIC=${MINIMUM_IDLE_INDIC}
|
||||||
|
- CONNECTION_TIMEOUT_INDIC=${CONNECTION_TIMEOUT_INDIC}
|
||||||
|
- VALIDATION_TIMEOUT_INDIC=${VALIDATION_TIMEOUT_INDIC}
|
||||||
|
- IDLE_TIMEOUT_INDIC=${IDLE_TIMEOUT_INDIC}
|
||||||
|
- MAX_LIFETIME_INDIC=${MAX_LIFETIME_INDIC}
|
||||||
|
- KEEPALIVE_TIME_INDIC=${KEEPALIVE_TIME_INDIC}
|
||||||
|
- LEAK_DETECTION_THRESHOLD_INDIC=${LEAK_DETECTION_THRESHOLD_INDIC}
|
||||||
- DB_URL_SIGNAL=${DB_URL_SIGNAL}
|
- DB_URL_SIGNAL=${DB_URL_SIGNAL}
|
||||||
- USERNAME_SIGNAL=${USERNAME_SIGNAL}
|
- USERNAME_SIGNAL=${USERNAME_SIGNAL}
|
||||||
- PASSWORD_SIGNAL=${PASSWORD_SIGNAL}
|
- PASSWORD_SIGNAL=${PASSWORD_SIGNAL}
|
||||||
|
- MAXIMUM_POOL_SIZE_SIGNAL=${MAXIMUM_POOL_SIZE_SIGNAL}
|
||||||
|
- MINIMUM_IDLE_SIGNAL=${MINIMUM_IDLE_SIGNAL}
|
||||||
|
- CONNECTION_TIMEOUT_SIGNAL=${CONNECTION_TIMEOUT_SIGNAL}
|
||||||
|
- VALIDATION_TIMEOUT_SIGNAL=${VALIDATION_TIMEOUT_SIGNAL}
|
||||||
|
- IDLE_TIMEOUT_SIGNAL=${IDLE_TIMEOUT_SIGNAL}
|
||||||
|
- MAX_LIFETIME_SIGNAL=${MAX_LIFETIME_SIGNAL}
|
||||||
|
- KEEPALIVE_TIME_SIGNAL=${KEEPALIVE_TIME_SIGNAL}
|
||||||
|
- LEAK_DETECTION_THRESHOLD_SIGNAL=${LEAK_DETECTION_THRESHOLD_SIGNAL}
|
||||||
- DB_URL_SCORING=${DB_URL_SCORING}
|
- DB_URL_SCORING=${DB_URL_SCORING}
|
||||||
- USERNAME_SCORING=${USERNAME_SCORING}
|
- USERNAME_SCORING=${USERNAME_SCORING}
|
||||||
- PASSWORD_SCORING=${PASSWORD_SCORING}
|
- PASSWORD_SCORING=${PASSWORD_SCORING}
|
||||||
|
- MAXIMUM_POOL_SIZE_SCORING=${MAXIMUM_POOL_SIZE_SCORING}
|
||||||
|
- MINIMUM_IDLE_SCORING=${MINIMUM_IDLE_SCORING}
|
||||||
|
- CONNECTION_TIMEOUT_SCORING=${CONNECTION_TIMEOUT_SCORING}
|
||||||
|
- VALIDATION_TIMEOUT_SCORING=${VALIDATION_TIMEOUT_SCORING}
|
||||||
|
- IDLE_TIMEOUT_SCORING=${IDLE_TIMEOUT_SCORING}
|
||||||
|
- MAX_LIFETIME_SCORING=${MAX_LIFETIME_SCORING}
|
||||||
|
- KEEPALIVE_TIME_SCORING=${KEEPALIVE_TIME_SCORING}
|
||||||
|
- LEAK_DETECTION_THRESHOLD_SCORING=${LEAK_DETECTION_THRESHOLD_SCORING}
|
||||||
- ACCEPTED_XML_SIZE=${ACCEPTED_XML_SIZE}
|
- ACCEPTED_XML_SIZE=${ACCEPTED_XML_SIZE}
|
||||||
- ACCEPTED_ARCHIVE_SIZE=${ACCEPTED_ARCHIVE_SIZE}
|
- ACCEPTED_ARCHIVE_SIZE=${ACCEPTED_ARCHIVE_SIZE}
|
||||||
- SIGNALS_ROOT_URI=${SIGNALS_ROOT_URI}
|
- SIGNALS_ROOT_URI=${SIGNALS_ROOT_URI}
|
||||||
|
|
|
||||||
27
pom.xml
27
pom.xml
|
|
@ -10,7 +10,7 @@
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>ru.nbch</groupId>
|
<groupId>ru.nbch</groupId>
|
||||||
<artifactId>credit-tracker</artifactId>
|
<artifactId>credit-tracker</artifactId>
|
||||||
<version>1.15</version>
|
<version>1.24</version>
|
||||||
<name>credit_tracker</name>
|
<name>credit_tracker</name>
|
||||||
<description>Credit Tracker Application</description>
|
<description>Credit Tracker Application</description>
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<git.info.prefix>git_info</git.info.prefix>
|
<git.info.prefix>git_info</git.info.prefix>
|
||||||
<git.info.filename>git.properties</git.info.filename>
|
<git.info.filename>git.properties</git.info.filename>
|
||||||
<registry.url>rh8-vm3.nbki.msk:5000</registry.url>
|
<registry.url>10.230.238.56:5000</registry.url>
|
||||||
<!-- <registry.url>rh8-vm3.nbki.msk:5000</registry.url>-->
|
<!-- <registry.url>rh8-vm3.nbki.msk:5000</registry.url>-->
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
@ -126,11 +126,6 @@
|
||||||
<version>3.0.4</version>
|
<version>3.0.4</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-junit-jupiter</artifactId>
|
<artifactId>mockito-junit-jupiter</artifactId>
|
||||||
|
|
@ -142,7 +137,6 @@
|
||||||
<profile>
|
<profile>
|
||||||
<id>docker-push-dev</id>
|
<id>docker-push-dev</id>
|
||||||
<build>
|
<build>
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>io.fabric8</groupId>
|
<groupId>io.fabric8</groupId>
|
||||||
|
|
@ -153,7 +147,7 @@
|
||||||
<id>Build and deploy docker container</id>
|
<id>Build and deploy docker container</id>
|
||||||
<phase>install</phase>
|
<phase>install</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<!--<goal>build</goal>-->
|
<goal>build</goal>
|
||||||
<goal>push</goal>
|
<goal>push</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
@ -169,11 +163,15 @@
|
||||||
<inline>
|
<inline>
|
||||||
<files>
|
<files>
|
||||||
<file>
|
<file>
|
||||||
<source>${project.build.directory}/${project.build.finalName}.jar</source>
|
<source>
|
||||||
|
${project.build.directory}/${project.build.finalName}.jar
|
||||||
|
</source>
|
||||||
<outputDirectory>.</outputDirectory>
|
<outputDirectory>.</outputDirectory>
|
||||||
</file>
|
</file>
|
||||||
<file>
|
<file>
|
||||||
<source>${project.basedir}/apm-agent/elastic-apm-agent-1.45.0.jar</source>
|
<source>
|
||||||
|
${project.basedir}/apm-agent/elastic-apm-agent-1.45.0.jar
|
||||||
|
</source>
|
||||||
<outputDirectory>.</outputDirectory>
|
<outputDirectory>.</outputDirectory>
|
||||||
</file>
|
</file>
|
||||||
<file>
|
<file>
|
||||||
|
|
@ -192,6 +190,12 @@
|
||||||
<source>${project.basedir}/signal-package.xsd</source>
|
<source>${project.basedir}/signal-package.xsd</source>
|
||||||
<outputDirectory>.</outputDirectory>
|
<outputDirectory>.</outputDirectory>
|
||||||
</file>
|
</file>
|
||||||
|
<file>
|
||||||
|
<source>
|
||||||
|
${project.basedir}/ca_nbki.cer
|
||||||
|
</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
</files>
|
</files>
|
||||||
</inline>
|
</inline>
|
||||||
</assembly>
|
</assembly>
|
||||||
|
|
@ -204,7 +208,6 @@
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,12 @@ import ru.nbch.credit_tracker.entities.external_request.signals.Person;
|
||||||
import ru.nbch.credit_tracker.service.indic.PersonService;
|
import ru.nbch.credit_tracker.service.indic.PersonService;
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PersonFactoryBuilder {
|
public class PersonFactoryBuilder {
|
||||||
private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy");
|
private final static DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd.MM.yyyy");
|
||||||
|
|
||||||
private final static String DEFAULT_DATE = "01.01.2000";
|
private final static String DEFAULT_DATE = "01.01.2000";
|
||||||
private final static String IP = "0";
|
private final static String IP = "0";
|
||||||
|
|
@ -31,7 +30,7 @@ public class PersonFactoryBuilder {
|
||||||
|
|
||||||
|
|
||||||
private PersonService.PersonData personData;
|
private PersonService.PersonData personData;
|
||||||
private Integer uid;
|
private Long uid;
|
||||||
|
|
||||||
public static PersonFactoryBuilder builder() {
|
public static PersonFactoryBuilder builder() {
|
||||||
return new PersonFactoryBuilder();
|
return new PersonFactoryBuilder();
|
||||||
|
|
@ -42,7 +41,7 @@ public class PersonFactoryBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PersonFactoryBuilder uid(Integer uid) {
|
public PersonFactoryBuilder uid(Long uid) {
|
||||||
this.uid = uid;
|
this.uid = uid;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -57,10 +56,10 @@ public class PersonFactoryBuilder {
|
||||||
person.setS(nameData.getLastName());
|
person.setS(nameData.getLastName());
|
||||||
person.setN(nameData.getFirstName());
|
person.setN(nameData.getFirstName());
|
||||||
person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null);
|
person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null);
|
||||||
person.setD(DATE_FORMAT.format(CTUtil.localDatetoDate(nameData.getBirthDate())));
|
person.setD(DATE_FORMAT.format(nameData.getBirthDate()));
|
||||||
|
|
||||||
person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum()));
|
person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum()));
|
||||||
person.setPd(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now()))); // Do not use passport iss_date. Signal service could reject the package
|
person.setPd(DATE_FORMAT.format(LocalDate.now())); // Do not use passport iss_date. Signal service could reject the package
|
||||||
person.setDt(getDt(passportData.getIdType(), passportData.getIdType2()));
|
person.setDt(getDt(passportData.getIdType(), passportData.getIdType2()));
|
||||||
if (person.getDt() != null && person.getDt().equals("999")) {
|
if (person.getDt() != null && person.getDt().equals("999")) {
|
||||||
person.setOdt(ODT);
|
person.setOdt(ODT);
|
||||||
|
|
@ -69,12 +68,12 @@ public class PersonFactoryBuilder {
|
||||||
person.setIp(IP);
|
person.setIp(IP);
|
||||||
person.setUid(uid);
|
person.setUid(uid);
|
||||||
person.setOksm(OKSM);
|
person.setOksm(OKSM);
|
||||||
person.setConsentDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
|
person.setConsentDate(DATE_FORMAT.format(LocalDate.now()));
|
||||||
person.setConsentPurpose(CONSENT_PURPOSE);
|
person.setConsentPurpose(CONSENT_PURPOSE);
|
||||||
person.setReportUser(REPORT_USER);
|
person.setReportUser(REPORT_USER);
|
||||||
person.setLiability(LIABILITY);
|
person.setLiability(LIABILITY);
|
||||||
person.setConsentPeriod(CONSENT_PERIOD);
|
person.setConsentPeriod(CONSENT_PERIOD);
|
||||||
person.setAgrDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
|
person.setAgrDate(DATE_FORMAT.format(LocalDate.now()));
|
||||||
person.setReportUserRegNum(REPORT_USER_REG_NUM);
|
person.setReportUserRegNum(REPORT_USER_REG_NUM);
|
||||||
person.setReportUserTaxID(REPORT_USER_TAX_ID);
|
person.setReportUserTaxID(REPORT_USER_TAX_ID);
|
||||||
person.setConsentHash(CONSENT_HASH);
|
person.setConsentHash(CONSENT_HASH);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
package ru.nbch.credit_tracker.config.datasource;
|
package ru.nbch.credit_tracker.config.datasource;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
import ru.nbch.credit_tracker.config.settings.DataSourceSettings;
|
import ru.nbch.credit_tracker.config.settings.DataSourceSettings;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
public class DatabaseConfig {
|
public class DatabaseConfig {
|
||||||
|
|
||||||
protected DataSource createDataSource(DataSourceSettings settings) {
|
protected HikariDataSource createDataSource(DataSourceSettings settings) {
|
||||||
return DataSourceBuilder.create()
|
return DataSourceBuilder.create()
|
||||||
.driverClassName(settings.driver())
|
.driverClassName(settings.driver())
|
||||||
.url(settings.url())
|
.url(settings.url())
|
||||||
.username(settings.username())
|
.username(settings.username())
|
||||||
.password(settings.password())
|
.password(settings.password())
|
||||||
|
.type(HikariDataSource.class)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.config.datasource;
|
package ru.nbch.credit_tracker.config.datasource;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||||
|
|
@ -9,8 +10,8 @@ import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
|
import ru.nbch.credit_tracker.config.settings.DataSourceSettings;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
|
@ -29,14 +30,25 @@ public class IndicDataSourceConfig extends DatabaseConfig {
|
||||||
|
|
||||||
@Bean(name = "indicDataSource")
|
@Bean(name = "indicDataSource")
|
||||||
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
||||||
DataSource dataSource = createDataSource(config.getIndicDataSourceSettings());
|
DataSourceSettings indicSetings = config.getIndicDataSourceSettings();
|
||||||
|
|
||||||
|
HikariDataSource dataSource = createDataSource(indicSetings);
|
||||||
|
dataSource.setMaximumPoolSize(indicSetings.maximumPoolSize());
|
||||||
|
dataSource.setMinimumIdle(indicSetings.minimumIdle());
|
||||||
|
dataSource.setConnectionTimeout(indicSetings.connectionTimeout());
|
||||||
|
dataSource.setValidationTimeout(indicSetings.validationTimeout());
|
||||||
|
dataSource.setIdleTimeout(indicSetings.idleTimeout());
|
||||||
|
dataSource.setMaxLifetime(indicSetings.maxLifetime());
|
||||||
|
dataSource.setKeepaliveTime(indicSetings.keepaliveTime());
|
||||||
|
dataSource.setLeakDetectionThreshold(indicSetings.leakDetectionThreshold());
|
||||||
|
|
||||||
try (Connection connection = dataSource.getConnection()) {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
connection.isValid(3);
|
connection.isValid(3);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unable to connect to Indic url={}", config.getIndicDataSourceSettings().url(), e);
|
log.error("Unable to connect to Indic url={}", indicSetings.url(), e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
log.info("Connected to Indic: url={}", config.getIndicDataSourceSettings().url());
|
log.info("Connected to Indic: url={}", indicSetings.url());
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,10 +60,5 @@ public class IndicDataSourceConfig extends DatabaseConfig {
|
||||||
sqlSessionFactoryBean.setTypeHandlersPackage("ru.nbch.credit_tracker.config.datasource.handlers");
|
sqlSessionFactoryBean.setTypeHandlersPackage("ru.nbch.credit_tracker.config.datasource.handlers");
|
||||||
return sqlSessionFactoryBean.getObject();
|
return sqlSessionFactoryBean.getObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "jdbcTemplateIndic")
|
|
||||||
public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(@Qualifier("indicDataSource") DataSource dataSource) {
|
|
||||||
return new NamedParameterJdbcTemplate(dataSource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.config.datasource;
|
package ru.nbch.credit_tracker.config.datasource;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||||
|
|
@ -10,6 +11,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
|
import ru.nbch.credit_tracker.config.settings.DataSourceSettings;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
|
@ -28,14 +30,25 @@ public class ScoringDataSourceConfig extends DatabaseConfig {
|
||||||
|
|
||||||
@Bean(name = "scoringDataSource")
|
@Bean(name = "scoringDataSource")
|
||||||
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
||||||
DataSource dataSource = createDataSource(config.getScoringDataSourceSettings());
|
DataSourceSettings scoringSetings = config.getScoringDataSourceSettings();
|
||||||
|
|
||||||
|
HikariDataSource dataSource = createDataSource(scoringSetings);
|
||||||
|
dataSource.setMaximumPoolSize(scoringSetings.maximumPoolSize());
|
||||||
|
dataSource.setMinimumIdle(scoringSetings.minimumIdle());
|
||||||
|
dataSource.setConnectionTimeout(scoringSetings.connectionTimeout());
|
||||||
|
dataSource.setValidationTimeout(scoringSetings.validationTimeout());
|
||||||
|
dataSource.setIdleTimeout(scoringSetings.idleTimeout());
|
||||||
|
dataSource.setMaxLifetime(scoringSetings.maxLifetime());
|
||||||
|
dataSource.setKeepaliveTime(scoringSetings.keepaliveTime());
|
||||||
|
dataSource.setLeakDetectionThreshold(scoringSetings.leakDetectionThreshold());
|
||||||
|
|
||||||
try (Connection connection = dataSource.getConnection()) {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
connection.isValid(3);
|
connection.isValid(3);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unable to connect to Scoring url={}", config.getScoringDataSourceSettings().url(), e);
|
log.error("Unable to connect to Scoring url={}", scoringSetings.url(), e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
log.info("Connected to Scoring: url={}", config.getScoringDataSourceSettings().url());
|
log.info("Connected to Scoring: url={}", scoringSetings.url());
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.config.datasource;
|
package ru.nbch.credit_tracker.config.datasource;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||||
|
|
@ -10,6 +11,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
|
import ru.nbch.credit_tracker.config.settings.DataSourceSettings;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
|
@ -27,14 +29,25 @@ public class SignalDataSourceConfig extends DatabaseConfig {
|
||||||
|
|
||||||
@Bean(name = "signalDataSource")
|
@Bean(name = "signalDataSource")
|
||||||
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
||||||
DataSource dataSource = createDataSource(config.getSignalDataSourceSettings());
|
DataSourceSettings signalSetings = config.getSignalDataSourceSettings();
|
||||||
|
|
||||||
|
HikariDataSource dataSource = createDataSource(signalSetings);
|
||||||
|
dataSource.setMaximumPoolSize(signalSetings.maximumPoolSize());
|
||||||
|
dataSource.setMinimumIdle(signalSetings.minimumIdle());
|
||||||
|
dataSource.setConnectionTimeout(signalSetings.connectionTimeout());
|
||||||
|
dataSource.setValidationTimeout(signalSetings.validationTimeout());
|
||||||
|
dataSource.setIdleTimeout(signalSetings.idleTimeout());
|
||||||
|
dataSource.setMaxLifetime(signalSetings.maxLifetime());
|
||||||
|
dataSource.setKeepaliveTime(signalSetings.keepaliveTime());
|
||||||
|
dataSource.setLeakDetectionThreshold(signalSetings.leakDetectionThreshold());
|
||||||
|
|
||||||
try (Connection connection = dataSource.getConnection()) {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
connection.isValid(3);
|
connection.isValid(3);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
log.error("Unable to connect to Signal url={}", config.getSignalDataSourceSettings().url(), e);
|
log.error("Unable to connect to Signal url={}", signalSetings.url(), e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
log.info("Connected to Signal: url={}", config.getSignalDataSourceSettings().url());
|
log.info("Connected to Signal: url={}", signalSetings.url());
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.nbch.credit_tracker.config.mdc;
|
||||||
|
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(Aspect.class)
|
||||||
|
@EnableAspectJAutoProxy(proxyTargetClass = true)
|
||||||
|
public class AopMdcConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MdcAspect mdcAspect() {
|
||||||
|
return new MdcAspect();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package ru.nbch.credit_tracker.config.mdc;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.slf4j.MDC;
|
||||||
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Aspect
|
||||||
|
public class MdcAspect {
|
||||||
|
|
||||||
|
// For methods that set an MDC value (from a method argument) and then clear it at the end
|
||||||
|
@Around("@annotation(setAndClearMdc)")
|
||||||
|
public Object setAndClearMdcAdvice(ProceedingJoinPoint pjp, SetAndClearMdc setAndClearMdc) throws Throwable {
|
||||||
|
Object[] args = pjp.getArgs();
|
||||||
|
int index = setAndClearMdc.argIndex();
|
||||||
|
Object obj = (args != null && args.length > index) ? args[index] : null;
|
||||||
|
if (obj instanceof MonitoringRequest request) {
|
||||||
|
if (request.getPackageName() != null) {
|
||||||
|
putMdcValue(setAndClearMdc.key(), request.getPackageName());
|
||||||
|
}
|
||||||
|
} else if (obj instanceof UserPackage userPackage) {
|
||||||
|
if (userPackage.getPackageName() != null) {
|
||||||
|
putMdcValue(setAndClearMdc.key(), userPackage.getPackageName());
|
||||||
|
}
|
||||||
|
} else if (obj instanceof String packageName) {
|
||||||
|
putMdcValue(setAndClearMdc.key(), packageName);
|
||||||
|
} else {
|
||||||
|
log.debug("no packageName found for for {}", pjp.toShortString());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return pjp.proceed();
|
||||||
|
} finally {
|
||||||
|
MDC.remove(setAndClearMdc.key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putMdcValue(String key, String value) {
|
||||||
|
try {
|
||||||
|
MDC.put(key, "[" + value + "] ");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
log.error("{}", ExceptionUtils.getStackTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package ru.nbch.credit_tracker.config.mdc;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
// Annotation to set an MDC key based on a method argument and clear it after method execution
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface SetAndClearMdc {
|
||||||
|
String key() default "ru.nbch.credit_tracker.log.mdc.key";
|
||||||
|
// The index of the method argument to use for the MDC value (defaults to the first argument)
|
||||||
|
int argIndex() default 0;
|
||||||
|
}
|
||||||
|
|
@ -55,7 +55,12 @@ public class GlobalExceptionHandler {
|
||||||
commonError.setErrorText(errorText);
|
commonError.setErrorText(errorText);
|
||||||
|
|
||||||
if (ex instanceof SignalClientException) {
|
if (ex instanceof SignalClientException) {
|
||||||
|
String packageName = ((SignalClientException) ex).getPackageName();
|
||||||
|
if(packageName != null ) {
|
||||||
|
log.warn("Response error: {}. PackageName: {}", errorText, packageName);
|
||||||
|
} else {
|
||||||
log.warn("Response error: {}", errorText);
|
log.warn("Response error: {}", errorText);
|
||||||
|
}
|
||||||
return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST);
|
return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST);
|
||||||
} else {
|
} else {
|
||||||
Exception cause = ((SignalServerException) ex).getCause();
|
Exception cause = ((SignalServerException) ex).getCause();
|
||||||
|
|
@ -69,6 +74,7 @@ public class GlobalExceptionHandler {
|
||||||
switch (ex.getErrorFormat()) {
|
switch (ex.getErrorFormat()) {
|
||||||
case MonitoringError -> commonError = new MonitoringError();
|
case MonitoringError -> commonError = new MonitoringError();
|
||||||
case MonitoringActivePackagesError -> commonError = new MonitoringActivePackagesError();
|
case MonitoringActivePackagesError -> commonError = new MonitoringActivePackagesError();
|
||||||
|
case MonitoringAllPackagesError -> commonError = new MonitoringAllPackagesError();
|
||||||
case MonitoringDownloadError -> commonError = new MonitoringDownloadError();
|
case MonitoringDownloadError -> commonError = new MonitoringDownloadError();
|
||||||
case MonitoringReportListError -> commonError = new MonitoringReportListError();
|
case MonitoringReportListError -> commonError = new MonitoringReportListError();
|
||||||
case MonitoringPackageDeleteError -> commonError = new MonitoringPackageDeleteError();
|
case MonitoringPackageDeleteError -> commonError = new MonitoringPackageDeleteError();
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,9 @@ package ru.nbch.credit_tracker.config.rest.filters;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import jakarta.servlet.http.Part;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
@ -22,6 +14,10 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Order(0)
|
@Order(0)
|
||||||
|
|
@ -34,7 +30,7 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
protected boolean shouldNotFilter(HttpServletRequest request) {
|
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||||
String path = request.getRequestURI();
|
String path = request.getRequestURI();
|
||||||
return path.startsWith("/actuator/health") || path.startsWith("/swagger")
|
return path.startsWith("/actuator/health") || path.startsWith("/swagger")
|
||||||
|| path.startsWith("/v3/api-docs") || path.startsWith("/static/");
|
|| path.startsWith("/v3/api-docs") || path.startsWith("/static/") || path.equals("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -51,13 +47,14 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
.orElse(UUID.randomUUID().toString());
|
.orElse(UUID.randomUUID().toString());
|
||||||
resp.setHeader("X-Correlation-Id", correlationId);
|
resp.setHeader("X-Correlation-Id", correlationId);
|
||||||
|
|
||||||
|
logIncomingRequest(req, correlationId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
chain.doFilter(req, resp);
|
chain.doFilter(req, resp);
|
||||||
} finally {
|
} finally {
|
||||||
long tookMs = (System.nanoTime() - startNs) / 1_000_000;
|
long tookMs = (System.nanoTime() - startNs) / 1_000_000;
|
||||||
|
|
||||||
String requestBody = readBody(req.getContentAsByteArray(), req.getCharacterEncoding());
|
Map<String, String> reqParams = paramsMap(req);
|
||||||
String responseBody = readBody(resp.getContentAsByteArray(), resp.getCharacterEncoding());
|
|
||||||
|
|
||||||
Map<String, String> reqHeaders = headersMap(req);
|
Map<String, String> reqHeaders = headersMap(req);
|
||||||
Map<String, String> respHeaders = headersMap(resp);
|
Map<String, String> respHeaders = headersMap(resp);
|
||||||
|
|
@ -66,40 +63,64 @@ public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
mask(respHeaders);
|
mask(respHeaders);
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
"HTTP {} {}{} | status={} | took={}ms | cid={} | reqHeaders={} | reqBody={} | respHeaders={} | respBody={}",
|
"HTTP (RESPONSE) {} {} | status={} | took={}ms | cid={} | reqHeaders={} | reqParams={} | respHeaders={}",
|
||||||
req.getMethod(),
|
req.getMethod(),
|
||||||
req.getRequestURI(),
|
req.getRequestURI(),
|
||||||
req.getQueryString() == null ? "" : "?" + req.getQueryString(),
|
|
||||||
resp.getStatus(),
|
resp.getStatus(),
|
||||||
tookMs,
|
tookMs,
|
||||||
correlationId,
|
correlationId,
|
||||||
reqHeaders,
|
reqHeaders,
|
||||||
requestBody,
|
reqParams,
|
||||||
respHeaders,
|
respHeaders
|
||||||
responseBody
|
|
||||||
);
|
);
|
||||||
|
|
||||||
resp.copyBodyToResponse();
|
resp.copyBodyToResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ContentCachingRequestWrapper wrapRequest(HttpServletRequest request) {
|
private void logIncomingRequest(ContentCachingRequestWrapper req, String correlationId) {
|
||||||
|
Map<String, String> reqParams = paramsMap(req);
|
||||||
|
Map<String, String> reqHeaders = headersMap(req);
|
||||||
|
mask(reqHeaders);
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"HTTP (REQUEST) {} {} | cid={} | reqHeaders={} | reqParams={}",
|
||||||
|
req.getMethod(),
|
||||||
|
req.getRequestURI(),
|
||||||
|
correlationId,
|
||||||
|
reqHeaders,
|
||||||
|
reqParams
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ContentCachingRequestWrapper wrapRequest(HttpServletRequest request) throws IOException {
|
||||||
return (request instanceof ContentCachingRequestWrapper c) ? c : new ContentCachingRequestWrapper(request, MAX_BODY);
|
return (request instanceof ContentCachingRequestWrapper c) ? c : new ContentCachingRequestWrapper(request, MAX_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String readBody(byte[] buf, String encoding) {
|
|
||||||
if (buf == null || buf.length == 0) return "";
|
|
||||||
var bytes = buf.length > MAX_BODY ? Arrays.copyOf(buf, MAX_BODY) : buf;
|
|
||||||
String body = new String(bytes, encoding != null ? java.nio.charset.Charset.forName(encoding) : StandardCharsets.UTF_8);
|
|
||||||
if (buf.length > MAX_BODY) body += "…[truncated]";
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, String> headersMap(HttpServletRequest req) {
|
private static Map<String, String> headersMap(HttpServletRequest req) {
|
||||||
return Collections.list(req.getHeaderNames()).stream()
|
return Collections.list(req.getHeaderNames()).stream()
|
||||||
.collect(Collectors.toMap(h -> h, req::getHeader, (a, b) -> a, LinkedHashMap::new));
|
.collect(Collectors.toMap(h -> h, req::getHeader, (a, b) -> a, LinkedHashMap::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> paramsMap(HttpServletRequestWrapper req) {
|
||||||
|
Map<String, String> paramsMap = new LinkedHashMap<>();
|
||||||
|
req.getParameterMap().forEach((k, v) -> {
|
||||||
|
String params = String.join(", ", v);
|
||||||
|
paramsMap.put(k, params);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
Collection<Part> fileParts = req.getParts();
|
||||||
|
fileParts.forEach(part -> {
|
||||||
|
paramsMap.put(part.getName(), part.getSubmittedFileName());
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return paramsMap;
|
||||||
|
}
|
||||||
|
|
||||||
private static Map<String, String> headersMap(HttpServletResponse resp) {
|
private static Map<String, String> headersMap(HttpServletResponse resp) {
|
||||||
return resp.getHeaderNames().stream()
|
return resp.getHeaderNames().stream()
|
||||||
.collect(Collectors.toMap(h -> h, resp::getHeader, (a, b) -> a, LinkedHashMap::new));
|
.collect(Collectors.toMap(h -> h, resp::getHeader, (a, b) -> a, LinkedHashMap::new));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
package ru.nbch.credit_tracker.config.rest.filters;
|
||||||
|
|
||||||
|
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
import ru.nbch.credit_tracker.config.rest.wrappers.CachedHttpRequestWrapper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
@Order(1)
|
||||||
|
public class MemberCodeHttpLoggingFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||||
|
String path = request.getRequestURI();
|
||||||
|
return !(path.startsWith("/api/v1/signal/all_packages") || path.startsWith("/api/v1/signal/active_packages"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
CachedHttpRequestWrapper req = wrapRequest(request);
|
||||||
|
String body = IOUtils.toString(req.getBody(), req.getCharacterEncoding());
|
||||||
|
if (StringUtils.isNotBlank(body)) {
|
||||||
|
try {
|
||||||
|
int startIndex = body.indexOf("<UserId>") + 8;
|
||||||
|
int endIndex = body.indexOf("</UserId>");
|
||||||
|
String userId = body.substring(startIndex, endIndex);
|
||||||
|
log.info(
|
||||||
|
"HTTP (REQUEST) {} {} | memberCode={}",
|
||||||
|
req.getMethod(),
|
||||||
|
req.getRequestURI(),
|
||||||
|
userId.substring(0, 6)
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filterChain.doFilter(req, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CachedHttpRequestWrapper wrapRequest(HttpServletRequest request) throws IOException {
|
||||||
|
return new CachedHttpRequestWrapper(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ru.nbch.credit_tracker.config.rest.wrappers;
|
||||||
|
|
||||||
|
import jakarta.servlet.ServletInputStream;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class CachedHttpRequestWrapper extends HttpServletRequestWrapper {
|
||||||
|
private final byte[] body;
|
||||||
|
|
||||||
|
|
||||||
|
public CachedHttpRequestWrapper(HttpServletRequest request) throws IOException {
|
||||||
|
super(request);
|
||||||
|
this.body = request.getInputStream().readAllBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServletInputStream getInputStream() {
|
||||||
|
return new CachedServletInputStream(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package ru.nbch.credit_tracker.config.rest.wrappers;
|
||||||
|
|
||||||
|
import jakarta.servlet.ReadListener;
|
||||||
|
import jakarta.servlet.ServletInputStream;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
public class CachedServletInputStream extends ServletInputStream {
|
||||||
|
|
||||||
|
private final ByteArrayInputStream byteArray;
|
||||||
|
|
||||||
|
public CachedServletInputStream(byte[] data) {
|
||||||
|
this.byteArray = new ByteArrayInputStream(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() {
|
||||||
|
return byteArray.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFinished() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReady() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReadListener(ReadListener listener) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,13 @@ public record DataSourceSettings(
|
||||||
String username,
|
String username,
|
||||||
String password,
|
String password,
|
||||||
String url,
|
String url,
|
||||||
String driver
|
String driver,
|
||||||
|
Integer maximumPoolSize,
|
||||||
|
Integer minimumIdle,
|
||||||
|
long connectionTimeout,
|
||||||
|
long validationTimeout,
|
||||||
|
long idleTimeout,
|
||||||
|
long maxLifetime,
|
||||||
|
long keepaliveTime,
|
||||||
|
long leakDetectionThreshold
|
||||||
) {}
|
) {}
|
||||||
|
|
@ -6,6 +6,8 @@ import org.springframework.context.annotation.Configuration;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.external_response.monitoring_report_file.SgnlReportMonitorigSetupError;
|
import ru.nbch.credit_tracker.entities.external_response.monitoring_report_file.SgnlReportMonitorigSetupError;
|
||||||
import ru.nbch.credit_tracker.entities.external_response.online_report.SgnlOnlineReport;
|
import ru.nbch.credit_tracker.entities.external_response.online_report.SgnlOnlineReport;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_request.all_packages.MonitoringAllPackagesRequest;
|
||||||
import ru.nbch.credit_tracker.entities.user_response.errors.MonitoringError;
|
import ru.nbch.credit_tracker.entities.user_response.errors.MonitoringError;
|
||||||
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringSetupResponse;
|
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringSetupResponse;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||||
|
|
@ -26,6 +28,8 @@ public class XmlConfig {
|
||||||
// unmarshalling classes
|
// unmarshalling classes
|
||||||
SgnlOnlineReport.class,
|
SgnlOnlineReport.class,
|
||||||
SgnlReportMonitorigSetupError.class,
|
SgnlReportMonitorigSetupError.class,
|
||||||
|
MonitoringActivePackagesRequest.class,
|
||||||
|
MonitoringAllPackagesRequest.class,
|
||||||
// marshalling classes
|
// marshalling classes
|
||||||
MonitoringError.class,
|
MonitoringError.class,
|
||||||
MonitoringSetupResponse.class);
|
MonitoringSetupResponse.class);
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ import java.time.LocalDateTime;
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class Hit {
|
public class Hit {
|
||||||
private Integer id;
|
private Long id;
|
||||||
private Integer packageId;
|
private Long packageId;
|
||||||
private String subjectId;
|
private String subjectId;
|
||||||
private Integer signalType;
|
private Integer signalType;
|
||||||
private LocalDateTime responseSentAt;
|
private LocalDateTime responseSentAt;
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import java.time.LocalDateTime;
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
public class PhoneFidMap {
|
public class PhoneFidMap {
|
||||||
private Integer id;
|
private Long id;
|
||||||
private Integer packageId;
|
private Long packageId;
|
||||||
private String subjectId;
|
private String subjectId;
|
||||||
private String phone;
|
private String phone;
|
||||||
private Integer fid;
|
private Integer fid;
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,12 @@ import java.time.LocalDateTime;
|
||||||
@Setter
|
@Setter
|
||||||
@Builder
|
@Builder
|
||||||
public class UserPackage {
|
public class UserPackage {
|
||||||
private Integer id;
|
private Long id;
|
||||||
private String userId;
|
private String userId;
|
||||||
private String packageName;
|
private String packageName;
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
private String status;
|
private String status;
|
||||||
private LocalDateTime deactivatedAt;
|
private LocalDateTime deactivatedAt;
|
||||||
private String lastDownloadedReport;
|
private String lastDownloadedReport;
|
||||||
|
private LocalDateTime monitoringAt;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public class Person {
|
||||||
@XmlValue
|
@XmlValue
|
||||||
protected String value;
|
protected String value;
|
||||||
@XmlAttribute(name = "uid", required = true)
|
@XmlAttribute(name = "uid", required = true)
|
||||||
protected Integer uid;
|
protected Long uid;
|
||||||
@XmlAttribute(name = "oksm", required = true)
|
@XmlAttribute(name = "oksm", required = true)
|
||||||
protected String oksm;
|
protected String oksm;
|
||||||
@XmlAttribute(name = "s", required = true)
|
@XmlAttribute(name = "s", required = true)
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public class MonitoringReportErrors {
|
||||||
public static class P {
|
public static class P {
|
||||||
|
|
||||||
@XmlAttribute(name = "uid")
|
@XmlAttribute(name = "uid")
|
||||||
protected Integer uid;
|
protected Long uid;
|
||||||
|
|
||||||
@XmlValue
|
@XmlValue
|
||||||
protected String value;
|
protected String value;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import java.util.List;
|
||||||
public class Person {
|
public class Person {
|
||||||
|
|
||||||
@XmlAttribute(name = "uid", required = true)
|
@XmlAttribute(name = "uid", required = true)
|
||||||
protected Integer uid;
|
protected Long uid;
|
||||||
|
|
||||||
@XmlElement(name = "Inquiry", required = true)
|
@XmlElement(name = "Inquiry", required = true)
|
||||||
protected List<Inquiry> inquiries;
|
protected List<Inquiry> inquiries;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.user_response.errors;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "MonitoringAllPackagesResponse", propOrder = {
|
||||||
|
"status",
|
||||||
|
"errorCode",
|
||||||
|
"errorText"
|
||||||
|
})
|
||||||
|
@XmlRootElement(name = "MonitoringAllPackagesResponse")
|
||||||
|
public class MonitoringAllPackagesError implements CommonError {
|
||||||
|
|
||||||
|
@XmlElement(name = "Status", required = true)
|
||||||
|
protected String status;
|
||||||
|
@XmlElement(name = "Code",required = true)
|
||||||
|
protected String errorCode;
|
||||||
|
@XmlElement(name = "Message",required = true)
|
||||||
|
protected String errorText;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
public enum XmlErrorFormat {
|
public enum XmlErrorFormat {
|
||||||
MonitoringActivePackagesError,
|
MonitoringActivePackagesError,
|
||||||
|
MonitoringAllPackagesError,
|
||||||
MonitoringDownloadError,
|
MonitoringDownloadError,
|
||||||
MonitoringError,
|
MonitoringError,
|
||||||
MonitoringPackageDeleteError,
|
MonitoringPackageDeleteError,
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
@Getter
|
@Getter
|
||||||
public class SignalClientException extends SignalException {
|
public class SignalClientException extends SignalException {
|
||||||
|
|
||||||
public SignalClientException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat) {
|
private final String packageName;
|
||||||
|
|
||||||
|
public SignalClientException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat, String packageName) {
|
||||||
super(errorMessage, errorFormat);
|
super(errorMessage, errorFormat);
|
||||||
|
this.packageName = packageName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
package ru.nbch.credit_tracker.facade;
|
package ru.nbch.credit_tracker.facade;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.slf4j.MDC;
|
||||||
|
import org.springframework.aop.framework.AopContext;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
import org.springframework.core.io.FileUrlResource;
|
import org.springframework.core.io.FileUrlResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import ru.nbch.credit_tracker.config.mdc.SetAndClearMdc;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
||||||
|
|
@ -31,7 +35,7 @@ import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
import ru.nbch.credit_tracker.utils.ValidationUtil;
|
import ru.nbch.credit_tracker.utils.ValidationService;
|
||||||
import ru.nbch.credit_tracker.utils.ZipUtils;
|
import ru.nbch.credit_tracker.utils.ZipUtils;
|
||||||
|
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
|
@ -43,6 +47,7 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
@ -54,12 +59,17 @@ import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.serverExcp;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||||
public class SignalFacade {
|
public class SignalFacade {
|
||||||
|
|
||||||
|
private SignalFacade self;
|
||||||
|
|
||||||
private final CreditTrackerSettings config;
|
private final CreditTrackerSettings config;
|
||||||
private final AuthorizationService authorizationService;
|
private final AuthorizationService authorizationService;
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
private final MonitoringErrorProcesingService monitoringErrorProcesingService;
|
private final MonitoringErrorProcesingService monitoringErrorProcesingService;
|
||||||
|
private final ValidationService validationService;
|
||||||
private final StaxXmlProcessor staxXmlProcessor;
|
private final StaxXmlProcessor staxXmlProcessor;
|
||||||
|
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
|
@ -71,6 +81,7 @@ public class SignalFacade {
|
||||||
SignalService signalService,
|
SignalService signalService,
|
||||||
SignalRestService signalRestService,
|
SignalRestService signalRestService,
|
||||||
MonitoringErrorProcesingService monitoringErrorProcesingService,
|
MonitoringErrorProcesingService monitoringErrorProcesingService,
|
||||||
|
ValidationService validationService,
|
||||||
StaxXmlProcessor staxXmlProcessor,
|
StaxXmlProcessor staxXmlProcessor,
|
||||||
@Qualifier("executorService") ExecutorService executor) {
|
@Qualifier("executorService") ExecutorService executor) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
@ -78,6 +89,7 @@ public class SignalFacade {
|
||||||
this.signalService = signalService;
|
this.signalService = signalService;
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
this.monitoringErrorProcesingService = monitoringErrorProcesingService;
|
this.monitoringErrorProcesingService = monitoringErrorProcesingService;
|
||||||
|
this.validationService = validationService;
|
||||||
this.staxXmlProcessor = staxXmlProcessor;
|
this.staxXmlProcessor = staxXmlProcessor;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.maxXmlFileSize = config.getMaxXmlFileSize() * 1024 * 1024;
|
this.maxXmlFileSize = config.getMaxXmlFileSize() * 1024 * 1024;
|
||||||
|
|
@ -91,7 +103,7 @@ public class SignalFacade {
|
||||||
|
|
||||||
// Валидация Архива на количетсво файлов, размер и расширение
|
// Валидация Архива на количетсво файлов, размер и расширение
|
||||||
MonitoringRequest monitoringRequest;
|
MonitoringRequest monitoringRequest;
|
||||||
Integer packageId;
|
Long packageId;
|
||||||
ZipInputStream zipInputStream = null;
|
ZipInputStream zipInputStream = null;
|
||||||
String filePath;
|
String filePath;
|
||||||
try {
|
try {
|
||||||
|
|
@ -144,13 +156,13 @@ public class SignalFacade {
|
||||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword());
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword());
|
||||||
if (!authResult.isSuccess()) {
|
if (!authResult.isSuccess()) {
|
||||||
signalService.rejectPackage(monitoringRequest);
|
signalService.rejectPackage(monitoringRequest);
|
||||||
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringError);
|
throw clientExcp(authResult.getError(), monitoringRequest.getPackageName(), XmlErrorFormat.MonitoringError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// проверка на уникальность пакета
|
// проверка на уникальность пакета
|
||||||
if (signalService.isPackageNotUnique(monitoringRequest)) {
|
if (signalService.isPackageNotUnique(monitoringRequest)) {
|
||||||
signalService.rejectPackage(monitoringRequest);
|
signalService.rejectPackage(monitoringRequest);
|
||||||
throw clientExcp(SignalError.ERROR_007, XmlErrorFormat.MonitoringError);
|
throw clientExcp(SignalError.ERROR_007, monitoringRequest.getPackageName(), XmlErrorFormat.MonitoringError);
|
||||||
}
|
}
|
||||||
|
|
||||||
packageId = signalService.registerPackage(monitoringRequest);
|
packageId = signalService.registerPackage(monitoringRequest);
|
||||||
|
|
@ -164,7 +176,7 @@ public class SignalFacade {
|
||||||
}
|
}
|
||||||
|
|
||||||
// в отдельном потоке запускаем регистрацию субъектов, поиск фидов и расчет флагов просрочек
|
// в отдельном потоке запускаем регистрацию субъектов, поиск фидов и расчет флагов просрочек
|
||||||
registerFidsAndDebts(packageId, monitoringRequest.getPackageName(), filePath);
|
getCurrentProxy().registerFidsAndDebts(packageId, monitoringRequest.getPackageName(), filePath);
|
||||||
|
|
||||||
return ResponseEntity.ok().body(new MonitoringSetupResponse());
|
return ResponseEntity.ok().body(new MonitoringSetupResponse());
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +187,7 @@ public class SignalFacade {
|
||||||
monitoringRequest = staxXmlProcessor.read(in, MonitoringRequest.class,
|
monitoringRequest = staxXmlProcessor.read(in, MonitoringRequest.class,
|
||||||
request -> {
|
request -> {
|
||||||
try {
|
try {
|
||||||
ValidationUtil.validateMonitoringRequest(request);
|
validationService.validateMonitoringRequest(request);
|
||||||
} catch (SignalClientException e) {
|
} catch (SignalClientException e) {
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
signalService.rejectPackage(request);
|
signalService.rejectPackage(request);
|
||||||
|
|
@ -211,8 +223,13 @@ public class SignalFacade {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerFidsAndDebts(Integer packageId, String packageName, String filePath) {
|
@SetAndClearMdc(argIndex = 1)
|
||||||
|
public void registerFidsAndDebts(Long packageId, String packageName, String filePath) {
|
||||||
|
Map<String, String> context = MDC.getCopyOfContextMap();
|
||||||
executor.execute(() -> {
|
executor.execute(() -> {
|
||||||
|
if (context != null) {
|
||||||
|
MDC.setContextMap(context);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
signalService.registerSubjects(filePath, packageId);
|
signalService.registerSubjects(filePath, packageId);
|
||||||
CTUtil.removeFile(filePath);
|
CTUtil.removeFile(filePath);
|
||||||
|
|
@ -223,8 +240,9 @@ public class SignalFacade {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (signalRestService.setupMonitoring(packageId)) {
|
if (signalRestService.setupMonitoring(packageId)) {
|
||||||
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
LocalDateTime monitoringAt = LocalDateTime.now();
|
||||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}, MonitoringAt: {}", packageId, packageName, monitoringAt);
|
||||||
|
signalService.updatePackageOnMonitoringSuccess(packageId, monitoringAt);
|
||||||
monitoringErrorProcesingService.findErrors(packageId);
|
monitoringErrorProcesingService.findErrors(packageId);
|
||||||
} else {
|
} else {
|
||||||
log.info("Package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
log.info("Package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||||
|
|
@ -280,7 +298,7 @@ public class SignalFacade {
|
||||||
try {
|
try {
|
||||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(allPackagesRequest.getUserId(), allPackagesRequest.getPassword());
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(allPackagesRequest.getUserId(), allPackagesRequest.getPassword());
|
||||||
if (!authResult.isSuccess()) {
|
if (!authResult.isSuccess()) {
|
||||||
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringActivePackagesError);
|
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringAllPackagesError);
|
||||||
}
|
}
|
||||||
List<UserPackage> activePackages = signalService.findAllPackages(allPackagesRequest.getUserId());
|
List<UserPackage> activePackages = signalService.findAllPackages(allPackagesRequest.getUserId());
|
||||||
|
|
||||||
|
|
@ -302,13 +320,13 @@ public class SignalFacade {
|
||||||
response.setPackages(packages);
|
response.setPackages(packages);
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
} else {
|
} else {
|
||||||
throw clientExcp(SignalError.ERROR_019, XmlErrorFormat.MonitoringActivePackagesError);
|
throw clientExcp(SignalError.ERROR_019, XmlErrorFormat.MonitoringAllPackagesError);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalClientException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalClientException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringActivePackagesError, e);
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringAllPackagesError, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -408,4 +426,11 @@ public class SignalFacade {
|
||||||
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringDownloadError, e);
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringDownloadError, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SignalFacade getCurrentProxy() {
|
||||||
|
if (self == null) {
|
||||||
|
self = (SignalFacade) AopContext.currentProxy();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@ import java.util.List;
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface FlagsMapper {
|
public interface FlagsMapper {
|
||||||
|
|
||||||
List<FlagsService.RuPastDuarearData> findRuPastDuarearData(@Param("fids") List<Integer> fids);
|
List<FlagsService.FlagFidData> findFlagsDebt5000(@Param("fids") List<Integer> fids);
|
||||||
|
|
||||||
List<FlagsService.RuPaymtData> findRuPaymtData(@Param("fids") List<Integer> fids, @Param("reportedDate") LocalDate reportedDate);
|
List<FlagsService.FlagFidData> findFlag90ByPastDueArrear(@Param("fids") List<Integer> fids, @Param("reportedDate") LocalDate reportedDate);
|
||||||
|
|
||||||
|
List<FlagsService.FlagFidData> findFlag90ByRuPaymt(@Param("fids") List<Integer> fids, @Param("reportedDate") LocalDate reportedDate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,16 @@ import java.util.List;
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface PhoneFidMapMapper {
|
public interface PhoneFidMapMapper {
|
||||||
|
|
||||||
void registerSubjects(@Param("subjects") List<Subject> subjects, @Param("packageId") Integer packageId);
|
void registerSubjects(@Param("subjects") List<Subject> subjects, @Param("packageId") Long packageId);
|
||||||
|
|
||||||
List<PhoneFidMap> findFullPhoneFidMap(@Param("packageId") Integer packageId, @Param("offset") int offset, @Param("limit") int limit);
|
List<PhoneFidMap> findFullPhoneFidMap(@Param("packageId") Long packageId, @Param("offset") int offset, @Param("limit") int limit);
|
||||||
|
|
||||||
void updatePhoneFidMaps(@Param("subjects") List<PhoneFidMap> subjects);
|
void updatePhoneFidMaps(@Param("subjects") List<PhoneFidMap> subjects);
|
||||||
|
|
||||||
void updatePhoneFidMapsErrors(@Param("subjects") List<PhoneFidMap> subjects);
|
void updatePhoneFidMapsErrors(@Param("subjects") List<PhoneFidMap> subjects);
|
||||||
|
|
||||||
PhoneFidMap findPhoneFidMapById(@Param("id") Integer packageId);
|
PhoneFidMap findPhoneFidMapById(@Param("id") Long packageId);
|
||||||
|
|
||||||
boolean hasNonNullFids(@Param("packageId") Integer packageId);
|
boolean hasNonNullFids(@Param("packageId") Long packageId);
|
||||||
|
boolean hasOldRow(@Param("packageId") Long packageId, @Param("daysCount") Integer daysCount);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,15 @@ public interface UserPackageMapper {
|
||||||
|
|
||||||
void deletePackage(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String newStatus, @Param("previousStatus") String previousStatus, @Param("deactivatedAt") LocalDateTime deactivatedAt);
|
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);
|
Long insertPackage(@Param("userPackage") UserPackage userPackage);
|
||||||
|
|
||||||
void updatePackageStatus(@Param("packageId") Integer packageId, @Param("status") String status);
|
void updatePackageStatus(@Param("packageId") Long packageId, @Param("status") String status);
|
||||||
|
|
||||||
void updatePackageLastDownloadedReport(@Param("id") Integer id, @Param("fileName") String fileName);
|
void updatePackageLastDownloadedReport(@Param("id") Long id, @Param("fileName") String fileName);
|
||||||
|
|
||||||
UserPackage findPackage(@Param("id") Integer id);
|
void updatePackageOnMonitoringSuccess(@Param("id") Long id, @Param("monitoringAt") LocalDateTime monitoringAt);
|
||||||
|
|
||||||
|
UserPackage findPackage(@Param("id") Long id);
|
||||||
|
|
||||||
List<UserPackage> findUserPackages(@Param("userId") String userId, @Param("statuses") List<String> status);
|
List<UserPackage> findUserPackages(@Param("userId") String userId, @Param("statuses") List<String> status);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,21 @@ package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.aop.framework.AopContext;
|
||||||
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.nbch.credit_tracker.config.mdc.SetAndClearMdc;
|
||||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||||
public class MonitoringErrorProcesingService {
|
public class MonitoringErrorProcesingService {
|
||||||
|
|
||||||
|
private MonitoringErrorProcesingService self;
|
||||||
|
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
|
|
||||||
|
|
@ -19,8 +25,13 @@ public class MonitoringErrorProcesingService {
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void findErrors(Integer packageId) {
|
public void findErrors(Long packageId) {
|
||||||
UserPackage userPackage = signalService.findPackage(packageId);
|
UserPackage userPackage = signalService.findPackage(packageId);
|
||||||
|
getCurrentProxy().processPackage(userPackage, packageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SetAndClearMdc
|
||||||
|
public void processPackage(UserPackage userPackage, Long packageId) {
|
||||||
if (userPackage != null) {
|
if (userPackage != null) {
|
||||||
String packCode = userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName();
|
String packCode = userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName();
|
||||||
log.info("Проверка на ошибки при постановке на мониторинг. packCode={}, packageId={}", packCode, packageId);
|
log.info("Проверка на ошибки при постановке на мониторинг. packCode={}, packageId={}", packCode, packageId);
|
||||||
|
|
@ -38,4 +49,11 @@ public class MonitoringErrorProcesingService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MonitoringErrorProcesingService getCurrentProxy() {
|
||||||
|
if (self == null) {
|
||||||
|
self = (MonitoringErrorProcesingService) AopContext.currentProxy();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.MDC;
|
||||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
|
|
@ -69,16 +70,24 @@ public class MonitoringService {
|
||||||
log.info("Start monitoring");
|
log.info("Start monitoring");
|
||||||
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||||
for (UserPackage userPackage : packages) {
|
for (UserPackage userPackage : packages) {
|
||||||
log.info("Processing package {}", userPackage.getPackageName());
|
MDC.put("ru.nbch.credit_tracker.log.mdc.key", "[" + userPackage.getPackageName() +"]");
|
||||||
|
processPackage(userPackage);
|
||||||
|
MDC.remove("ru.nbch.credit_tracker.log.mdc.key");
|
||||||
|
}
|
||||||
|
log.info("Finish monitoring");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processPackage(UserPackage userPackage) {
|
||||||
|
log.info("Processing package");
|
||||||
if (!signalService.hasNonNullfids(userPackage.getId())) {
|
if (!signalService.hasNonNullfids(userPackage.getId())) {
|
||||||
log.info("Package {} has no fids. Package will be skipped.", userPackage.getPackageName());
|
log.info("Package has no fids. Package will be skipped.");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
SgnlOnlineReport onlineReports = signalRestService.getReports(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName());
|
SgnlOnlineReport onlineReports = signalRestService.getReports(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName());
|
||||||
|
|
||||||
if (onlineReports == null) {
|
if (onlineReports == null) {
|
||||||
log.info("No reports found for package {}", userPackage.getPackageName());
|
log.info("No reports found for package");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Формируем список имен файлов, по которым сработали сигналы. Сюда входят только те имена, у которых парсится дата формирования отчета
|
// Формируем список имен файлов, по которым сработали сигналы. Сюда входят только те имена, у которых парсится дата формирования отчета
|
||||||
|
|
@ -86,8 +95,8 @@ public class MonitoringService {
|
||||||
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList();
|
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList();
|
||||||
|
|
||||||
if (fileNames.isEmpty()) {
|
if (fileNames.isEmpty()) {
|
||||||
log.info("No new report found for package {}", userPackage.getPackageName());
|
log.info("No new report found for package");
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(userPackage.getLastDownloadedReport());
|
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(userPackage.getLastDownloadedReport());
|
||||||
|
|
@ -105,7 +114,7 @@ public class MonitoringService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(userPackage.getLastDownloadedReport())) {
|
if (StringUtils.isNotBlank(userPackage.getLastDownloadedReport())) {
|
||||||
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", userPackage.getPackageName(), userPackage.getLastDownloadedReport());
|
log.info("Last downloaded report found for package. Last Downloaded Report Name: {}", userPackage.getLastDownloadedReport());
|
||||||
} else {
|
} else {
|
||||||
log.info("Last Downloaded Report Name is empty");
|
log.info("Last Downloaded Report Name is empty");
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +131,7 @@ public class MonitoringService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loadedReportPath == null) {
|
if (loadedReportPath == null) {
|
||||||
log.info("Report was not loaded for package {}", userPackage.getPackageName());
|
log.info("Report was not loaded for package");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,15 +145,13 @@ public class MonitoringService {
|
||||||
updateSignalHits(userPackage, responsePath, fileName);
|
updateSignalHits(userPackage, responsePath, fileName);
|
||||||
signalService.updateLastDownloadedReport(userPackage.getId(), newReport);
|
signalService.updateLastDownloadedReport(userPackage.getId(), newReport);
|
||||||
} else {
|
} else {
|
||||||
log.info("Report was not created for package {}", userPackage.getPackageName());
|
log.info("Report was not created for package");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage(), e);
|
log.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.info("Finish monitoring");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Формирует результирующий xml файл для конечного пользователя на основе файла из официального сервиса сигналов
|
* Формирует результирующий xml файл для конечного пользователя на основе файла из официального сервиса сигналов
|
||||||
|
|
@ -297,7 +304,7 @@ public class MonitoringService {
|
||||||
10000,
|
10000,
|
||||||
"/MonitoringSignalResponse/Subjects/Subject");
|
"/MonitoringSignalResponse/Subjects/Subject");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Error while and updating hits", e);
|
throw new RuntimeException("Error while updating hits", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTUtil.removeFile(responsePath); // удалям результирующий xml файл с диска (Он уже заархивирован к этому моменту)
|
CTUtil.removeFile(responsePath); // удалям результирующий xml файл с диска (Он уже заархивирован к этому моменту)
|
||||||
|
|
@ -305,7 +312,7 @@ public class MonitoringService {
|
||||||
log.info("Signal hits updated for package {}", userPackage.getPackageName());
|
log.info("Signal hits updated for package {}", userPackage.getPackageName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String loadReport(Integer packageId, String reportName) {
|
public String loadReport(Long packageId, String reportName) {
|
||||||
return signalRestService.downloadReport(packageId, reportName);
|
return signalRestService.downloadReport(packageId, reportName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,8 @@ import ru.nbch.credit_tracker.entities.external_response.monitoring_report_error
|
||||||
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService2;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.PersonService;
|
import ru.nbch.credit_tracker.service.indic.PersonService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService2;
|
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||||
import ru.nbch.credit_tracker.service.signal.HitsService;
|
import ru.nbch.credit_tracker.service.signal.HitsService;
|
||||||
import ru.nbch.credit_tracker.service.signal.PhoneFidMapService;
|
import ru.nbch.credit_tracker.service.signal.PhoneFidMapService;
|
||||||
import ru.nbch.credit_tracker.service.signal.UserPackageService;
|
import ru.nbch.credit_tracker.service.signal.UserPackageService;
|
||||||
|
|
@ -44,8 +43,8 @@ public class SignalService {
|
||||||
private final HitsService hitsService;
|
private final HitsService hitsService;
|
||||||
private final UserPackageService userPackageService;
|
private final UserPackageService userPackageService;
|
||||||
private final PhoneFidMapService phoneFidMapService;
|
private final PhoneFidMapService phoneFidMapService;
|
||||||
private final PhoneService2 phoneService;
|
private final PhoneService phoneService;
|
||||||
private final FlagsService2 flagsService;
|
private final FlagsService flagsService;
|
||||||
private final PersonService personService;
|
private final PersonService personService;
|
||||||
private final StaxXmlProcessor staxXmlProcessor;
|
private final StaxXmlProcessor staxXmlProcessor;
|
||||||
|
|
||||||
|
|
@ -55,8 +54,8 @@ public class SignalService {
|
||||||
HitsService hitsService,
|
HitsService hitsService,
|
||||||
UserPackageService userPackageService,
|
UserPackageService userPackageService,
|
||||||
PhoneFidMapService phoneFidMapService,
|
PhoneFidMapService phoneFidMapService,
|
||||||
PhoneService2 phoneService,
|
PhoneService phoneService,
|
||||||
FlagsService2 flagsService,
|
FlagsService flagsService,
|
||||||
PersonService personService,
|
PersonService personService,
|
||||||
StaxXmlProcessor staxXmlProcessor) {
|
StaxXmlProcessor staxXmlProcessor) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
@ -73,7 +72,7 @@ public class SignalService {
|
||||||
return userPackageService.isPackageNotUnique(request.getUserId(), request.getPackageName());
|
return userPackageService.isPackageNotUnique(request.getUserId(), request.getPackageName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer registerPackage(MonitoringRequest request) {
|
public Long registerPackage(MonitoringRequest request) {
|
||||||
UserPackage userPackage = UserPackage.builder()
|
UserPackage userPackage = UserPackage.builder()
|
||||||
.userId(request.getUserId())
|
.userId(request.getUserId())
|
||||||
.packageName(request.getPackageName())
|
.packageName(request.getPackageName())
|
||||||
|
|
@ -83,7 +82,7 @@ public class SignalService {
|
||||||
return userPackageService.insertPackage(userPackage);
|
return userPackageService.insertPackage(userPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerSubjects(String filePath, Integer packageId) {
|
public void registerSubjects(String filePath, Long packageId) {
|
||||||
log.info("Start registering subjects. PackageId: {}", packageId);
|
log.info("Start registering subjects. PackageId: {}", packageId);
|
||||||
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(filePath)), 8 * 1024 * 1024)) {
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(filePath)), 8 * 1024 * 1024)) {
|
||||||
staxXmlProcessor.read(in, MonitoringRequest.class,
|
staxXmlProcessor.read(in, MonitoringRequest.class,
|
||||||
|
|
@ -106,12 +105,11 @@ public class SignalService {
|
||||||
/**
|
/**
|
||||||
* Обрабатывает все PhoneFidMap по packageId, выгружая их пачками и фильтруя по переданному фильтру
|
* Обрабатывает все PhoneFidMap по packageId, выгружая их пачками и фильтруя по переданному фильтру
|
||||||
*/
|
*/
|
||||||
public UpdateResult updateSubjects(Integer packageId, Predicate<PhoneFidMap> filter) {
|
public UpdateResult updateSubjects(Long packageId, Predicate<PhoneFidMap> filter) {
|
||||||
boolean updated = false;
|
boolean updated = false;
|
||||||
boolean noFidsFound = true;
|
boolean noFidsFound = true;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
List<PhoneFidMap> batch;
|
List<PhoneFidMap> batch;
|
||||||
Map<Integer, PhoneFidMap> phonesByFidToProcessing = new HashMap<>();
|
|
||||||
do {
|
do {
|
||||||
batch = phoneFidMapService.findFullPhoneFidMap(packageId, offset, batchSize);
|
batch = phoneFidMapService.findFullPhoneFidMap(packageId, offset, batchSize);
|
||||||
|
|
||||||
|
|
@ -127,30 +125,15 @@ public class SignalService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filteredItems.isEmpty()) {
|
if (!filteredItems.isEmpty()) {
|
||||||
Map<Integer, PhoneFidMap> fidsMapByBatch = phoneService.defineFidByPhone(filteredItems);
|
boolean fidsFound = updateFlags(filteredItems, packageId);
|
||||||
log.debug("Actual fids size by phone's batch: {}", fidsMapByBatch.size());
|
|
||||||
|
|
||||||
if (fidsMapByBatch.size() + phonesByFidToProcessing.size() <= batchSize) {
|
|
||||||
phonesByFidToProcessing.putAll(fidsMapByBatch);
|
|
||||||
} else {
|
|
||||||
boolean fidsFound = updateFlags(phonesByFidToProcessing, packageId);
|
|
||||||
if (noFidsFound) {
|
if (noFidsFound) {
|
||||||
noFidsFound = !fidsFound;
|
noFidsFound = !fidsFound;
|
||||||
}
|
}
|
||||||
phonesByFidToProcessing = new HashMap<>(fidsMapByBatch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += batchSize;
|
offset += batchSize;
|
||||||
} while (!batch.isEmpty());
|
} while (!batch.isEmpty());
|
||||||
|
|
||||||
if (!phonesByFidToProcessing.isEmpty()) {
|
|
||||||
boolean fidsFound = updateFlags(phonesByFidToProcessing, packageId);
|
|
||||||
if (noFidsFound) {
|
|
||||||
noFidsFound = !fidsFound;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UpdateResult(updated, noFidsFound);
|
return new UpdateResult(updated, noFidsFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,37 +141,50 @@ public class SignalService {
|
||||||
* Обрабатывает пачку PhoneFidMap: обновляет фиды и флаги просрочек
|
* Обрабатывает пачку PhoneFidMap: обновляет фиды и флаги просрочек
|
||||||
* @return fidsFound true - если хотя бы по одному номеру был найден фид, false - в противном случае
|
* @return fidsFound true - если хотя бы по одному номеру был найден фид, false - в противном случае
|
||||||
*/
|
*/
|
||||||
// TODO Добавить отдельный метод. Если не нашелся фид, надо обновить в базе fid = null и флаги = null calculated_at=now()
|
public boolean updateFlags(List<PhoneFidMap> subjects, Long packageId) {
|
||||||
public boolean updateFlags(Map<Integer, PhoneFidMap> fidsMap, Integer packageId) {
|
log.info("Start calculating fids and flags for subjects batch. PackageId: {}", packageId);
|
||||||
log.info("Start calculating flags for subjects batch. PackageId: {}", packageId);
|
Map<String, Integer> fidsMap = phoneService.findFidsPhoneData(subjects);
|
||||||
Map<Integer, FlagsService.FlagsData> flagsDataMap = flagsService.findFlags(fidsMap.keySet().stream().toList());
|
LocalDateTime calculatedAt = LocalDateTime.now();
|
||||||
|
boolean fidsFound = fidsMap.values().stream().anyMatch(Objects::nonNull);
|
||||||
|
Map<Integer, FlagsService.FlagsData> flagsDataMap = flagsService.findFlags(fidsMap.values().stream().filter(Objects::nonNull).toList());
|
||||||
List<PhoneFidMap> subjectToUpdate = new ArrayList<>();
|
List<PhoneFidMap> subjectToUpdate = new ArrayList<>();
|
||||||
for (Map.Entry<Integer, FlagsService.FlagsData> entry : flagsDataMap.entrySet()) {
|
|
||||||
Integer fid = entry.getKey();
|
|
||||||
FlagsService.FlagsData flagsData = entry.getValue();
|
|
||||||
PhoneFidMap phoneFidMap = fidsMap.get(fid);
|
|
||||||
|
|
||||||
phoneFidMap.setFid(fid);
|
subjects.forEach(subject -> {
|
||||||
phoneFidMap.setFlagDebt5000(flagsData.getFlagDebt5000());
|
Integer fid = fidsMap.get("9" + subject.getPhone());
|
||||||
phoneFidMap.setFlag90days(flagsData.getFlag90days());
|
if (fid != null) {
|
||||||
phoneFidMap.setCalculatedAt(LocalDateTime.now());
|
FlagsService.FlagsData flagsData = flagsDataMap.get(fid);
|
||||||
|
subject = PhoneFidMap.builder()
|
||||||
subjectToUpdate.add(phoneFidMap);
|
.id(subject.getId())
|
||||||
|
.packageId(packageId)
|
||||||
|
.subjectId(subject.getSubjectId())
|
||||||
|
.phone(subject.getPhone())
|
||||||
|
.fid(fid)
|
||||||
|
.flagDebt5000(flagsData.getFlagDebt5000())
|
||||||
|
.flag90days(flagsData.getFlag90days())
|
||||||
|
.calculatedAt(calculatedAt)
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
|
subject = PhoneFidMap.builder()
|
||||||
|
.id(subject.getId())
|
||||||
|
.packageId(packageId)
|
||||||
|
.subjectId(subject.getSubjectId())
|
||||||
|
.phone(subject.getPhone())
|
||||||
|
.calculatedAt(calculatedAt)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
subjectToUpdate.add(subject);
|
||||||
|
});
|
||||||
|
|
||||||
log.debug("Start updating subject's batch");
|
int updateBatchSize = batchSize / 9; // 9 параметров на одну запись для обновления. Максимальное количество параметров ~65000
|
||||||
if (!subjectToUpdate.isEmpty()) {
|
|
||||||
int updateBatchSize = 7000; // 9 параметров на одну запись для обновления. Максимальное количество параметров ~65000
|
|
||||||
for (int j = 0; j < subjectToUpdate.size(); j += updateBatchSize) {
|
for (int j = 0; j < subjectToUpdate.size(); j += updateBatchSize) {
|
||||||
int endIndex = Math.min(j + updateBatchSize, subjectToUpdate.size());
|
int endIndex = Math.min(j + updateBatchSize, subjectToUpdate.size());
|
||||||
phoneFidMapService.updatePhoneFidMaps(subjectToUpdate.subList(j, endIndex));
|
phoneFidMapService.updatePhoneFidMaps(subjectToUpdate.subList(j, endIndex));
|
||||||
log.trace("Updated fids and flags for subject's batch from: {} to: {}. Total count: {}. PackageId: {}", j, endIndex, subjectToUpdate.size(), packageId);
|
log.trace("Updated fids and flags for subject's batch from: {} to: {}. Total count: {}. PackageId: {}", j, endIndex, subjectToUpdate.size(), packageId);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
log.debug("Complete updating subject's batch");
|
|
||||||
|
|
||||||
log.info("Finish calculating flags for subjects. PackageId: {}. Batch size: {}", packageId, fidsMap.size());
|
log.info("Finish calculating fids and flags for subjects. PackageId: {}. Batch size: {}", packageId, subjects.size());
|
||||||
return !fidsMap.isEmpty();
|
|
||||||
|
return fidsFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rejectPackage(MonitoringRequest request) {
|
public void rejectPackage(MonitoringRequest request) {
|
||||||
|
|
@ -201,16 +197,20 @@ public class SignalService {
|
||||||
userPackageService.insertPackage(userPackage);
|
userPackageService.insertPackage(userPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePackageStatus(Integer packageId, Status status) {
|
public void updatePackageStatus(Long packageId, Status status) {
|
||||||
userPackageService.updatePackageStatus(packageId, status);
|
userPackageService.updatePackageStatus(packageId, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updatePackageOnMonitoringSuccess(Long packageId, LocalDateTime monitoringAt) {
|
||||||
|
userPackageService.updatePackageOnMonitoringSuccess(packageId, monitoringAt);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Формирует файл запроса в официальный сервис сигналов, выгружая паспортные данные пачками и сразу записывая их в файл
|
* Формирует файл запроса в официальный сервис сигналов, выгружая паспортные данные пачками и сразу записывая их в файл
|
||||||
*
|
*
|
||||||
* @return Путь к файлу запроса к официальному сервису сигналов на постановку на мониторинг
|
* @return Путь к файлу запроса к официальному сервису сигналов на постановку на мониторинг
|
||||||
*/
|
*/
|
||||||
public String writeSignals(Integer packageId) {
|
public String writeSignals(Long packageId) {
|
||||||
String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator;
|
String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator;
|
||||||
String filePath = folderPath + UUID.randomUUID() + "_output.xml";
|
String filePath = folderPath + UUID.randomUUID() + "_output.xml";
|
||||||
CTUtil.createFolder(folderPath);
|
CTUtil.createFolder(folderPath);
|
||||||
|
|
@ -226,7 +226,7 @@ public class SignalService {
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Signals buildSignals(Integer packageId) {
|
private Signals buildSignals(Long packageId) {
|
||||||
UserPackage userPackage = userPackageService.findPackage(packageId);
|
UserPackage userPackage = userPackageService.findPackage(packageId);
|
||||||
Signals signals = new Signals();
|
Signals signals = new Signals();
|
||||||
signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы)
|
signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы)
|
||||||
|
|
@ -242,7 +242,7 @@ public class SignalService {
|
||||||
* Обрабатывает все PhoneFidMap по packageId, выгружая их пачками и фильтруя по переданному фильтру.
|
* Обрабатывает все PhoneFidMap по packageId, выгружая их пачками и фильтруя по переданному фильтру.
|
||||||
* writer записывает пачку сразу в файл
|
* writer записывает пачку сразу в файл
|
||||||
*/
|
*/
|
||||||
private void buildPersons(Integer packageId, Consumer<List<Person>> writer) {
|
private void buildPersons(Long packageId, Consumer<List<Person>> writer) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
List<PhoneFidMap> batch;
|
List<PhoneFidMap> batch;
|
||||||
do {
|
do {
|
||||||
|
|
@ -282,14 +282,14 @@ public class SignalService {
|
||||||
return persons;
|
return persons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateSubjectsErrors(String filePath, Integer packageId) {
|
public void updateSubjectsErrors(String filePath, Long packageId) {
|
||||||
log.info("Start updating subjects errors. PackageId: {}", packageId);
|
log.info("Start updating subjects errors. PackageId: {}", packageId);
|
||||||
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(filePath)), 8 * 1024 * 1024)) {
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(filePath)), 8 * 1024 * 1024)) {
|
||||||
staxXmlProcessor.read(in, MonitoringReportErrors.class,
|
staxXmlProcessor.read(in, MonitoringReportErrors.class,
|
||||||
request -> {
|
request -> {
|
||||||
if (!request.getPersons().isEmpty()) {
|
if (!request.getPersons().isEmpty()) {
|
||||||
List<PhoneFidMap> subjects = request.getPersons().stream().map(p -> {
|
List<PhoneFidMap> subjects = request.getPersons().stream().map(p -> {
|
||||||
log.error("Ошибка при формировании субъекта. package_id = {}, id = {}. Описание: {}", packageId, p.getUid(), p.getValue());
|
log.warn("Ошибка при формировании субъекта. package_id = {}, id = {}. Описание: {}", packageId, p.getUid(), p.getValue());
|
||||||
return PhoneFidMap.builder()
|
return PhoneFidMap.builder()
|
||||||
.id(p.getUid())
|
.id(p.getUid())
|
||||||
.errorText(p.getValue())
|
.errorText(p.getValue())
|
||||||
|
|
@ -341,19 +341,19 @@ public class SignalService {
|
||||||
hitsService.insertHits(hits);
|
hitsService.insertHits(hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLastDownloadedReport(Integer id, String fileName) {
|
public void updateLastDownloadedReport(Long id, String fileName) {
|
||||||
userPackageService.updatePackageLastDownloadedReport(id, fileName);
|
userPackageService.updatePackageLastDownloadedReport(id, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhoneFidMap findPhoneFidMapById(Integer id) {
|
public PhoneFidMap findPhoneFidMapById(Long id) {
|
||||||
return phoneFidMapService.findPhoneFidMapById(id);
|
return phoneFidMapService.findPhoneFidMapById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNonNullfids(Integer packageId) {
|
public boolean hasNonNullfids(Long packageId) {
|
||||||
return phoneFidMapService.hasNonNullfids(packageId);
|
return phoneFidMapService.hasNonNullfids(packageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserPackage findPackage(Integer packageId) {
|
public UserPackage findPackage(Long packageId) {
|
||||||
return userPackageService.findPackage(packageId);
|
return userPackageService.findPackage(packageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.aop.framework.AopContext;
|
||||||
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.nbch.credit_tracker.config.mdc.SetAndClearMdc;
|
||||||
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
|
|
@ -14,8 +17,11 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||||
public class UpdateProcessingPackagesService {
|
public class UpdateProcessingPackagesService {
|
||||||
|
|
||||||
|
private UpdateProcessingPackagesService self;
|
||||||
|
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
private final MonitoringErrorProcesingService monitoringErrorProcesingService;
|
private final MonitoringErrorProcesingService monitoringErrorProcesingService;
|
||||||
|
|
@ -33,25 +39,26 @@ public class UpdateProcessingPackagesService {
|
||||||
List<UserPackage> packages = signalService.findPackagesOnProcessing();
|
List<UserPackage> packages = signalService.findPackagesOnProcessing();
|
||||||
for (UserPackage userPackage : packages) {
|
for (UserPackage userPackage : packages) {
|
||||||
log.info("Updating flags for Package {}", userPackage.getPackageName());
|
log.info("Updating flags for Package {}", userPackage.getPackageName());
|
||||||
process(userPackage.getId(), userPackage.getPackageName());
|
getCurrentProxy().process(userPackage.getId(), userPackage.getPackageName());
|
||||||
}
|
}
|
||||||
log.info("Finish updating processing packages");
|
log.info("Finish updating processing packages");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process(Integer packageId, String packageName) {
|
@SetAndClearMdc(argIndex = 1)
|
||||||
|
public void process(Long packageId, String packageName) {
|
||||||
try {
|
try {
|
||||||
SignalService.UpdateResult updateResult = signalService.updateSubjects(packageId, null);
|
SignalService.UpdateResult updateResult = signalService.updateSubjects(packageId, null);
|
||||||
if (updateResult.isNoFidsFound()) {
|
if (updateResult.isNoFidsFound()) {
|
||||||
log.info("No fids found for PackageId: {} PackageName: {}. Package status ON_MONITORING. No registration in signal service.", packageId, packageName);
|
log.info("No fids found for PackageId: {} . Package status ON_MONITORING. No registration in signal service.", packageId);
|
||||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (signalRestService.setupMonitoring(packageId)) {
|
if (signalRestService.setupMonitoring(packageId)) {
|
||||||
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
log.info("Package was successfully registered in signal service. PackageId: {}", packageId);
|
||||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||||
monitoringErrorProcesingService.findErrors(packageId);
|
monitoringErrorProcesingService.findErrors(packageId);
|
||||||
} else {
|
} else {
|
||||||
log.info("Package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
log.info("Package registration was rejected by signal service. PackageId: {}", packageId);
|
||||||
signalService.updatePackageStatus(packageId, Status.ERROR);
|
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
@ -59,4 +66,11 @@ public class UpdateProcessingPackagesService {
|
||||||
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UpdateProcessingPackagesService getCurrentProxy() {
|
||||||
|
if (self == null) {
|
||||||
|
self = (UpdateProcessingPackagesService) AopContext.currentProxy();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,18 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
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
|
||||||
|
|
@ -29,43 +26,56 @@ 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() +"]");
|
||||||
updateFlags(userPackage.getId(), 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);
|
||||||
|
}
|
||||||
|
MDC.remove("ru.nbch.credit_tracker.log.mdc.key");
|
||||||
}
|
}
|
||||||
log.info("Finish updating flags");
|
log.info("Finish updating flags");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFlags(Integer packageId, String packageName) {
|
private void updateFlags(UserPackage userPackage) {
|
||||||
|
Long packageId = userPackage.getId();
|
||||||
|
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)) {
|
||||||
log.info("Flags were updated successfully. PackageId: {} PackageName: {}. Package status changed to ON_MONITORING", packageId, packageName);
|
LocalDateTime monitoringAt = userPackage.getMonitoringAt() != null ? userPackage.getMonitoringAt() : LocalDateTime.now();
|
||||||
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
log.info("Flags were updated successfully. PackageId: {} PackageName: {} MonitoringAt: {}. Package status changed to ON_MONITORING", packageId, packageName, monitoringAt);
|
||||||
|
signalService.updatePackageOnMonitoringSuccess(packageId, monitoringAt);
|
||||||
monitoringErrorProcesingService.findErrors(packageId);
|
monitoringErrorProcesingService.findErrors(packageId);
|
||||||
} else {
|
} else {
|
||||||
log.info("Updated package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
log.info("Updated package registration was rejected by signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,19 @@ package ru.nbch.credit_tracker.service.indic;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.mapper.indic.FlagsMapper;
|
import ru.nbch.credit_tracker.mapper.indic.FlagsMapper;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class FlagsService {
|
public class FlagsService {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(FlagsService.class);
|
|
||||||
private final FlagsMapper mapper;
|
private final FlagsMapper mapper;
|
||||||
|
|
||||||
public FlagsService(FlagsMapper mapper) {
|
public FlagsService(FlagsMapper mapper) {
|
||||||
|
|
@ -28,19 +25,11 @@ public class FlagsService {
|
||||||
if (fids.isEmpty()) {
|
if (fids.isEmpty()) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
List<Integer> distinctFids = fids.stream()
|
|
||||||
.distinct()
|
|
||||||
.sorted(Comparator.naturalOrder())
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
log.debug("Fids count: {}", distinctFids.size());
|
|
||||||
Map<Integer, Integer> flags5000 = new HashMap<>();
|
|
||||||
Map<Integer, Integer> flags90DaysByPastDueArrear = new HashMap<>();
|
|
||||||
Map<Integer, Integer> flags90DaysByRuPaymt = new HashMap<>();
|
|
||||||
findFlagsRuPastDueArrear(distinctFids, flags5000, flags90DaysByPastDueArrear);
|
|
||||||
findFlagsRuPaymt(distinctFids, flags90DaysByRuPaymt);
|
|
||||||
|
|
||||||
Map<Integer, FlagsData> result = new HashMap<>();
|
Map<Integer, FlagsData> result = new HashMap<>();
|
||||||
|
Map<Integer, Integer> flags5000 = calcFlag5000(fids);
|
||||||
|
Map<Integer, Integer> flags90DaysByPastDueArrear = calcFlag90DaysByPastDueArrear(fids);
|
||||||
|
Map<Integer, Integer> flags90DaysByRuPaymt = calcFlag90DaysByRuPaymt(fids);
|
||||||
|
|
||||||
fids.forEach(fid -> {
|
fids.forEach(fid -> {
|
||||||
Integer flagDebt5000 = flags5000.get(fid);
|
Integer flagDebt5000 = flags5000.get(fid);
|
||||||
if (flagDebt5000 == null) {
|
if (flagDebt5000 == null) {
|
||||||
|
|
@ -48,7 +37,7 @@ public class FlagsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer flag90days = flags90DaysByPastDueArrear.get(fid);
|
Integer flag90days = flags90DaysByPastDueArrear.get(fid);
|
||||||
if (flag90days == null || flag90days == 0) {
|
if (flag90days == null) {
|
||||||
flag90days = flags90DaysByRuPaymt.get(fid);
|
flag90days = flags90DaysByRuPaymt.get(fid);
|
||||||
if (flag90days == null) {
|
if (flag90days == null) {
|
||||||
flag90days = 0;
|
flag90days = 0;
|
||||||
|
|
@ -61,118 +50,51 @@ public class FlagsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Выбирает данные из RU_PASTDUEARREAR и ищет по ним флаги просрочек
|
|
||||||
* По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT.
|
* По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT.
|
||||||
* Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то flag500 устанавливается в 1.
|
* Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то флаг устанавливается в 1.
|
||||||
* Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0.
|
* Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0.
|
||||||
*
|
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PASTDUEARREAR у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag5000Map - рещультирующая мапа флагов просрочек debt5000
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
*/
|
||||||
private void findFlagsRuPastDueArrear(List<Integer> fids, Map<Integer, Integer> flag5000Map, Map<Integer, Integer> flag90Days) {
|
private Map<Integer, Integer> calcFlag5000(List<Integer> fids) {
|
||||||
log.debug("Start calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
return mapper.findFlagsDebt5000(fids).stream()
|
||||||
List<RuPastDuarearData> ruPastDuarearDataList = mapper.findRuPastDuarearData(fids);
|
.collect(Collectors.toMap(FlagFidData::getFid, FlagFidData::getFlag,
|
||||||
|
(existing, replacement) -> {
|
||||||
ruPastDuarearDataList.sort(Comparator.comparing(FlagsService.RuPastDuarearData::getFid) // сортируем сначала по фиду
|
if (existing == 1) {
|
||||||
.thenComparing(FlagsService.RuPastDuarearData::getReportedDate, Comparator.reverseOrder())); // Затем сортируем по REPORTED_DT по убыванию
|
return existing;
|
||||||
|
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
|
||||||
|
|
||||||
for (Integer fid : fids) {
|
|
||||||
Iterator<RuPastDuarearData> iterator = ruPastDuarearDataList.iterator();
|
|
||||||
BigInteger prevAccSerialNum = null;
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
FlagsService.RuPastDuarearData data = iterator.next();
|
|
||||||
if (fid.equals(data.getFid())) {
|
|
||||||
if (flag5000Map.get(fid) == null) { // Первая запись в списке с макс REPORTED_DT. Нас интересует только она для флага 5000
|
|
||||||
if (prevAccSerialNum == null || !prevAccSerialNum.equals(data.getAccSerialNum())) {
|
|
||||||
if (data.getAmtPastDue() != null && data.getAmtPastDue().compareTo(BigDecimal.valueOf(5000)) >= 0) {
|
|
||||||
flag5000Map.put(fid, 1);
|
|
||||||
}
|
|
||||||
prevAccSerialNum = data.getAccSerialNum();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Integer flag90 = flag90Days.get(fid);
|
|
||||||
if (flag90 != null && flag90 == 1) {
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag90 == null || flag90 == 0) {
|
|
||||||
if (data.getDaysPastDue() != null) {
|
|
||||||
boolean has90daysFlag = data.getDaysPastDue().compareTo(BigInteger.valueOf(90)) >= 0 && !data.getReportedDate().isBefore(yearAgo);
|
|
||||||
if (has90daysFlag) {
|
|
||||||
flag90Days.put(fid, 1);
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
flag90Days.put(fid, 0);
|
return replacement;
|
||||||
iterator.remove();
|
|
||||||
}
|
}
|
||||||
} else {
|
}));
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// если мы так и не нашли флаги для этих фидов - выставляем их в 0
|
|
||||||
flag5000Map.putIfAbsent(fid, 0);
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
log.debug("Complete calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Выбирает данные из RU_PAYMT и ищет по ним флаги просрочек 90Days
|
* Флаг = 1, если выполняется хотя бы одно из условий:
|
||||||
*
|
* В INDIC.RU_PASTDUEARREAR или RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
*/
|
||||||
private void findFlagsRuPaymt(List<Integer> fids, Map<Integer, Integer> flag90Days) {
|
private Map<Integer, Integer> calcFlag90DaysByPastDueArrear(List<Integer> fids) {
|
||||||
log.debug("Start calculating flag 90 days by RU_PAPAYMT");
|
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
||||||
List<RuPaymtData> ruPaymtDataList = mapper.findRuPaymtData(fids, yearAgo);
|
return mapper.findFlag90ByPastDueArrear(fids, yearAgo).stream()
|
||||||
ruPaymtDataList.sort(Comparator.comparing(RuPaymtData::getFid, Comparator.naturalOrder()));
|
.collect(Collectors.toMap(FlagFidData::getFid, FlagFidData::getFlag,
|
||||||
|
(existing, replacement) -> {
|
||||||
for (Integer fid : fids) {
|
if (existing == 1) {
|
||||||
Iterator<RuPaymtData> iterator = ruPaymtDataList.iterator();
|
return existing;
|
||||||
while (iterator.hasNext()) {
|
} else {
|
||||||
RuPaymtData data = iterator.next();
|
return replacement;
|
||||||
if (fid.equals(data.getFid())) {
|
}
|
||||||
Integer flag90 = flag90Days.get(fid);
|
}));
|
||||||
if (flag90 != null && flag90 == 1) {
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag90 == null || flag90 == 0) {
|
private Map<Integer, Integer> calcFlag90DaysByRuPaymt(List<Integer> fids) {
|
||||||
if (data.getDaysPastDue() != null) {
|
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
||||||
boolean has90daysFlag = data.getDaysPastDue().compareTo(BigInteger.valueOf(90)) >= 0 && !data.getReportedDate().isBefore(yearAgo);
|
return mapper.findFlag90ByRuPaymt(fids, yearAgo).stream()
|
||||||
if (has90daysFlag) {
|
.collect(Collectors.toMap(FlagFidData::getFid, FlagFidData::getFlag,
|
||||||
flag90Days.put(fid, 1);
|
(existing, replacement) -> {
|
||||||
iterator.remove();
|
if (existing == 1) {
|
||||||
break;
|
return existing;
|
||||||
} else {
|
} else {
|
||||||
flag90Days.put(fid, 0);
|
return replacement;
|
||||||
iterator.remove();
|
|
||||||
}
|
}
|
||||||
} else {
|
}));
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
log.debug("Complete calculating flag 90 days by RU_PAPAYMT");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|
@ -185,23 +107,8 @@ public class FlagsService {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
public static class FlagFidData {
|
||||||
@NoArgsConstructor
|
|
||||||
public static class RuPastDuarearData {
|
|
||||||
private Integer fid;
|
private Integer fid;
|
||||||
private BigInteger accSerialNum;
|
private Integer flag;
|
||||||
private LocalDate reportedDate;
|
|
||||||
private BigDecimal amtPastDue;
|
|
||||||
private BigInteger daysPastDue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public static class RuPaymtData {
|
|
||||||
private Integer fid;
|
|
||||||
private BigInteger daysPastDue;
|
|
||||||
private LocalDate reportedDate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,256 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service.indic;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class FlagsService2 {
|
|
||||||
|
|
||||||
private static final String SELECT_RU_PASDUEARREAR_DATA =
|
|
||||||
"SELECT FID, ACC_SERIAL_NUM, REPORTED_DT, AMT_PAST_DUE, DAYS_PAST_DUE " +
|
|
||||||
"FROM RU_PASTDUEARREAR " +
|
|
||||||
"WHERE FID IN (:fids) " +
|
|
||||||
"ORDER BY FID, REPORTED_DT DESC " +
|
|
||||||
"WITH UR";
|
|
||||||
|
|
||||||
private static final String SELECT_RU_PAYMT_DATA =
|
|
||||||
"SELECT FID, DAYS_PAST_DUE, REPORTED_DT " +
|
|
||||||
"FROM RU_PAYMT " +
|
|
||||||
"WHERE FID IN (:fids) " +
|
|
||||||
"AND REPORTED_DT >= :reportedDate " +
|
|
||||||
"WITH UR";
|
|
||||||
|
|
||||||
private final NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
public FlagsService2(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) {
|
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, FlagsService.FlagsData> findFlags(List<Integer> fids) {
|
|
||||||
if (fids.isEmpty()) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
List<Integer> distinctFids = fids.stream()
|
|
||||||
.distinct()
|
|
||||||
.sorted(Comparator.naturalOrder())
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
log.debug("Fids count: {}", distinctFids.size());
|
|
||||||
Map<Integer, Integer> flags5000 = new HashMap<>();
|
|
||||||
Map<Integer, Integer> flags90DaysByPastDueArrear = new HashMap<>();
|
|
||||||
Map<Integer, Integer> flags90DaysByRuPaymt = new HashMap<>();
|
|
||||||
findFlagsRuPastDueArrear(distinctFids, flags5000, flags90DaysByPastDueArrear);
|
|
||||||
findFlagsRuPaymt(distinctFids, flags90DaysByRuPaymt);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> result = new HashMap<>();
|
|
||||||
fids.forEach(fid -> {
|
|
||||||
Integer flagDebt5000 = flags5000.get(fid);
|
|
||||||
if (flagDebt5000 == null) {
|
|
||||||
flagDebt5000 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Integer flag90days = flags90DaysByPastDueArrear.get(fid);
|
|
||||||
if (flag90days == null || flag90days == 0) {
|
|
||||||
flag90days = flags90DaysByRuPaymt.get(fid);
|
|
||||||
if (flag90days == null) {
|
|
||||||
flag90days = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.put(fid, new FlagsService.FlagsData(flagDebt5000, flag90days));
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Выбирает данные из RU_PASTDUEARREAR и ищет по ним флаги просрочек
|
|
||||||
* По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT.
|
|
||||||
* Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то flag500 устанавливается в 1.
|
|
||||||
* Если ни по одному счёту условие не выполняется или счетов вообще не найдено, флаг = 0.
|
|
||||||
* <p>
|
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PASTDUEARREAR у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
|
||||||
*
|
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag5000Map - рещультирующая мапа флагов просрочек debt5000
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
|
||||||
private void findFlagsRuPastDueArrear(List<Integer> fids, Map<Integer, Integer> flag5000Map, Map<Integer, Integer> flag90Days) {
|
|
||||||
log.debug("Start calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
|
||||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
|
||||||
params.addValue("fids", fids);
|
|
||||||
|
|
||||||
jdbcTemplate.query(SELECT_RU_PASDUEARREAR_DATA, params, (ResultSet rs) -> {
|
|
||||||
Integer currentFid = null;
|
|
||||||
BigInteger prevAccSerialNum = null;
|
|
||||||
boolean processed5000ForCurrentId = false;
|
|
||||||
boolean processed90DaysForCurrentId = false;
|
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
Integer fid = rs.getInt("FID");
|
|
||||||
|
|
||||||
// Переход к новому fid. Сброс состояния
|
|
||||||
if (!fid.equals(currentFid)) {
|
|
||||||
currentFid = fid;
|
|
||||||
prevAccSerialNum = null;
|
|
||||||
processed5000ForCurrentId = false;
|
|
||||||
processed90DaysForCurrentId = false;
|
|
||||||
|
|
||||||
// Инициализируем значения по умолчанию
|
|
||||||
flag5000Map.putIfAbsent(fid, 0);
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Если для текущего FID уже обработали оба флага, пропускаем остальные записи
|
|
||||||
if (processed5000ForCurrentId && processed90DaysForCurrentId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка флага 5000
|
|
||||||
if (!processed5000ForCurrentId && flag5000Map.get(fid) == 0) {
|
|
||||||
BigInteger currentAccSerialNum = getBigInteger(rs, "ACC_SERIAL_NUM");
|
|
||||||
BigDecimal amtPastDue = getBigDecimal(rs, "AMT_PAST_DUE");
|
|
||||||
|
|
||||||
if (prevAccSerialNum == null || !prevAccSerialNum.equals(currentAccSerialNum)) {
|
|
||||||
if (amtPastDue != null && amtPastDue.compareTo(BigDecimal.valueOf(5000)) >= 0) {
|
|
||||||
flag5000Map.put(fid, 1);
|
|
||||||
processed5000ForCurrentId = true;
|
|
||||||
}
|
|
||||||
prevAccSerialNum = currentAccSerialNum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка флага 90 дней
|
|
||||||
if (!processed90DaysForCurrentId) {
|
|
||||||
Integer currentFlag90 = flag90Days.get(fid);
|
|
||||||
|
|
||||||
if (currentFlag90 != null && currentFlag90 == 1) {
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFlag90 == null || currentFlag90 == 0) {
|
|
||||||
BigInteger days = getBigInteger(rs, "DAYS_PAST_DUE");
|
|
||||||
LocalDate reportedDate = rs.getObject("REPORTED_DT", LocalDate.class);
|
|
||||||
|
|
||||||
if (days != null) {
|
|
||||||
boolean has90daysFlag = days.compareTo(BigInteger.valueOf(90)) >= 0
|
|
||||||
&& reportedDate != null && !reportedDate.isBefore(yearAgo);
|
|
||||||
|
|
||||||
if (has90daysFlag) {
|
|
||||||
flag90Days.put(fid, 1);
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
log.debug("Complete calculating flag 5000 and 90 days by RU_PASTDUEARREAR");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Выбирает данные из RU_PAYMT и ищет по ним флаги просрочек 90Days
|
|
||||||
* <p>
|
|
||||||
* flag90Days = 1, если выполняется хотя бы одно из условий:
|
|
||||||
* В INDIC.RU_PAYMT у данного FID есть запись с DAYS_PAST_DUE ≥ 90 и REPORTED_DT >= текущая дата – 12 месяцев.
|
|
||||||
* Если ни по одной записи условия не выполняются или записей вообще не найдено, флаг = 0.
|
|
||||||
*
|
|
||||||
* @param fids - отсортирован по возрастанию фидов
|
|
||||||
* @param flag90Days - рещультирующая мапа флагов просрочек 90_days
|
|
||||||
*/
|
|
||||||
private void findFlagsRuPaymt(List<Integer> fids, Map<Integer, Integer> flag90Days) {
|
|
||||||
log.debug("Start calculating flag 90 days by RU_PAPAYMT");
|
|
||||||
LocalDate yearAgo = LocalDate.now().minusYears(1);
|
|
||||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
|
||||||
params.addValue("fids", fids);
|
|
||||||
params.addValue("reportedDate", yearAgo);
|
|
||||||
jdbcTemplate.query(SELECT_RU_PAYMT_DATA, params, rs -> {
|
|
||||||
Integer currentFid = null;
|
|
||||||
boolean processed90DaysForCurrentId = false;
|
|
||||||
|
|
||||||
while (rs.next()) {
|
|
||||||
Integer fid = rs.getInt("FID");
|
|
||||||
|
|
||||||
// Переход к новому fid. Сброс состояния
|
|
||||||
if (!fid.equals(currentFid)) {
|
|
||||||
currentFid = fid;
|
|
||||||
processed90DaysForCurrentId = false;
|
|
||||||
|
|
||||||
// Инициализируем значения по умолчанию
|
|
||||||
flag90Days.putIfAbsent(fid, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработка флага 90 дней
|
|
||||||
if (!processed90DaysForCurrentId) {
|
|
||||||
Integer currentFlag90 = flag90Days.get(fid);
|
|
||||||
|
|
||||||
if (currentFlag90 != null && currentFlag90 == 1) {
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFlag90 == null || currentFlag90 == 0) {
|
|
||||||
BigInteger days = getBigInteger(rs, "DAYS_PAST_DUE");
|
|
||||||
LocalDate date = rs.getObject("REPORTED_DT", LocalDate.class);
|
|
||||||
|
|
||||||
if (days != null) {
|
|
||||||
boolean has90daysFlag = days.compareTo(BigInteger.valueOf(90)) >= 0
|
|
||||||
&& date != null && !date.isBefore(yearAgo);
|
|
||||||
|
|
||||||
if (has90daysFlag) {
|
|
||||||
flag90Days.put(fid, 1);
|
|
||||||
processed90DaysForCurrentId = true;
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
flag90Days.put(fid, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
log.debug("Complete calculating flag 90 days by RU_PAPAYMT");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private BigInteger getBigInteger(ResultSet rs, String columnName) {
|
|
||||||
try {
|
|
||||||
String value = rs.getString(columnName);
|
|
||||||
return value != null ? new BigInteger(value) : null;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BigDecimal getBigDecimal(ResultSet rs, String columnName) {
|
|
||||||
try {
|
|
||||||
return rs.getBigDecimal(columnName);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
package ru.nbch.credit_tracker.service.indic;
|
package ru.nbch.credit_tracker.service.indic;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
@Service
|
||||||
public class PhoneService {
|
public class PhoneService {
|
||||||
|
|
||||||
|
|
@ -24,45 +24,32 @@ public class PhoneService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ищет фиды по номерам телефона
|
* Ищет фиды по номерам телефона
|
||||||
* @return Map: key - fid; value - {@link PhoneFidMap}
|
* @return Map: key - номер телефона; value - fid
|
||||||
*/
|
*/
|
||||||
public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) {
|
public Map<String, Integer> findFidsPhoneData(List<PhoneFidMap> subjects) {
|
||||||
Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();
|
List<String> phones = subjects.stream().map(subject -> "9" + subject.getPhone()).toList();
|
||||||
List<String> phones = subjects.stream().
|
return convertFidsDataToMap(mapper.findFids(phones));
|
||||||
map(subject -> "9" + subject.getPhone())
|
}
|
||||||
.toList();
|
|
||||||
|
|
||||||
subjects.sort(
|
private Map<String, Integer> convertFidsDataToMap(List<FidsData> fidsData) {
|
||||||
Comparator.comparing(
|
if (fidsData == null || fidsData.isEmpty()) {
|
||||||
PhoneFidMap::getPhone,
|
return new HashMap<>();
|
||||||
Comparator.naturalOrder()
|
}
|
||||||
|
return fidsData.stream()
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
FidsData::getPhone,
|
||||||
|
Collectors.collectingAndThen(
|
||||||
|
Collectors.maxBy(
|
||||||
|
Comparator.comparing(FidsData::getFileSinceDate)
|
||||||
|
.thenComparing(FidsData::getFid)
|
||||||
|
),
|
||||||
|
data -> data.map(FidsData::getFid).orElse(null)
|
||||||
)
|
)
|
||||||
);
|
));
|
||||||
|
|
||||||
//отсортированный список по NUMBER, FID и FILE_SINCE_DT
|
|
||||||
List<FidsData> phonesByFid = mapper.findFids(phones);
|
|
||||||
log.debug("Start merging fids");
|
|
||||||
for (PhoneFidMap phoneFid : subjects) {
|
|
||||||
Iterator<FidsData> iterator = phonesByFid.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
FidsData fidsData = iterator.next();
|
|
||||||
if (fidsData.getPhone().equals(9 + phoneFid.getPhone())) {
|
|
||||||
//fixme доступ по ссылке, страшно, придумать что-то еще
|
|
||||||
phoneFidMap.put(fidsData.getFid(), phoneFid);
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.debug("End merging fids");
|
|
||||||
|
|
||||||
return phoneFidMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public static class FidsData {
|
public static class FidsData {
|
||||||
private Integer fid;
|
private Integer fid;
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service.indic;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class PhoneService2 {
|
|
||||||
|
|
||||||
private static final String SELCT_FIDS = """
|
|
||||||
SELECT
|
|
||||||
pn.number,
|
|
||||||
pn.fid,
|
|
||||||
pn.file_since_dt
|
|
||||||
FROM PHONE_NORM pn
|
|
||||||
JOIN (SELECT DISTINCT fid FROM NAME) nf
|
|
||||||
ON nf.fid = pn.fid
|
|
||||||
WHERE number in (:phones)
|
|
||||||
ORDER BY
|
|
||||||
pn.number ASC,
|
|
||||||
pn.file_since_dt DESC,
|
|
||||||
pn.fid DESC
|
|
||||||
WITH UR
|
|
||||||
""";
|
|
||||||
|
|
||||||
private final NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
public PhoneService2(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) {
|
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ищет фиды по номерам телефона
|
|
||||||
*
|
|
||||||
* @return Map: key - fid; value - {@link PhoneFidMap}
|
|
||||||
*/
|
|
||||||
public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) {
|
|
||||||
Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();
|
|
||||||
|
|
||||||
List<String> phones = subjects.stream().
|
|
||||||
map(subject -> "9" + subject.getPhone())
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
subjects.sort(
|
|
||||||
Comparator.comparing(
|
|
||||||
PhoneFidMap::getPhone,
|
|
||||||
Comparator.naturalOrder()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
MapSqlParameterSource params = new MapSqlParameterSource();
|
|
||||||
params.addValue("phones", phones);
|
|
||||||
|
|
||||||
List<FidsData> phonesByFid = jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) ->
|
|
||||||
new FidsData(rs.getInt("fid"), rs.getString("number"), rs.getObject("file_since_dt", LocalDate.class))
|
|
||||||
);
|
|
||||||
|
|
||||||
log.debug("Start merging fids");
|
|
||||||
for (PhoneFidMap phoneFid : subjects) {
|
|
||||||
Iterator<FidsData> iterator = phonesByFid.iterator();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
FidsData fidsData = iterator.next();
|
|
||||||
if (fidsData.getPhone().equals(9 + phoneFid.getPhone())) {
|
|
||||||
//fixme доступ по ссылке, страшно, придумать что-то еще
|
|
||||||
phoneFidMap.put(fidsData.getFid(), phoneFid);
|
|
||||||
iterator.remove();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.debug("End merging fids");
|
|
||||||
|
|
||||||
return phoneFidMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
public static class FidsData {
|
|
||||||
private Integer fid;
|
|
||||||
private String phone;
|
|
||||||
private LocalDate fileSinceDate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -16,11 +16,11 @@ public class PhoneFidMapService {
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerSubjects(List<Subject> subjects, Integer packageId) {
|
public void registerSubjects(List<Subject> subjects, Long packageId) {
|
||||||
mapper.registerSubjects(subjects, packageId);
|
mapper.registerSubjects(subjects, packageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PhoneFidMap> findFullPhoneFidMap(Integer packageId, int offset, int limit) {
|
public List<PhoneFidMap> findFullPhoneFidMap(Long packageId, int offset, int limit) {
|
||||||
return mapper.findFullPhoneFidMap(packageId, offset, limit);
|
return mapper.findFullPhoneFidMap(packageId, offset, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,11 +32,11 @@ public class PhoneFidMapService {
|
||||||
mapper.updatePhoneFidMapsErrors(subjects);
|
mapper.updatePhoneFidMapsErrors(subjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhoneFidMap findPhoneFidMapById(Integer id) {
|
public PhoneFidMap findPhoneFidMapById(Long id) {
|
||||||
return mapper.findPhoneFidMapById(id);
|
return mapper.findPhoneFidMapById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNonNullfids(Integer packageId) {
|
public boolean hasNonNullfids(Long packageId) {
|
||||||
return mapper.hasNonNullFids(packageId);
|
return mapper.hasNonNullFids(packageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ public class SignalRestService {
|
||||||
* Ставит пакет на мониторинг в официальный сервис сигналов
|
* Ставит пакет на мониторинг в официальный сервис сигналов
|
||||||
* @return true - если пакет успешно поставился на мониторинг. false - в противном случае
|
* @return true - если пакет успешно поставился на мониторинг. false - в противном случае
|
||||||
*/
|
*/
|
||||||
public boolean setupMonitoring(Integer packageId) throws Exception {
|
public boolean setupMonitoring(Long packageId) throws Exception {
|
||||||
String path = signalService.writeSignals(packageId);
|
String path = signalService.writeSignals(packageId);
|
||||||
Resource request = compressFile(path);
|
Resource request = compressFile(path);
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ public class SignalRestService {
|
||||||
/**
|
/**
|
||||||
* @return имя файла с ошибками по поставленному на мониторинг отчету
|
* @return имя файла с ошибками по поставленному на мониторинг отчету
|
||||||
*/
|
*/
|
||||||
public String getErrorFileName(Integer packageId, String packCode) {
|
public String getErrorFileName(Long packageId, String packCode) {
|
||||||
String url = GET_REPORT_URI + "?packCode=" + packCode;
|
String url = GET_REPORT_URI + "?packCode=" + packCode;
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|
@ -131,7 +131,7 @@ public class SignalRestService {
|
||||||
SgnlReportMonitorigSetupError report = xmlProcessor.read(answer, SgnlReportMonitorigSetupError.class);
|
SgnlReportMonitorigSetupError report = xmlProcessor.read(answer, SgnlReportMonitorigSetupError.class);
|
||||||
if (report.getOperationReport().getErrorsForNextReport() != null) {
|
if (report.getOperationReport().getErrorsForNextReport() != null) {
|
||||||
String fileName = report.getOperationReport().getErrorsForNextReport().getFilename();
|
String fileName = report.getOperationReport().getErrorsForNextReport().getFilename();
|
||||||
log.error("Найдены ошибки по пакету. packCode={}, packageId={}, fileName = {}", packCode, packageId, fileName);
|
log.warn("Найдены ошибки по пакету. packCode={}, packageId={}, fileName = {}", packCode, packageId, fileName);
|
||||||
return fileName;
|
return fileName;
|
||||||
} else {
|
} else {
|
||||||
log.info("Пакет был поставлен на мониторинг без ошибок. packCode={}, packageId={}", packCode, packageId);
|
log.info("Пакет был поставлен на мониторинг без ошибок. packCode={}, packageId={}", packCode, packageId);
|
||||||
|
|
@ -148,7 +148,7 @@ public class SignalRestService {
|
||||||
*
|
*
|
||||||
* @return путь к разархивированному файлу. Пример: <loadDir>/tmp_folder/<package_id>/0001XX_MY_BATCH_223112.1.errors.xml.gz
|
* @return путь к разархивированному файлу. Пример: <loadDir>/tmp_folder/<package_id>/0001XX_MY_BATCH_223112.1.errors.xml.gz
|
||||||
*/
|
*/
|
||||||
public String loadErrorFile(Integer packageId, String fileName) {
|
public String loadErrorFile(Long packageId, String fileName) {
|
||||||
String url = DOWNLOAD_REPORT_URI + "?fNameRequest=" + fileName;
|
String url = DOWNLOAD_REPORT_URI + "?fNameRequest=" + fileName;
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|
@ -229,7 +229,7 @@ public class SignalRestService {
|
||||||
*
|
*
|
||||||
* @return путь к разархивированному файлу. Пример: <loadDir>/tmp_folder/<package_id>/0001XX_MY_BATCH_204.1.online.2025-07-08T20-00-46.xml.gz.xml
|
* @return путь к разархивированному файлу. Пример: <loadDir>/tmp_folder/<package_id>/0001XX_MY_BATCH_204.1.online.2025-07-08T20-00-46.xml.gz.xml
|
||||||
*/
|
*/
|
||||||
public String downloadReport(Integer packageId, String reportName) {
|
public String downloadReport(Long packageId, String reportName) {
|
||||||
String url = DOWNLOAD_ONLINE_REPORT_URI + "?fNameReport=" + reportName;
|
String url = DOWNLOAD_ONLINE_REPORT_URI + "?fNameReport=" + reportName;
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|
@ -247,7 +247,7 @@ public class SignalRestService {
|
||||||
return unzipReport(response,packageId, reportName);
|
return unzipReport(response,packageId, reportName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String unzipReport(ResponseEntity<byte[]> response, Integer packageId, String reportName) {
|
private String unzipReport(ResponseEntity<byte[]> response, Long packageId, String reportName) {
|
||||||
boolean isGzipped = response.getHeaders().getContentType() != null
|
boolean isGzipped = response.getHeaders().getContentType() != null
|
||||||
&& response.getHeaders().getContentType().toString().equals("application/x-gzip");
|
&& response.getHeaders().getContentType().toString().equals("application/x-gzip");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,19 +34,23 @@ public class UserPackageService {
|
||||||
mapper.deletePackage(userId.substring(0, 6), packageName, newStatus.name(), previousStatus.name(), deactivatedAt);
|
mapper.deletePackage(userId.substring(0, 6), packageName, newStatus.name(), previousStatus.name(), deactivatedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer insertPackage(UserPackage userPackage) {
|
public Long insertPackage(UserPackage userPackage) {
|
||||||
return mapper.insertPackage(userPackage);
|
return mapper.insertPackage(userPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePackageStatus(Integer packageId, Status status) {
|
public void updatePackageStatus(Long packageId, Status status) {
|
||||||
mapper.updatePackageStatus(packageId, status.name());
|
mapper.updatePackageStatus(packageId, status.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updatePackageLastDownloadedReport(Integer id, String fileName) {
|
public void updatePackageLastDownloadedReport(Long id, String fileName) {
|
||||||
mapper.updatePackageLastDownloadedReport(id, fileName);
|
mapper.updatePackageLastDownloadedReport(id, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserPackage findPackage(Integer id) {
|
public void updatePackageOnMonitoringSuccess(Long id, LocalDateTime monitoringAt) {
|
||||||
|
mapper.updatePackageOnMonitoringSuccess(id, monitoringAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserPackage findPackage(Long id) {
|
||||||
return mapper.findPackage(id);
|
return mapper.findPackage(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public class MonitoringReportErrorsStaxtReader extends BaseStaxReader<Monitoring
|
||||||
switch (reader.getAttributeLocalName(i)) {
|
switch (reader.getAttributeLocalName(i)) {
|
||||||
case "uid" -> {
|
case "uid" -> {
|
||||||
try {
|
try {
|
||||||
int uid = Integer.parseInt(text);
|
Long uid = Long.parseLong(text);
|
||||||
obj.getCurrentPerson().setUid(uid);
|
obj.getCurrentPerson().setUid(uid);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
log.error("Couldn't parse uid: {}", text);
|
log.error("Couldn't parse uid: {}", text);
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public class OnlineDownloadReportPersonsStaxReader extends BaseStaxReader<Person
|
||||||
switch (reader.getAttributeLocalName(i)) {
|
switch (reader.getAttributeLocalName(i)) {
|
||||||
case "uid" -> {
|
case "uid" -> {
|
||||||
try {
|
try {
|
||||||
int uid = Integer.parseInt(text);
|
Long uid = Long.parseLong(text);
|
||||||
obj.getCurrentPerson().setUid(uid);
|
obj.getCurrentPerson().setUid(uid);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
log.error("Couldn't parse uid: {}", text);
|
log.error("Couldn't parse uid: {}", text);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package ru.nbch.credit_tracker.utils;
|
package ru.nbch.credit_tracker.utils;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.nbch.credit_tracker.config.mdc.SetAndClearMdc;
|
||||||
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.Subject;
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.Subject;
|
||||||
import ru.nbch.credit_tracker.enums.SignalError;
|
import ru.nbch.credit_tracker.enums.SignalError;
|
||||||
|
|
@ -12,13 +14,15 @@ import java.util.regex.Pattern;
|
||||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ValidationUtil {
|
@Service
|
||||||
|
public class ValidationService {
|
||||||
|
|
||||||
private static final String phoneRegex = "^\\d{9}$";
|
private static final String phoneRegex = "^\\d{9}$";
|
||||||
private static final String packageNameRegex = "^[A-Z0-9_]{1,22}$";
|
private static final String packageNameRegex = "^[A-Z0-9_]{1,22}$";
|
||||||
private static final String npIdRegex = "^\\S{1,36}$";
|
private static final String npIdRegex = "^\\S{1,36}$";
|
||||||
|
|
||||||
public static void validateMonitoringRequest(MonitoringRequest request) throws SignalClientException {
|
@SetAndClearMdc
|
||||||
|
public void validateMonitoringRequest(MonitoringRequest request) throws SignalClientException {
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
throw clientExcp(SignalError.ERROR_011, XmlErrorFormat.MonitoringError);
|
throw clientExcp(SignalError.ERROR_011, XmlErrorFormat.MonitoringError);
|
||||||
}
|
}
|
||||||
|
|
@ -27,32 +31,34 @@ public class ValidationUtil {
|
||||||
throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "PackageName");
|
throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "PackageName");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String packageName = request.getPackageName();
|
||||||
|
|
||||||
if (!validatePackageName(request.getPackageName())) {
|
if (!validatePackageName(request.getPackageName())) {
|
||||||
throw clientExcp(SignalError.ERROR_008, XmlErrorFormat.MonitoringError);
|
throw clientExcp(SignalError.ERROR_008, packageName, XmlErrorFormat.MonitoringError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getUserId() == null) {
|
if (request.getUserId() == null) {
|
||||||
throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "UserId");
|
throw clientExcp(SignalError.ERROR_002, packageName, XmlErrorFormat.MonitoringError, "UserId");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getPassword() == null) {
|
if (request.getPassword() == null) {
|
||||||
throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Password");
|
throw clientExcp(SignalError.ERROR_002, packageName, XmlErrorFormat.MonitoringError, "Password");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getSubjects() == null) {
|
if (request.getSubjects() == null) {
|
||||||
throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subjects");
|
throw clientExcp(SignalError.ERROR_002, packageName, XmlErrorFormat.MonitoringError, "Subjects");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.getSubjects().getSubject().isEmpty()) {
|
if (request.getSubjects().getSubject().isEmpty()) {
|
||||||
throw clientExcp(SignalError.ERROR_002, XmlErrorFormat.MonitoringError, "Subject");
|
throw clientExcp(SignalError.ERROR_002, packageName, XmlErrorFormat.MonitoringError, "Subject");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Subject subject : request.getSubjects().getSubject()) {
|
for (Subject subject : request.getSubjects().getSubject()) {
|
||||||
if (!validateNPId(subject.getId())) {
|
if (!validateNPId(subject.getId())) {
|
||||||
throw clientExcp(SignalError.ERROR_010, XmlErrorFormat.MonitoringError, subject.getId());
|
throw clientExcp(SignalError.ERROR_010, packageName, XmlErrorFormat.MonitoringError, subject.getId());
|
||||||
}
|
}
|
||||||
if (!validatePhone(subject.getClientId())) {
|
if (!validatePhone(subject.getClientId())) {
|
||||||
throw clientExcp(SignalError.ERROR_003, XmlErrorFormat.MonitoringError, subject.getId());
|
throw clientExcp(SignalError.ERROR_003, packageName, XmlErrorFormat.MonitoringError, subject.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,7 +9,11 @@ import ru.nbch.credit_tracker.exceptions.SignalServerException;
|
||||||
public class ExceptionUtils {
|
public class ExceptionUtils {
|
||||||
|
|
||||||
public static SignalClientException clientExcp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) {
|
public static SignalClientException clientExcp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Object... args) {
|
||||||
return new SignalClientException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat);
|
return clientExcp(enumKeyCode, null, xmlErrorFormat, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SignalClientException clientExcp(IEnumKeyCode enumKeyCode, String packageName, XmlErrorFormat xmlErrorFormat, Object... args) {
|
||||||
|
return new SignalClientException(new EnumKeyMessage(enumKeyCode, args), xmlErrorFormat, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SignalServerException serverExcp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Exception cause, Object... args) {
|
public static SignalServerException serverExcp(IEnumKeyCode enumKeyCode, XmlErrorFormat xmlErrorFormat, Exception cause, Object... args) {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} %X{ru.nbch.credit_tracker.log.mdc.key} - %msg%n</pattern>
|
||||||
<charset>utf-8</charset>
|
<charset>utf-8</charset>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<maxFileSize>100MB</maxFileSize>
|
<maxFileSize>100MB</maxFileSize>
|
||||||
</triggeringPolicy>
|
</triggeringPolicy>
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} %X{ru.nbch.credit_tracker.log.mdc.key} - %msg%n</pattern>
|
||||||
<charset>utf-8</charset>
|
<charset>utf-8</charset>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
@ -63,12 +63,12 @@
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!--SQL запросы и результаты их выполнения-->
|
<!--SQL запросы и результаты их выполнения-->
|
||||||
<logger name="ru.nbch.credit_tracker.mapper" level="DEBUG" additivity="false">
|
<logger name="ru.nbch.credit_tracker.mapper" level="INFO" additivity="false">
|
||||||
<appender-ref ref="FILE"/>
|
<appender-ref ref="FILE"/>
|
||||||
<appender-ref ref="FILE-JSON"/>
|
<appender-ref ref="FILE-JSON"/>
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
<logger name="ru.nbch.credit_tracker.service" level="TRACE" additivity="false">
|
<logger name="ru.nbch.credit_tracker.service" level="INFO" additivity="false">
|
||||||
<appender-ref ref="FILE"/>
|
<appender-ref ref="FILE"/>
|
||||||
<appender-ref ref="FILE-JSON"/>
|
<appender-ref ref="FILE-JSON"/>
|
||||||
<appender-ref ref="CONSOLE"/>
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
|
|
||||||
|
|
@ -5,39 +5,51 @@
|
||||||
|
|
||||||
<mapper namespace="ru.nbch.credit_tracker.mapper.indic.FlagsMapper">
|
<mapper namespace="ru.nbch.credit_tracker.mapper.indic.FlagsMapper">
|
||||||
|
|
||||||
<resultMap id="RuPastDuarearResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$RuPastDuarearData">
|
<resultMap id="FlagsFidDataResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$FlagFidData">
|
||||||
<result property="fid" column="fid" />
|
<result property="fid" column="fid" />
|
||||||
<result property="accSerialNum" column="ACC_SERIAL_NUM" />
|
<result property="flag" column="flag" />
|
||||||
<result property="reportedDate" column="REPORTED_DT" />
|
|
||||||
<result property="amtPastDue" column="AMT_PAST_DUE" />
|
|
||||||
<result property="daysPastDue" column="DAYS_PAST_DUE" />
|
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap id="RuPaymtResultMap" type="ru.nbch.credit_tracker.service.indic.FlagsService$RuPaymtData">
|
<select id="findFlagsDebt5000" resultMap="FlagsFidDataResultMap">
|
||||||
<result property="fid" column="fid" />
|
SELECT
|
||||||
<result property="daysPastDue" column="DAYS_PAST_DUE" />
|
FID as fid,
|
||||||
<result property="reportedDate" column="REPORTED_DT" />
|
(case when (sum(case when AMT_PAST_DUE > 5000 then 1 else 0 end) = 0) then 0 else 1 end) as flag
|
||||||
</resultMap>
|
FROM
|
||||||
|
(select FID, AMT_PAST_DUE, rank() over (partition by FID, ACC_SERIAL_NUM order by REPORTED_DT desc) rn
|
||||||
<select id="findRuPastDuarearData" resultMap="RuPastDuarearResultMap">
|
|
||||||
SELECT FID, ACC_SERIAL_NUM, REPORTED_DT, AMT_PAST_DUE, 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>
|
||||||
with UR
|
)
|
||||||
|
where rn=1
|
||||||
|
group by FID
|
||||||
|
WITH UR
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="findRuPaymtData" resultMap="RuPaymtResultMap">
|
<select id="findFlag90ByPastDueArrear" resultMap="FlagsFidDataResultMap">
|
||||||
SELECT FID, DAYS_PAST_DUE, REPORTED_DT
|
SELECT
|
||||||
|
FID as fid,
|
||||||
|
(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
|
||||||
|
WHERE FID IN
|
||||||
|
<foreach item="fid" collection="fids" open="(" separator="," close=")">
|
||||||
|
#{fid}
|
||||||
|
</foreach>
|
||||||
|
GROUP BY FID
|
||||||
|
WITH UR
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="findFlag90ByRuPaymt" resultMap="FlagsFidDataResultMap">
|
||||||
|
SELECT
|
||||||
|
FID as fid,
|
||||||
|
(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
|
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>
|
||||||
AND REPORTED_DT >= #{reportedDate}
|
GROUP BY FID
|
||||||
with UR
|
WITH UR
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -12,21 +12,14 @@
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="findFids" resultMap="fidsDataResultMap">
|
<select id="findFids" resultMap="fidsDataResultMap">
|
||||||
SELECT
|
SELECT pn.NUMBER AS number, pn.FID AS fid, pn.FILE_SINCE_DT AS fileSinceDate
|
||||||
pn.number,
|
FROM PHONE_NORM pn
|
||||||
pn.fid,
|
INNER JOIN NAME n ON n.FID = pn.FID
|
||||||
pn.file_since_dt
|
|
||||||
FROM indic.PHONE_NORM pn
|
|
||||||
JOIN (SELECT DISTINCT fid FROM indic.NAME) nf
|
|
||||||
ON nf.fid = pn.fid
|
|
||||||
WHERE number in
|
WHERE number in
|
||||||
<foreach item="phone" collection="phones" open="(" separator="," close=")">
|
<foreach item="phone" collection="phones" open="(" separator="," close=")">
|
||||||
#{phone}
|
#{phone}
|
||||||
</foreach>
|
</foreach>
|
||||||
ORDER BY
|
ORDER BY fileSinceDate DESC, fid DESC
|
||||||
pn.number ASC,
|
|
||||||
pn.file_since_dt DESC,
|
|
||||||
pn.fid DESC
|
|
||||||
WITH UR
|
WITH UR
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -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 < now() - make_interval(days => #{daysCount})
|
||||||
|
)
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
<result property="status" column="status"/>
|
<result property="status" column="status"/>
|
||||||
<result property="deactivatedAt" column="deactivated_at"/>
|
<result property="deactivatedAt" column="deactivated_at"/>
|
||||||
<result property="lastDownloadedReport" column="last_downloaded_report"/>
|
<result property="lastDownloadedReport" column="last_downloaded_report"/>
|
||||||
|
<result property="monitoringAt" column="monitoring_at"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="isPackageNotUnique" resultType="boolean">
|
<select id="isPackageNotUnique" resultType="boolean">
|
||||||
|
|
@ -51,7 +52,7 @@
|
||||||
#{previousStatus}
|
#{previousStatus}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
<select id="insertPackage" resultType="java.lang.Integer"
|
<select id="insertPackage" resultType="java.lang.Long"
|
||||||
parameterType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
parameterType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||||
INSERT INTO signals_user_packages (membercode, package_name, created_at, status)
|
INSERT INTO signals_user_packages (membercode, package_name, created_at, status)
|
||||||
values (#{userPackage.userId}, #{userPackage.packageName}, #{userPackage.createdAt}, #{userPackage.status}) RETURNING id
|
values (#{userPackage.userId}, #{userPackage.packageName}, #{userPackage.createdAt}, #{userPackage.status}) RETURNING id
|
||||||
|
|
@ -69,9 +70,15 @@
|
||||||
WHERE id = #{id}
|
WHERE id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<update id="updatePackageOnMonitoringSuccess">
|
||||||
|
UPDATE signals_user_packages
|
||||||
|
SET monitoring_at = #{monitoringAt}, status = 'ON_MONITORING'
|
||||||
|
WHERE id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
<select id="findPackage" resultMap="packageDataResultMap"
|
<select id="findPackage" resultMap="packageDataResultMap"
|
||||||
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||||
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report
|
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report, monitoring_at
|
||||||
FROM signals_user_packages
|
FROM signals_user_packages
|
||||||
WHERE id = #{id}
|
WHERE id = #{id}
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
|
|
@ -79,7 +86,7 @@
|
||||||
|
|
||||||
<select id="findUserPackages" resultMap="packageDataResultMap"
|
<select id="findUserPackages" resultMap="packageDataResultMap"
|
||||||
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||||
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report
|
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report, monitoring_at
|
||||||
FROM signals_user_packages
|
FROM signals_user_packages
|
||||||
WHERE membercode IS NOT NULL
|
WHERE membercode IS NOT NULL
|
||||||
AND LEFT(membercode, 6) = #{userId}
|
AND LEFT(membercode, 6) = #{userId}
|
||||||
|
|
@ -91,7 +98,7 @@
|
||||||
|
|
||||||
<select id="findAllPackagesByUserId" resultMap="packageDataResultMap"
|
<select id="findAllPackagesByUserId" resultMap="packageDataResultMap"
|
||||||
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||||
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report
|
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report, monitoring_at
|
||||||
FROM signals_user_packages
|
FROM signals_user_packages
|
||||||
WHERE membercode IS NOT NULL
|
WHERE membercode IS NOT NULL
|
||||||
AND LEFT(membercode, 6) = #{userId}
|
AND LEFT(membercode, 6) = #{userId}
|
||||||
|
|
@ -99,7 +106,7 @@
|
||||||
|
|
||||||
<select id="findAllPackagesByStatus" resultMap="packageDataResultMap"
|
<select id="findAllPackagesByStatus" resultMap="packageDataResultMap"
|
||||||
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
resultType="ru.nbch.credit_tracker.entities.dto.UserPackage">
|
||||||
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report
|
SELECT id, membercode, package_name, created_at, status, deactivated_at, last_downloaded_report, monitoring_at
|
||||||
FROM signals_user_packages
|
FROM signals_user_packages
|
||||||
WHERE status = #{status}
|
WHERE status = #{status}
|
||||||
</select>
|
</select>
|
||||||
|
|
|
||||||
2
src/main/resources/sql/v1.10.ddl
Normal file
2
src/main/resources/sql/v1.10.ddl
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
alter table signals_phone_fid_map
|
||||||
|
add error_text text;
|
||||||
2
src/main/resources/sql/v1.18.ddl
Normal file
2
src/main/resources/sql/v1.18.ddl
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
alter table signals_user_packages
|
||||||
|
add "monitoring_at" timestamp;
|
||||||
14
src/main/resources/sql/v1.20.ddl
Normal file
14
src/main/resources/sql/v1.20.ddl
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
alter table signals_user_packages
|
||||||
|
alter column id type bigint using id::bigint;
|
||||||
|
|
||||||
|
alter table signals_phone_fid_map
|
||||||
|
alter column id type bigint using id::bigint;
|
||||||
|
|
||||||
|
alter table signals_phone_fid_map
|
||||||
|
alter column package_id type bigint using package_id::bigint;
|
||||||
|
|
||||||
|
alter table signals_hits
|
||||||
|
alter column id type bigint using id::bigint;
|
||||||
|
|
||||||
|
alter table signals_hits
|
||||||
|
alter column package_id type bigint using package_id::bigint;
|
||||||
3
src/main/resources/sql/v1.22.ddl
Normal file
3
src/main/resources/sql/v1.22.ddl
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
CREATE INDEX IF NOT EXISTS
|
||||||
|
idx_signals_phone_fid_map_calculated_at
|
||||||
|
ON signals_phone_fid_map (calculated_at);
|
||||||
|
|
@ -1,280 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService2;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class FlagsService2Test {
|
|
||||||
|
|
||||||
private static final LocalDate INITIAL_DATE = LocalDate.parse("2025-09-25");
|
|
||||||
|
|
||||||
private static final String RU_PASTDUEAREAR_CREATE = """
|
|
||||||
create table RU_PASTDUEARREAR
|
|
||||||
(
|
|
||||||
FID INTEGER not null,
|
|
||||||
SERIAL_NUM BIGINT not null primary key,
|
|
||||||
ACC_SERIAL_NUM BIGINT not null,
|
|
||||||
REPORTED_DT DATE not null,
|
|
||||||
AMT_PAST_DUE DECIMAL(17, 2),
|
|
||||||
DAYS_PAST_DUE BIGINT
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String RU_PASTDUEAREAR_DROP = """
|
|
||||||
DROP TABLE IF EXISTS RU_PASTDUEARREAR;
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String RU_PAYMT_DROP = """
|
|
||||||
DROP TABLE IF EXISTS RU_PAYMT;
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String RU_PAYMT_CREATE = """
|
|
||||||
create table RU_PAYMT
|
|
||||||
(
|
|
||||||
FID INTEGER not null,
|
|
||||||
SERIAL_NUM BIGINT not null primary key,
|
|
||||||
DAYS_PAST_DUE INTEGER,
|
|
||||||
REPORTED_DT DATE not null
|
|
||||||
);
|
|
||||||
""";
|
|
||||||
|
|
||||||
private static final String FILL_RU_PASTDUEARREAR = String.format("""
|
|
||||||
INSERT INTO RU_PASTDUEARREAR VALUES
|
|
||||||
(1, 1, 1, '%s', 36000.00, 159), -- просрочка 5000 и 90_days по этой записи
|
|
||||||
(2, 2, 2, '%s', 3200.00, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(2, 3, 2, '%s', 6700.00, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(2, 4, 2, '%s', 5700.00, null), -- просрочка 5000 по этой записи
|
|
||||||
(3, 5, 3, '%s', 300000000000.00, null),
|
|
||||||
(2, 6, 2, '%s', 0.00, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(4, 7, 4, '%s', 4000.00, null), -- нет просрочек
|
|
||||||
(5, 8, 5, '%s', 2000.31, 182), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 9, 5, '%s', 2000.31, 212), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 10, 5, '%s', 2000.31, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 11, 5, '%s', 2000.31, 273), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 12, 5, '%s', 2000.31, null), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 13, 5, '%s', 7000.31, 307), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 14, 5, '%s', 2000.31, 338), -- не макс reported_date для того же acc_serial_num, просрочка 90_days будет взята у этой записи
|
|
||||||
(5, 15, 5, '%s', 7000.31, 368), -- Просрочка 5000 будет взята у этой записи. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
(5, 16, 5, '%s', 2000.31, 399), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(5, 17, 5, '%s', 5000.31, 5), -- не макс reported_date для того же acc_serial_num
|
|
||||||
(6, 18, 6, '%s', 3000, null), -- Нет просрочки 5000, нет просрочки 90_days (90_days будет в RU_PAYMT)
|
|
||||||
(7, 19, 7, '%s', 5500, 90), -- не макс reported_date для того же acc_serial_num. 90_days будет взята отсюда
|
|
||||||
(7, 20, 7, '%s', 3000, null) -- Нет просрочки 5000. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
""",
|
|
||||||
calcLocalDateFromInitialDate("2025-05-31"),
|
|
||||||
calcLocalDateFromInitialDate("2021-12-29"),
|
|
||||||
calcLocalDateFromInitialDate("2022-01-28"),
|
|
||||||
calcLocalDateFromInitialDate("2025-04-06"),
|
|
||||||
calcLocalDateFromInitialDate("2025-01-14"),
|
|
||||||
calcLocalDateFromInitialDate("2021-11-29"),
|
|
||||||
calcLocalDateFromInitialDate("2025-12-06"),
|
|
||||||
calcLocalDateFromInitialDate("2021-04-01"),
|
|
||||||
calcLocalDateFromInitialDate("2021-05-01"),
|
|
||||||
calcLocalDateFromInitialDate("2021-05-31"),
|
|
||||||
calcLocalDateFromInitialDate("2021-07-01"),
|
|
||||||
calcLocalDateFromInitialDate("2021-07-31"),
|
|
||||||
calcLocalDateFromInitialDate("2021-08-04"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-08"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-09"),
|
|
||||||
calcLocalDateFromInitialDate("2021-11-04"),
|
|
||||||
calcLocalDateFromInitialDate("2022-01-04"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-09"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-09"),
|
|
||||||
calcLocalDateFromInitialDate("2025-09-10"));
|
|
||||||
|
|
||||||
private static final String FILL_RU_PAYMT = String.format("""
|
|
||||||
INSERT INTO RU_PAYMT VALUES
|
|
||||||
(1, 1, null, '%s'),
|
|
||||||
(2, 2, 30, '%s'),
|
|
||||||
(3, 3, null, '%s'),
|
|
||||||
(3, 4, 100, '%s'),
|
|
||||||
(4, 5, 10, '%s'),
|
|
||||||
(5, 6, 10, '%s'),
|
|
||||||
(6, 7, 90, '%s'),
|
|
||||||
(6, 8, 80, '%s'),
|
|
||||||
(7, 9, null, '%s'),
|
|
||||||
(8, 10, null, '%s'),
|
|
||||||
(8, 11, 83, '%s'),
|
|
||||||
(8, 12, 91, '%s'),
|
|
||||||
(9, 13, 100, '%s')
|
|
||||||
""",
|
|
||||||
calcLocalDateFromInitialDate("2024-11-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-10"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-15"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-15"),
|
|
||||||
calcLocalDateFromInitialDate("2023-11-15"),
|
|
||||||
calcLocalDateFromInitialDate("2024-11-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"),
|
|
||||||
calcLocalDateFromInitialDate("2024-10-09"));
|
|
||||||
|
|
||||||
|
|
||||||
private DataSource dataSource;
|
|
||||||
private NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
private FlagsService2 flagsService;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
dataSource = DataSourceBuilder.create()
|
|
||||||
.url("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=DB2;DATABASE_TO_LOWER=TRUE")
|
|
||||||
.driverClassName("org.h2.Driver")
|
|
||||||
.username("sa")
|
|
||||||
.password("")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
|
||||||
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PASTDUEAREAR_DROP);
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PAYMT_DROP);
|
|
||||||
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PASTDUEAREAR_CREATE);
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(RU_PAYMT_CREATE);
|
|
||||||
|
|
||||||
flagsService = new FlagsService2(jdbcTemplate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlags() {
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PASTDUEARREAR);
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PAYMT);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPaymt() {
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PASTDUEARREAR);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPastduearreae() {
|
|
||||||
jdbcTemplate.getJdbcTemplate().execute(FILL_RU_PAYMT);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static LocalDate calcLocalDateFromInitialDate(String date) {
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
long daysPassed = ChronoUnit.DAYS.between(INITIAL_DATE, now);
|
|
||||||
return LocalDate.parse(date).plusDays(daysPassed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,218 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import ru.nbch.credit_tracker.mapper.indic.FlagsMapper;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
public class FlagsServiceTest {
|
|
||||||
|
|
||||||
private static final LocalDate INITIAL_DATE = LocalDate.parse("2025-09-25");
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
FlagsMapper flagsMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlags() {
|
|
||||||
FlagsService flagsService = new FlagsService(flagsMapper);
|
|
||||||
|
|
||||||
when(flagsMapper.findRuPastDuarearData(Mockito.anyList())).thenReturn(ruPastDuarearDataList);
|
|
||||||
when(flagsMapper.findRuPaymtData(Mockito.anyList(), Mockito.any())).thenReturn(ruPaymtDataList);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPaymt() {
|
|
||||||
FlagsService flagsService = new FlagsService(flagsMapper);
|
|
||||||
|
|
||||||
when(flagsMapper.findRuPastDuarearData(Mockito.anyList())).thenReturn(ruPastDuarearDataList);
|
|
||||||
when(flagsMapper.findRuPaymtData(Mockito.anyList(), Mockito.any())).thenReturn(new ArrayList<>());
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(1, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testfindFlagsWithoutRuPastduearreae() {
|
|
||||||
FlagsService flagsService = new FlagsService(flagsMapper);
|
|
||||||
|
|
||||||
when(flagsMapper.findRuPastDuarearData(Mockito.anyList())).thenReturn(new ArrayList<>());
|
|
||||||
when(flagsMapper.findRuPaymtData(Mockito.anyList(), Mockito.any())).thenReturn(ruPaymtDataList);
|
|
||||||
|
|
||||||
List<Integer> fids = new ArrayList<>(List.of(
|
|
||||||
1, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
2, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Нет просрочки 90_days в RU_PAYMT
|
|
||||||
3, // есть просрочка 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
4, // нет никаких просрочек
|
|
||||||
7, // нет просрочки 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
5, // есть просрочка 5000, есть просрочка 90_days в RU_PASTDUEARREAR
|
|
||||||
6, // нет просрочки 5000, нет просрочки 90_days в RU_PASTDUEARREAR. Есть просрочка 90_days в RU_PAYMT
|
|
||||||
8, // нету в RU_PASTDUEARREAR, есть в RU_PAYMT
|
|
||||||
9) // нету в RU_PASTDUEARREAR, нету в RU_PAYMT
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<Integer, FlagsService.FlagsData> resultMap = flagsService.findFlags(fids);
|
|
||||||
|
|
||||||
Assertions.assertEquals(9, resultMap.size());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(3).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(6).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(8).getFlagDebt5000());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(9).getFlagDebt5000());
|
|
||||||
|
|
||||||
Assertions.assertEquals(0, resultMap.get(1).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(2).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(3).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(4).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(5).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(6).getFlag90days());
|
|
||||||
Assertions.assertEquals(0, resultMap.get(7).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(8).getFlag90days());
|
|
||||||
Assertions.assertEquals(1, resultMap.get(9).getFlag90days());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private final List<FlagsService.RuPastDuarearData> ruPastDuarearDataList = new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
new FlagsService.RuPastDuarearData(1, BigInteger.valueOf(1), calcLocalDateFromInitialDate("2025-05-31"), BigDecimal.valueOf(36000.00), BigInteger.valueOf(159)), // просрочка 5000 и 90_days по этой записи
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2021-12-29"), BigDecimal.valueOf(3200.00), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2022-01-28"), BigDecimal.valueOf(6700.00), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2025-04-06"), BigDecimal.valueOf(5700.00), null), // просрочка 5000 по этой записи
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(3, BigInteger.valueOf(3), calcLocalDateFromInitialDate("2025-01-14"), BigDecimal.valueOf(300000000000.00), null),
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(2, BigInteger.valueOf(2), calcLocalDateFromInitialDate("2021-11-29"), BigDecimal.valueOf(0.00), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(4, BigInteger.valueOf(4), calcLocalDateFromInitialDate("2025-12-06"), BigDecimal.valueOf(4000.00), null), // нет просрочек
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-04-01"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(182)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-05-01"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(212)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-05-31"), BigDecimal.valueOf(2000.31), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-07-01"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(273)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-07-31"), BigDecimal.valueOf(2000.31), null), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-08-04"), BigDecimal.valueOf(7000.31), BigInteger.valueOf(307)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2025-09-08"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(338)), // не макс reported_date для того же acc_serial_num, просрочка 90_days будет взята у этой записи
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(51), calcLocalDateFromInitialDate("2025-09-09"), BigDecimal.valueOf(7000.31), BigInteger.valueOf(368)), // Просрочка 5000 будет взята у этой записи. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2021-11-04"), BigDecimal.valueOf(2000.31), BigInteger.valueOf(399)), // не макс reported_date для того же acc_serial_num
|
|
||||||
new FlagsService.RuPastDuarearData(5, BigInteger.valueOf(5), calcLocalDateFromInitialDate("2022-01-04"), BigDecimal.valueOf(5000.31), BigInteger.valueOf(5)), // не макс reported_date для того же acc_serial_num
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(6, BigInteger.valueOf(6), calcLocalDateFromInitialDate("2025-09-09"), BigDecimal.valueOf(3000), null), // Нет просрочки 5000, нет просрочки 90_days (90_days будет в RU_PAYMT)
|
|
||||||
|
|
||||||
new FlagsService.RuPastDuarearData(7, BigInteger.valueOf(7), calcLocalDateFromInitialDate("2025-09-09"), BigDecimal.valueOf(5500), BigInteger.valueOf(90)), // не макс reported_date для того же acc_serial_num. 90_days будет взята отсюда
|
|
||||||
new FlagsService.RuPastDuarearData(7, BigInteger.valueOf(7), calcLocalDateFromInitialDate("2025-09-10"), BigDecimal.valueOf(3000), null) // Нет просрочки 5000. Уникальный acc_serial_num с макс reported_dt
|
|
||||||
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
private final List<FlagsService.RuPaymtData> ruPaymtDataList = new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
new FlagsService.RuPaymtData(1, null, calcLocalDateFromInitialDate("2024-11-09")),
|
|
||||||
new FlagsService.RuPaymtData(2, BigInteger.valueOf(30), calcLocalDateFromInitialDate("2024-11-09")),
|
|
||||||
new FlagsService.RuPaymtData(3, null, calcLocalDateFromInitialDate("2024-11-10")),
|
|
||||||
new FlagsService.RuPaymtData(3, BigInteger.valueOf(100), calcLocalDateFromInitialDate("2024-11-15")),
|
|
||||||
new FlagsService.RuPaymtData(4, BigInteger.valueOf(10), calcLocalDateFromInitialDate("2024-11-15")),
|
|
||||||
new FlagsService.RuPaymtData(5, BigInteger.valueOf(10), calcLocalDateFromInitialDate("2023-11-15")),
|
|
||||||
new FlagsService.RuPaymtData(6, BigInteger.valueOf(90), calcLocalDateFromInitialDate("2024-11-09")),
|
|
||||||
new FlagsService.RuPaymtData(6, BigInteger.valueOf(80), calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(7, null, calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(8, null, calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(8, BigInteger.valueOf(83), calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(8, BigInteger.valueOf(91), calcLocalDateFromInitialDate("2024-10-09")),
|
|
||||||
new FlagsService.RuPaymtData(9, BigInteger.valueOf(100), calcLocalDateFromInitialDate("2024-10-09"))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
private LocalDate calcLocalDateFromInitialDate(String date) {
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
long daysPassed = ChronoUnit.DAYS.between(INITIAL_DATE, now);
|
|
||||||
return LocalDate.parse(date).plusDays(daysPassed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
|
||||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService2;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
public class PhoneService2Test {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
NamedParameterJdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void defineFidByPhoneTest() {
|
|
||||||
PhoneService2 phoneService = new PhoneService2(jdbcTemplate);
|
|
||||||
|
|
||||||
fidsDataWithEqualSinceDt.sort(byDbOrder);
|
|
||||||
when(jdbcTemplate.query(anyString(), any(MapSqlParameterSource.class), any(RowMapper.class))).thenReturn(fidsDataWithEqualSinceDt);
|
|
||||||
|
|
||||||
List<PhoneFidMap> phoneFidMap = new ArrayList<>();
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1111").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1112").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1113").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1114").build());
|
|
||||||
|
|
||||||
Map<Integer, PhoneFidMap> res = phoneService.defineFidByPhone(phoneFidMap);
|
|
||||||
Assertions.assertEquals(3, res.size());
|
|
||||||
Assertions.assertEquals("1111", res.get(124).getPhone());
|
|
||||||
Assertions.assertEquals("1112", res.get(125).getPhone());
|
|
||||||
Assertions.assertEquals("1114", res.get(126).getPhone());
|
|
||||||
}
|
|
||||||
|
|
||||||
private final List<PhoneService2.FidsData> fidsDataWithEqualSinceDt = new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
new PhoneService2.FidsData(123, "91111", LocalDate.of(2025, 9, 10)),
|
|
||||||
new PhoneService2.FidsData(124, "91111", LocalDate.of(2025, 9, 10)),
|
|
||||||
new PhoneService2.FidsData(125, "91112", LocalDate.of(2024, 10, 10)),
|
|
||||||
new PhoneService2.FidsData(126, "91114", LocalDate.of(2024, 10, 11))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Comparator<PhoneService2.FidsData> byDbOrder =
|
|
||||||
Comparator.comparing(PhoneService2.FidsData::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC
|
|
||||||
.thenComparing(PhoneService2.FidsData::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC
|
|
||||||
.thenComparing(PhoneService2.FidsData::getFid, Comparator.reverseOrder());
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
|
||||||
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
public class PhoneServiceTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
PhoneMapper phoneMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void defineFidByPhoneTest() {
|
|
||||||
PhoneService phoneService = new PhoneService(phoneMapper);
|
|
||||||
|
|
||||||
fidsDataWithEqualSinceDt.sort(byDbOrder);
|
|
||||||
when(phoneMapper.findFids(Mockito.anyList())).thenReturn(fidsDataWithEqualSinceDt);
|
|
||||||
|
|
||||||
List<PhoneFidMap> phoneFidMap = new ArrayList<>();
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1111").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1112").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1113").build());
|
|
||||||
phoneFidMap.add(PhoneFidMap.builder().phone("1114").build());
|
|
||||||
|
|
||||||
Map<Integer, PhoneFidMap> res = phoneService.defineFidByPhone(phoneFidMap);
|
|
||||||
Assertions.assertEquals(3, res.size());
|
|
||||||
Assertions.assertEquals("1111", res.get(124).getPhone());
|
|
||||||
Assertions.assertEquals("1112", res.get(125).getPhone());
|
|
||||||
Assertions.assertEquals("1114", res.get(126).getPhone());
|
|
||||||
}
|
|
||||||
|
|
||||||
private final List<PhoneService.FidsData> fidsDataWithEqualSinceDt = new ArrayList<>(
|
|
||||||
List.of(
|
|
||||||
new PhoneService.FidsData(123, "91111", LocalDate.of(2025, 9, 10)),
|
|
||||||
new PhoneService.FidsData(124, "91111", LocalDate.of(2025, 9, 10)),
|
|
||||||
new PhoneService.FidsData(125, "91112", LocalDate.of(2024, 10, 10)),
|
|
||||||
new PhoneService.FidsData(126, "91114", LocalDate.of(2024, 10, 11))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Comparator<PhoneService.FidsData> byDbOrder =
|
|
||||||
Comparator.comparing(PhoneService.FidsData::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC
|
|
||||||
.thenComparing(PhoneService.FidsData::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC
|
|
||||||
.thenComparing(PhoneService.FidsData::getFid, Comparator.reverseOrder());
|
|
||||||
}
|
|
||||||
|
|
@ -28,14 +28,17 @@ import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
||||||
|
|
||||||
@SpringBootTest(classes = {ValidationUtilTest.TestConfig.class})
|
@SpringBootTest(classes = {ValidationServiceTest.TestConfig.class})
|
||||||
public class ValidationUtilTest {
|
public class ValidationServiceTest {
|
||||||
|
|
||||||
private final StaxXmlProcessor staxXmlProcessor;
|
private final StaxXmlProcessor staxXmlProcessor;
|
||||||
|
private final ValidationService validationService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ValidationUtilTest(StaxXmlProcessor staxXmlProcessor) {
|
public ValidationServiceTest(StaxXmlProcessor staxXmlProcessor,
|
||||||
|
ValidationService validationService) {
|
||||||
this.staxXmlProcessor = staxXmlProcessor;
|
this.staxXmlProcessor = staxXmlProcessor;
|
||||||
|
this.validationService = validationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|
@ -46,6 +49,11 @@ public class ValidationUtilTest {
|
||||||
staxReader.add(MonitoringRequestStaxReader::new);
|
staxReader.add(MonitoringRequestStaxReader::new);
|
||||||
return new XmlProcessorStaxImpl(staxReader);
|
return new XmlProcessorStaxImpl(staxReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ValidationService validationService() {
|
||||||
|
return new ValidationService();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<Arguments> validationTestCases() {
|
private static Stream<Arguments> validationTestCases() {
|
||||||
|
|
@ -107,7 +115,7 @@ public class ValidationUtilTest {
|
||||||
|
|
||||||
if(ex == null) {
|
if(ex == null) {
|
||||||
try {
|
try {
|
||||||
ValidationUtil.validateMonitoringRequest(monitoringRequest);
|
validationService.validateMonitoringRequest(monitoringRequest);
|
||||||
} catch (SignalClientException e) {
|
} catch (SignalClientException e) {
|
||||||
ex = e;
|
ex = e;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue