Compare commits
123 commits
| 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 | ||
|
|
fdbec299d6 | ||
|
|
a3fc3f8329 | ||
|
|
7ffcd874f6 | ||
|
|
d84bdf608c | ||
|
|
26a1467af5 | ||
|
|
f921b25453 | ||
|
|
f34a7be0a1 | ||
|
|
a1a602d9e8 | ||
|
|
5ec5c407ab | ||
|
|
7c6a5fef6b | ||
|
|
3c3e340bcd | ||
|
|
0cc25b5a4b | ||
|
|
d4bef965c3 | ||
|
|
6a350bfd17 | ||
|
|
2e42b956ef | ||
|
|
f24a6a978a | ||
|
|
1aff345768 | ||
|
|
d0c20abb96 | ||
|
|
5acda45438 | ||
|
|
53f36a47b0 | ||
|
|
b8848f1c36 | ||
|
|
0fd7bba97e | ||
|
|
111d8b876b | ||
|
|
3fe63a93ec | ||
|
|
af2cd72647 | ||
|
|
9ce3b91a1e | ||
|
|
ac82f57e23 | ||
|
|
a29fe1e0f8 | ||
|
|
f8967fa337 | ||
|
|
a428ba9d49 | ||
|
|
834c6bdebb | ||
|
|
2a19a8da87 | ||
|
|
87a4a0e334 | ||
|
|
f5595141a3 | ||
|
|
0c7adde053 | ||
|
|
aa106350b5 | ||
|
|
997bcc6c4a | ||
|
|
7120fd9dd2 | ||
|
|
bb429511d3 | ||
|
|
5493fc4094 | ||
|
|
10d7f00308 | ||
|
|
33d796ef6f | ||
|
|
a827bd0f6b | ||
|
|
c77e22e641 | ||
|
|
f9f026d815 | ||
|
|
f1e2ef608c | ||
|
|
887c2ff06e | ||
|
|
82a028c664 | ||
|
|
bec4250cf5 | ||
|
|
692dacc553 | ||
|
|
48264bbdb5 | ||
|
|
b8975cb415 | ||
|
|
5c824ef0cd | ||
|
|
ebb9cd0dc8 | ||
|
|
cb5f0d9a9b | ||
|
|
f052841954 | ||
|
|
f2a827c8f2 | ||
|
|
70bb792fa4 | ||
|
|
7986fc002d | ||
|
|
f4f3cf7151 | ||
|
|
09ee8e15fa | ||
|
|
21c0731aa0 | ||
|
|
1815596a7b | ||
|
|
41582e676d | ||
|
|
1ea8d12aab | ||
|
|
63afa9b8ae | ||
|
|
1e88776f2b | ||
|
|
86bbfe16eb | ||
|
|
a67478e350 | ||
|
|
0f49bfd27e | ||
|
|
f91fee9a18 | ||
|
|
51ec8a098d | ||
|
|
430ae8497a | ||
|
|
9b2e723f4c | ||
|
|
9a1ead682d | ||
|
|
1a6b13680c | ||
|
|
28e362231f | ||
|
|
0ac6b9fdef | ||
|
|
7c6a0c1696 | ||
|
|
f0d5381b64 | ||
|
|
fecb4d467f | ||
|
|
2edecd538e | ||
|
|
ba317986b0 | ||
|
|
adfd2d4d28 | ||
|
|
29d57017ab | ||
|
|
119e93a9ff | ||
|
|
216fe7adbb | ||
|
|
da024aaa3e | ||
|
|
7c4e81b18f | ||
|
|
a72930d1af | ||
|
|
3ed2902219 |
159 changed files with 5497 additions and 1378 deletions
23
Dockerfile
Normal file
23
Dockerfile
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
FROM eclipse-temurin:17-jre-alpine
|
||||||
|
MAINTAINER ru.nbch
|
||||||
|
|
||||||
|
VOLUME /opt/app/logs/app
|
||||||
|
VOLUME /opt/app/logs/json
|
||||||
|
VOLUME /opt/app/logs/access
|
||||||
|
VOLUME /opt/app/reports
|
||||||
|
|
||||||
|
WORKDIR /opt/app
|
||||||
|
COPY maven/elastic-apm-agent-1.45.0.jar /opt/app/elastic-apm-agent.jar
|
||||||
|
COPY maven/credit-tracker.jar /opt/app/credit-tracker.jar
|
||||||
|
COPY maven/start-credit-tracker.sh /opt/app/start-credit-tracker.sh
|
||||||
|
COPY maven/credit-tracker.properties /opt/app/credit-tracker.properties
|
||||||
|
COPY maven/monitoring-request.xsd /opt/app/monitoring-request.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
|
||||||
|
ENTRYPOINT ["/opt/app/start-credit-tracker.sh"]
|
||||||
BIN
apm-agent/elastic-apm-agent-1.45.0.jar
Normal file
BIN
apm-agent/elastic-apm-agent-1.45.0.jar
Normal file
Binary file not shown.
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-----
|
||||||
|
|
@ -1,38 +1,72 @@
|
||||||
server.port=8099
|
server.port=${SERVER_PORT:8099}
|
||||||
|
server.tomcat.accesslog.enabled=true
|
||||||
|
server.tomcat.accesslog.directory=/opt/app/logs/access
|
||||||
|
server.tomcat.accesslog.prefix=access_log
|
||||||
|
server.tomcat.accesslog.suffix=.log
|
||||||
|
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=jdbc:db2://10.230.227.101: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=tester
|
ct.indic-data-source-settings.username=${USERNAME_INDIC:tester}
|
||||||
ct.indic-data-source-settings.password=tester
|
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=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=credit_tracker_user
|
ct.signal-data-source-settings.username=${USERNAME_SIGNAL:credit_tracker_user}
|
||||||
ct.signal-data-source-settings.password=
|
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=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=tester
|
ct.scoring-data-source-settings.username=${USERNAME_SCORING:tester}
|
||||||
ct.scoring-data-source-settings.password=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}
|
||||||
|
|
||||||
spring.servlet.multipart.max-file-size=2048MB
|
ct.max_xml_file_size=${ACCEPTED_XML_SIZE:1024}
|
||||||
spring.servlet.multipart.max-request-size=2048MB
|
spring.servlet.multipart.max-file-size=${ACCEPTED_ARCHIVE_SIZE:2048MB}
|
||||||
|
spring.servlet.multipart.max-request-size=${ACCEPTED_ARCHIVE_SIZE:2048MB}
|
||||||
|
|
||||||
# xsd paths
|
# xsd paths
|
||||||
ct.xsd-validation.monitoring-request-path=monitoring-request.xsd
|
ct.xsd-validation.monitoring-request-path=monitoring-request.xsd
|
||||||
ct.xsd-validation.signal-package-path=signal-package.xsd
|
ct.xsd-validation.signal-package-path=signal-package.xsd
|
||||||
|
|
||||||
ct.signals-root-uri=http://10.230.227.102:11094/signalRUalfa/
|
ct.signals-root-uri=${SIGNALS_ROOT_URI:http://10.230.227.102:11094/signalRUalfa/}
|
||||||
ct.signals-token=gttcHxwcGojoAvZK
|
ct.signals-token=${SIGNALS_TOKEN:gttcHxwcGojoAvZK}
|
||||||
ct.signals-user=0001ZZ000001
|
ct.signals-user=${SIGNALS_USER:0001ZZ000001}
|
||||||
|
|
||||||
|
ct.load-dir=/opt/app/reports
|
||||||
|
#ct.load-dir=D:\\folder_name\\signals
|
||||||
|
|
||||||
ct.load-dir=D:\\folder_name\\signals
|
|
||||||
# min
|
# min
|
||||||
ct.monitoring-interval=15
|
ct.monitoring-interval=${MONITORING_INTERVAL:15}
|
||||||
# days
|
# days
|
||||||
ct.update-flags-interval=1
|
ct.update-flags-cron-expression=${UPDATE_FLAGS_CRON_EXPRESSION:0 0 22 * * *}
|
||||||
ct.days-to-update-flags=30
|
ct.days-to-update-flags=${DAYS_TO_UPDATE_FLAGS:30}
|
||||||
|
|
||||||
|
ct.encoding=windows-1251
|
||||||
77
docker_compose/credit_tracker_config.env
Normal file
77
docker_compose/credit_tracker_config.env
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
#commons
|
||||||
|
APP_VERSION=1.24
|
||||||
|
REGISTRY_URL=rh8-vm3.nbki.msk:5000
|
||||||
|
JMX_PORT=
|
||||||
|
JMX_HOSTNAME=
|
||||||
|
|
||||||
|
#volumes
|
||||||
|
REPORT_DIR=D:\folder_name\signals
|
||||||
|
LOGS_DIR=D:\folder_name\signals\logs\app
|
||||||
|
JSON_LOGS_DIR=D:\folder_name\signals\logs\json
|
||||||
|
ACCESS_LOGS_DIR=D:\folder_name\signals\logs\access
|
||||||
|
|
||||||
|
#APM settings
|
||||||
|
APM_SERVICE_NAME=credit-tracker
|
||||||
|
APM_SERVER_URLS=test
|
||||||
|
APM_ENVIRONMENT=test
|
||||||
|
APM_SERVICE_NODE_NAME=test
|
||||||
|
|
||||||
|
HOST_PORT=8081
|
||||||
|
SERVER_PORT=8099
|
||||||
|
|
||||||
|
# datasources
|
||||||
|
# indic
|
||||||
|
DB_URL_INDIC=jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=INDIC;
|
||||||
|
USERNAME_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
|
||||||
|
DB_URL_SIGNAL=jdbc:postgresql://10.200.200.133:5432/credit_tracker
|
||||||
|
USERNAME_SIGNAL=credit_tracker_user
|
||||||
|
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
|
||||||
|
DB_URL_SCORING=jdbc:db2://10.230.227.101:2668/cprosd22:currentSchema=TEST_2_INDIC;
|
||||||
|
USERNAME_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
|
||||||
|
ACCEPTED_XML_SIZE=1024
|
||||||
|
ACCEPTED_ARCHIVE_SIZE=2048MB
|
||||||
|
|
||||||
|
SIGNALS_ROOT_URI=http://10.230.227.102:11094/signalRUalfa/
|
||||||
|
SIGNALS_TOKEN=gttcHxwcGojoAvZK
|
||||||
|
SIGNALS_USER=0001ZZ000001
|
||||||
|
|
||||||
|
# min
|
||||||
|
MONITORING_INTERVAL=15
|
||||||
|
# days
|
||||||
|
UPDATE_FLAGS_CRON_EXPRESSION=0 22 * * *
|
||||||
|
DAYS_TO_UPDATE_FLAGS=30
|
||||||
|
|
||||||
|
|
||||||
63
docker_compose/docker-compose.yml
Normal file
63
docker_compose/docker-compose.yml
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
services:
|
||||||
|
credit-tracker:
|
||||||
|
image: ${REGISTRY_URL}/credit-tracker:${APP_VERSION}
|
||||||
|
container_name: credit-tracker
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ${LOGS_DIR}:/opt/app/logs/app
|
||||||
|
- ${JSON_LOGS_DIR}:/opt/app/logs/json
|
||||||
|
- ${REPORT_DIR}:/opt/app/reports
|
||||||
|
- ${ACCESS_LOGS_DIR}:/opt/app/logs/access
|
||||||
|
ports:
|
||||||
|
- "${HOST_PORT}:${SERVER_PORT}"
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Moscow
|
||||||
|
- APM_SERVICE_NAME=${APM_SERVICE_NAME}
|
||||||
|
- APM_SERVER_URLS=${APM_SERVER_URLS}
|
||||||
|
- APM_ENVIRONMENT=${APM_ENVIRONMENT}
|
||||||
|
- APM_SERVICE_NODE_NAME=${APM_SERVICE_NODE_NAME}
|
||||||
|
- APM_SERVICE_VERSION=${APP_VERSION}
|
||||||
|
- JMX_PORT=${JMX_PORT}
|
||||||
|
- JMX_HOSTNAME=${JMX_HOSTNAME}
|
||||||
|
- SERVER_PORT=${SERVER_PORT}
|
||||||
|
- DB_URL_INDIC=${DB_URL_INDIC}
|
||||||
|
- USERNAME_INDIC=${USERNAME_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}
|
||||||
|
- USERNAME_SIGNAL=${USERNAME_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}
|
||||||
|
- USERNAME_SCORING=${USERNAME_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_ARCHIVE_SIZE=${ACCEPTED_ARCHIVE_SIZE}
|
||||||
|
- SIGNALS_ROOT_URI=${SIGNALS_ROOT_URI}
|
||||||
|
- SIGNALS_TOKEN=${SIGNALS_TOKEN}
|
||||||
|
- SIGNALS_USER=${SIGNALS_USER}
|
||||||
|
- MONITORING_INTERVAL=${MONITORING_INTERVAL}
|
||||||
|
- UPDATE_FLAGS_INTERVAL=${UPDATE_FLAGS_INTERVAL}
|
||||||
|
- DAYS_TO_UPDATE_FLAGS=${DAYS_TO_UPDATE_FLAGS}
|
||||||
157
pom.xml
157
pom.xml
|
|
@ -9,8 +9,8 @@
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>ru.nbch</groupId>
|
<groupId>ru.nbch</groupId>
|
||||||
<artifactId>credit_tracker</artifactId>
|
<artifactId>credit-tracker</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.24</version>
|
||||||
<name>credit_tracker</name>
|
<name>credit_tracker</name>
|
||||||
<description>Credit Tracker Application</description>
|
<description>Credit Tracker Application</description>
|
||||||
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
<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>10.230.238.56:5000</registry.url>
|
||||||
|
<!-- <registry.url>rh8-vm3.nbki.msk:5000</registry.url>-->
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
@ -25,6 +27,10 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis.spring.boot</groupId>
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
|
|
@ -94,6 +100,21 @@
|
||||||
<artifactId>jakarta.activation</artifactId>
|
<artifactId>jakarta.activation</artifactId>
|
||||||
<version>2.0.1</version>
|
<version>2.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>co.elastic.apm</groupId>
|
||||||
|
<artifactId>apm-agent-api</artifactId>
|
||||||
|
<version>1.43.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.internetitem</groupId>
|
||||||
|
<artifactId>logback-elasticsearch-appender</artifactId>
|
||||||
|
<version>1.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.logstash.logback</groupId>
|
||||||
|
<artifactId>logstash-logback-encoder</artifactId>
|
||||||
|
<version>7.4</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|
@ -105,11 +126,118 @@
|
||||||
<version>3.0.4</version>
|
<version>3.0.4</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-junit-jupiter</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>docker-push-dev</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>docker-maven-plugin</artifactId>
|
||||||
|
<version>0.45.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>Build and deploy docker container</id>
|
||||||
|
<phase>install</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>build</goal>
|
||||||
|
<goal>push</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<images>
|
||||||
|
<image>
|
||||||
|
<name>${project.artifactId}:${project.version}</name>
|
||||||
|
<registry>${registry.url}</registry>
|
||||||
|
<build>
|
||||||
|
<dockerFile>${project.basedir}/Dockerfile</dockerFile>
|
||||||
|
<assembly>
|
||||||
|
<inline>
|
||||||
|
<files>
|
||||||
|
<file>
|
||||||
|
<source>
|
||||||
|
${project.build.directory}/${project.build.finalName}.jar
|
||||||
|
</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<source>
|
||||||
|
${project.basedir}/apm-agent/elastic-apm-agent-1.45.0.jar
|
||||||
|
</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<source>${project.basedir}/start-credit-tracker.sh</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<source>${project.basedir}/credit-tracker.properties</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<source>${project.basedir}/monitoring-request.xsd</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<source>${project.basedir}/signal-package.xsd</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
|
<file>
|
||||||
|
<source>
|
||||||
|
${project.basedir}/ca_nbki.cer
|
||||||
|
</source>
|
||||||
|
<outputDirectory>.</outputDirectory>
|
||||||
|
</file>
|
||||||
|
</files>
|
||||||
|
</inline>
|
||||||
|
</assembly>
|
||||||
|
<tags>
|
||||||
|
<tag>${project.version}</tag>
|
||||||
|
</tags>
|
||||||
|
</build>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
<build>
|
<build>
|
||||||
<finalName>credit-tracker</finalName>
|
<finalName>credit-tracker</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>pl.project13.maven</groupId>
|
<groupId>pl.project13.maven</groupId>
|
||||||
<artifactId>git-commit-id-plugin</artifactId>
|
<artifactId>git-commit-id-plugin</artifactId>
|
||||||
|
|
@ -140,30 +268,7 @@
|
||||||
</includeOnlyProperties>
|
</includeOnlyProperties>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<annotationProcessorPaths>
|
|
||||||
<path>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
</path>
|
|
||||||
</annotationProcessorPaths>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<excludes>
|
|
||||||
<exclude>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import ru.nbch.credit_tracker.service.MonitoringService;
|
import ru.nbch.credit_tracker.service.MonitoringService;
|
||||||
|
import ru.nbch.credit_tracker.service.UpdateProcessingPackagesService;
|
||||||
import ru.nbch.credit_tracker.service.UpdatingFlagsService;
|
import ru.nbch.credit_tracker.service.UpdatingFlagsService;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
|
@ -11,10 +12,12 @@ public class CreditTrackerApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
ConfigurableApplicationContext ctx = SpringApplication.run(CreditTrackerApplication.class, args);
|
ConfigurableApplicationContext ctx = SpringApplication.run(CreditTrackerApplication.class, args);
|
||||||
|
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);
|
||||||
monitoringService.run();
|
monitoringService.run();
|
||||||
updatingFlagsService.run();
|
updatingFlagsService.run();
|
||||||
|
updateProcessingPackagesService.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
package ru.nbch.credit_tracker.builder;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import ru.nbch.credit_tracker.entities.external_request.signals.Person;
|
||||||
|
import ru.nbch.credit_tracker.service.indic.PersonService;
|
||||||
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class PersonFactoryBuilder {
|
||||||
|
private final static DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("dd.MM.yyyy");
|
||||||
|
|
||||||
|
private final static String DEFAULT_DATE = "01.01.2000";
|
||||||
|
private final static String IP = "0";
|
||||||
|
private final static String OKSM = "999";
|
||||||
|
private final static String CONSENT_PURPOSE = "16";
|
||||||
|
private final static String REPORT_USER = "АО «НБКИ»";
|
||||||
|
private final static String LIABILITY = "1";
|
||||||
|
private final static String CONSENT_PERIOD = "3";
|
||||||
|
private final static String REPORT_USER_REG_NUM = "1057746710713";
|
||||||
|
private final static String REPORT_USER_TAX_ID = "7703548386";
|
||||||
|
private final static String CONSENT_HASH = "hash";
|
||||||
|
private final static String CONSENT_DIV_CODE = "000-000";
|
||||||
|
private final static String INQ_PURPOSE = "16";
|
||||||
|
private final static String ODT = "Иной документ";
|
||||||
|
private final static String CONSENT_ISSUE_AUTHORITY = "Кем выдан";
|
||||||
|
|
||||||
|
|
||||||
|
private PersonService.PersonData personData;
|
||||||
|
private Long uid;
|
||||||
|
|
||||||
|
public static PersonFactoryBuilder builder() {
|
||||||
|
return new PersonFactoryBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonFactoryBuilder personData(PersonService.PersonData personData) {
|
||||||
|
this.personData = personData;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonFactoryBuilder uid(Long uid) {
|
||||||
|
this.uid = uid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person build() {
|
||||||
|
if (personData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
PersonService.NameData nameData = personData.getName();
|
||||||
|
PersonService.PassportData passportData = personData.getPassport();
|
||||||
|
Person person = new Person();
|
||||||
|
person.setS(nameData.getLastName());
|
||||||
|
person.setN(nameData.getFirstName());
|
||||||
|
person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null);
|
||||||
|
person.setD(DATE_FORMAT.format(nameData.getBirthDate()));
|
||||||
|
|
||||||
|
person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum()));
|
||||||
|
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()));
|
||||||
|
if (person.getDt() != null && person.getDt().equals("999")) {
|
||||||
|
person.setOdt(ODT);
|
||||||
|
person.setConsentOdt(ODT);
|
||||||
|
}
|
||||||
|
person.setIp(IP);
|
||||||
|
person.setUid(uid);
|
||||||
|
person.setOksm(OKSM);
|
||||||
|
person.setConsentDate(DATE_FORMAT.format(LocalDate.now()));
|
||||||
|
person.setConsentPurpose(CONSENT_PURPOSE);
|
||||||
|
person.setReportUser(REPORT_USER);
|
||||||
|
person.setLiability(LIABILITY);
|
||||||
|
person.setConsentPeriod(CONSENT_PERIOD);
|
||||||
|
person.setAgrDate(DATE_FORMAT.format(LocalDate.now()));
|
||||||
|
person.setReportUserRegNum(REPORT_USER_REG_NUM);
|
||||||
|
person.setReportUserTaxID(REPORT_USER_TAX_ID);
|
||||||
|
person.setConsentHash(CONSENT_HASH);
|
||||||
|
|
||||||
|
person.setCs(person.getS());
|
||||||
|
person.setConsentN(person.getN());
|
||||||
|
person.setConsentM(person.getM());
|
||||||
|
person.setConsentBd(person.getD());
|
||||||
|
person.setConsentPn(person.getPn());
|
||||||
|
person.setConsentPd(person.getPd());
|
||||||
|
person.setConsentDivCode(CONSENT_DIV_CODE);
|
||||||
|
person.setConsentDt(person.getDt());
|
||||||
|
person.setConsentIssueAuthority(CONSENT_ISSUE_AUTHORITY);
|
||||||
|
person.setInqPurpose(INQ_PURPOSE);
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPn(String serNum, String idNum) {
|
||||||
|
String normSerNum = CTUtil.normalize(serNum);
|
||||||
|
String normIdNum = CTUtil.normalize(idNum);
|
||||||
|
return StringUtils.isNotBlank(normSerNum) ? normSerNum + normIdNum : normIdNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDt(String idType, String idType2) {
|
||||||
|
if (StringUtils.isNotBlank(idType2)) {
|
||||||
|
return idType2;
|
||||||
|
} else {
|
||||||
|
return switch (idType) {
|
||||||
|
case "21" -> "21";
|
||||||
|
case "22" -> "22.1";
|
||||||
|
case "09" -> "22.2";
|
||||||
|
case "26" -> "23";
|
||||||
|
case "04" -> "24";
|
||||||
|
case "07" -> "25";
|
||||||
|
case "14", "03" -> "27";
|
||||||
|
case "10" -> "31";
|
||||||
|
case "15" -> "32";
|
||||||
|
case "13" -> "37";
|
||||||
|
case "06", "27" -> "28";
|
||||||
|
case "01", "02" -> "999";
|
||||||
|
default -> {
|
||||||
|
log.warn("ID_TYPE2 is blank and no matching found for ID_TYPE {}", idType);
|
||||||
|
yield "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package ru.nbch.credit_tracker.component;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class MapperTimingAspect {
|
||||||
|
@Around("within(@org.apache.ibatis.annotations.Mapper *)")
|
||||||
|
public Object timeMapper(ProceedingJoinPoint pjp) throws Throwable {
|
||||||
|
long start = System.nanoTime();
|
||||||
|
try {
|
||||||
|
return pjp.proceed();
|
||||||
|
} finally {
|
||||||
|
long tookMs = (System.nanoTime() - start) / 1_000_000;
|
||||||
|
String method = pjp.getSignature().toShortString();
|
||||||
|
if (tookMs > 1000) {
|
||||||
|
log.warn("Slow mapper call {} took {} ms", method, tookMs);
|
||||||
|
} else {
|
||||||
|
log.debug("Mapper call {} took {} ms", method, tookMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.nbch.credit_tracker.config.datasource;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
|
import ru.nbch.credit_tracker.config.settings.DataSourceSettings;
|
||||||
|
|
||||||
|
public class DatabaseConfig {
|
||||||
|
|
||||||
|
protected HikariDataSource createDataSource(DataSourceSettings settings) {
|
||||||
|
return DataSourceBuilder.create()
|
||||||
|
.driverClassName(settings.driver())
|
||||||
|
.url(settings.url())
|
||||||
|
.username(settings.username())
|
||||||
|
.password(settings.password())
|
||||||
|
.type(HikariDataSource.class)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,11 +7,11 @@ import org.mybatis.spring.SqlSessionFactoryBean;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
|
||||||
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 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;
|
||||||
|
|
@ -23,26 +23,32 @@ import java.sql.SQLException;
|
||||||
basePackages = "ru.nbch.credit_tracker.mapper.indic",
|
basePackages = "ru.nbch.credit_tracker.mapper.indic",
|
||||||
sqlSessionFactoryRef = "sqlSessionIndic"
|
sqlSessionFactoryRef = "sqlSessionIndic"
|
||||||
)
|
)
|
||||||
public class IndicDataSourceConfig {
|
public class IndicDataSourceConfig extends DatabaseConfig {
|
||||||
|
|
||||||
@Value("classpath:mybatis/mapper/indic/*.xml")
|
@Value("classpath:mybatis/mapper/indic/*.xml")
|
||||||
private Resource[] resources;
|
private Resource[] resources;
|
||||||
|
|
||||||
@Bean(name = "indicDataSource")
|
@Bean(name = "indicDataSource")
|
||||||
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
||||||
DataSourceBuilder<HikariDataSource> dataSourceBuilder = (DataSourceBuilder<HikariDataSource>) DataSourceBuilder.create();
|
DataSourceSettings indicSetings = config.getIndicDataSourceSettings();
|
||||||
dataSourceBuilder.driverClassName(config.getIndicDataSourceSettings().driver());
|
|
||||||
dataSourceBuilder.url(config.getIndicDataSourceSettings().url());
|
HikariDataSource dataSource = createDataSource(indicSetings);
|
||||||
dataSourceBuilder.username(config.getIndicDataSourceSettings().username());
|
dataSource.setMaximumPoolSize(indicSetings.maximumPoolSize());
|
||||||
dataSourceBuilder.password(config.getIndicDataSourceSettings().password());
|
dataSource.setMinimumIdle(indicSetings.minimumIdle());
|
||||||
HikariDataSource dataSource = dataSourceBuilder.build();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,41 +7,48 @@ import org.mybatis.spring.SqlSessionFactoryBean;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
|
||||||
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 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;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
@MapperScan(
|
@MapperScan(
|
||||||
basePackages = "ru.nbch.credit_tracker.mapper.scoring",
|
basePackages = "ru.nbch.credit_tracker.mapper.scoring",
|
||||||
sqlSessionFactoryRef = "sqlSessionScoring"
|
sqlSessionFactoryRef = "sqlSessionScoring"
|
||||||
)
|
)
|
||||||
public class ScoringDataSourceConfig {
|
public class ScoringDataSourceConfig extends DatabaseConfig {
|
||||||
|
|
||||||
@Value("classpath:mybatis/mapper/scoring/*.xml")
|
@Value("classpath:mybatis/mapper/scoring/*.xml")
|
||||||
private Resource[] resources;
|
private Resource[] resources;
|
||||||
|
|
||||||
@Bean(name = "scoringDataSource")
|
@Bean(name = "scoringDataSource")
|
||||||
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
||||||
DataSourceBuilder<HikariDataSource> dataSourceBuilder = (DataSourceBuilder<HikariDataSource>) DataSourceBuilder.create();
|
DataSourceSettings scoringSetings = config.getScoringDataSourceSettings();
|
||||||
dataSourceBuilder.driverClassName(config.getScoringDataSourceSettings().driver());
|
|
||||||
dataSourceBuilder.url(config.getScoringDataSourceSettings().url());
|
HikariDataSource dataSource = createDataSource(scoringSetings);
|
||||||
dataSourceBuilder.username(config.getScoringDataSourceSettings().username());
|
dataSource.setMaximumPoolSize(scoringSetings.maximumPoolSize());
|
||||||
dataSourceBuilder.password(config.getScoringDataSourceSettings().password());
|
dataSource.setMinimumIdle(scoringSetings.minimumIdle());
|
||||||
HikariDataSource dataSource = dataSourceBuilder.build();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ import org.mybatis.spring.SqlSessionFactoryBean;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.jdbc.DataSourceBuilder;
|
|
||||||
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 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;
|
||||||
|
|
@ -23,25 +23,31 @@ import java.sql.SQLException;
|
||||||
basePackages = "ru.nbch.credit_tracker.mapper.signal",
|
basePackages = "ru.nbch.credit_tracker.mapper.signal",
|
||||||
sqlSessionFactoryRef = "sqlSessionSignal"
|
sqlSessionFactoryRef = "sqlSessionSignal"
|
||||||
)
|
)
|
||||||
public class SignalDataSourceConfig {
|
public class SignalDataSourceConfig extends DatabaseConfig {
|
||||||
@Value("classpath:mybatis/mapper/signal/*.xml")
|
@Value("classpath:mybatis/mapper/signal/*.xml")
|
||||||
private Resource[] resources;
|
private Resource[] resources;
|
||||||
|
|
||||||
@Bean(name = "signalDataSource")
|
@Bean(name = "signalDataSource")
|
||||||
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
public DataSource dataSource(CreditTrackerSettings config) throws SQLException {
|
||||||
DataSourceBuilder<HikariDataSource> dataSourceBuilder = (DataSourceBuilder<HikariDataSource>) DataSourceBuilder.create();
|
DataSourceSettings signalSetings = config.getSignalDataSourceSettings();
|
||||||
dataSourceBuilder.driverClassName(config.getSignalDataSourceSettings().driver());
|
|
||||||
dataSourceBuilder.url(config.getSignalDataSourceSettings().url());
|
HikariDataSource dataSource = createDataSource(signalSetings);
|
||||||
dataSourceBuilder.username(config.getSignalDataSourceSettings().username());
|
dataSource.setMaximumPoolSize(signalSetings.maximumPoolSize());
|
||||||
// dataSourceBuilder.password(config.getSignalDataSourceSettings().password()); TODO uncomment whe password will be set
|
dataSource.setMinimumIdle(signalSetings.minimumIdle());
|
||||||
HikariDataSource dataSource = dataSourceBuilder.build();
|
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;
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,85 @@
|
||||||
package ru.nbch.credit_tracker.config.rest;
|
package ru.nbch.credit_tracker.config.rest;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
|
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||||
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.errors.*;
|
||||||
|
import ru.nbch.credit_tracker.enums.SignalError;
|
||||||
|
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||||
|
import ru.nbch.credit_tracker.exceptions.SignalException;
|
||||||
|
import ru.nbch.credit_tracker.exceptions.SignalServerException;
|
||||||
|
import ru.nbch.credit_tracker.utils.error.SimpleMessageResolver;
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class GlobalExceptionHandler {
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
@ExceptionHandler(value = SignalErrorException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
private final SimpleMessageResolver messageResolver = new SimpleMessageResolver();
|
||||||
public ResponseEntity<CommonError> handleInvalidUser(SignalErrorException ex) {
|
private final String encoding;
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.setContentType(new MediaType("application", "xml", Charset.forName("windows-1251")));
|
public GlobalExceptionHandler(CreditTrackerSettings settings) {
|
||||||
if (ex.isUserError()) {
|
this.encoding = settings.getEncoding();
|
||||||
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.BAD_REQUEST);
|
|
||||||
} else {
|
|
||||||
return new ResponseEntity<>(ex.getError(), headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = MaxUploadSizeExceededException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
|
public ResponseEntity<MonitoringError> handleMaxUploadSizeExceeded(MaxUploadSizeExceededException ex) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(new MediaType("application", "xml", Charset.forName(encoding)));
|
||||||
|
|
||||||
|
MonitoringError error = new MonitoringError();
|
||||||
|
error.setStatus("error");
|
||||||
|
error.setErrorCode(SignalError.ERROR_009.getCode());
|
||||||
|
error.setErrorText(SignalError.ERROR_009.getKey());
|
||||||
|
|
||||||
|
return new ResponseEntity<>(error, headers, HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(value = SignalException.class, produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
|
public ResponseEntity<CommonError> handleClientException(SignalException ex) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(new MediaType("application", "xml", Charset.forName(encoding)));
|
||||||
|
|
||||||
|
String errorText = messageResolver.resolve(ex.getErrorMessage());
|
||||||
|
|
||||||
|
CommonError commonError = getCommonError(ex);
|
||||||
|
commonError.setStatus("error");
|
||||||
|
commonError.setErrorCode(ex.getErrorMessage().getSubject().getCode());
|
||||||
|
commonError.setErrorText(errorText);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return new ResponseEntity<>(commonError, headers, HttpStatus.BAD_REQUEST);
|
||||||
|
} else {
|
||||||
|
Exception cause = ((SignalServerException) ex).getCause();
|
||||||
|
log.error(cause.getMessage(), cause);
|
||||||
|
return new ResponseEntity<>(commonError, headers, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CommonError getCommonError(SignalException ex) {
|
||||||
|
CommonError commonError;
|
||||||
|
switch (ex.getErrorFormat()) {
|
||||||
|
case MonitoringError -> commonError = new MonitoringError();
|
||||||
|
case MonitoringActivePackagesError -> commonError = new MonitoringActivePackagesError();
|
||||||
|
case MonitoringAllPackagesError -> commonError = new MonitoringAllPackagesError();
|
||||||
|
case MonitoringDownloadError -> commonError = new MonitoringDownloadError();
|
||||||
|
case MonitoringReportListError -> commonError = new MonitoringReportListError();
|
||||||
|
case MonitoringPackageDeleteError -> commonError = new MonitoringPackageDeleteError();
|
||||||
|
default -> throw new IllegalStateException("Unsupported error format: " + ex.getErrorFormat());
|
||||||
|
}
|
||||||
|
return commonError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package ru.nbch.credit_tracker.config.rest;
|
||||||
|
|
||||||
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.scheduling.concurrent.CustomizableThreadFactory;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
|
|
||||||
|
|
@ -21,6 +22,6 @@ public class RestConfig {
|
||||||
|
|
||||||
@Bean(name = "executorService")
|
@Bean(name = "executorService")
|
||||||
public ExecutorService executorService() {
|
public ExecutorService executorService() {
|
||||||
return Executors.newCachedThreadPool();
|
return Executors.newCachedThreadPool(new CustomizableThreadFactory("package-registration-"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
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.HttpServletRequestWrapper;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.Part;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||||
|
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
@Order(0)
|
||||||
|
public class HttpLoggingFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private static final Set<String> SENSITIVE_HEADERS = Set.of("authorization", "cookie", "set-cookie");
|
||||||
|
private static final int MAX_BODY = 10 * 1024;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldNotFilter(HttpServletRequest request) {
|
||||||
|
String path = request.getRequestURI();
|
||||||
|
return path.startsWith("/actuator/health") || path.startsWith("/swagger")
|
||||||
|
|| path.startsWith("/v3/api-docs") || path.startsWith("/static/") || path.equals("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
long startNs = System.nanoTime();
|
||||||
|
|
||||||
|
ContentCachingRequestWrapper req = wrapRequest(request);
|
||||||
|
ContentCachingResponseWrapper resp = new ContentCachingResponseWrapper(response);
|
||||||
|
|
||||||
|
String correlationId = Optional.ofNullable(request.getHeader("X-Correlation-Id"))
|
||||||
|
.filter(StringUtils::hasText)
|
||||||
|
.orElse(UUID.randomUUID().toString());
|
||||||
|
resp.setHeader("X-Correlation-Id", correlationId);
|
||||||
|
|
||||||
|
logIncomingRequest(req, correlationId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
chain.doFilter(req, resp);
|
||||||
|
} finally {
|
||||||
|
long tookMs = (System.nanoTime() - startNs) / 1_000_000;
|
||||||
|
|
||||||
|
Map<String, String> reqParams = paramsMap(req);
|
||||||
|
|
||||||
|
Map<String, String> reqHeaders = headersMap(req);
|
||||||
|
Map<String, String> respHeaders = headersMap(resp);
|
||||||
|
|
||||||
|
mask(reqHeaders);
|
||||||
|
mask(respHeaders);
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"HTTP (RESPONSE) {} {} | status={} | took={}ms | cid={} | reqHeaders={} | reqParams={} | respHeaders={}",
|
||||||
|
req.getMethod(),
|
||||||
|
req.getRequestURI(),
|
||||||
|
resp.getStatus(),
|
||||||
|
tookMs,
|
||||||
|
correlationId,
|
||||||
|
reqHeaders,
|
||||||
|
reqParams,
|
||||||
|
respHeaders
|
||||||
|
);
|
||||||
|
|
||||||
|
resp.copyBodyToResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Map<String, String> headersMap(HttpServletRequest req) {
|
||||||
|
return Collections.list(req.getHeaderNames()).stream()
|
||||||
|
.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) {
|
||||||
|
return resp.getHeaderNames().stream()
|
||||||
|
.collect(Collectors.toMap(h -> h, resp::getHeader, (a, b) -> a, LinkedHashMap::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void mask(Map<String, String> headers) {
|
||||||
|
headers.replaceAll((k, v) -> SENSITIVE_HEADERS.contains(k.toLowerCase()) ? "***" : v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,9 +26,11 @@ public class CreditTrackerSettings {
|
||||||
private String signalsToken;
|
private String signalsToken;
|
||||||
private String signalsuser;
|
private String signalsuser;
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
) {}
|
) {}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package ru.nbch.credit_tracker.config.xml;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.JAXBException;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
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.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.success.MonitoringSetupResponse;
|
||||||
|
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
||||||
|
import ru.nbch.credit_tracker.service.xml.jaxb.XmlProcessorImplAnyClasses;
|
||||||
|
import ru.nbch.credit_tracker.service.xml.stax.*;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class XmlConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public IXmlProcessor xmlProcessor(CreditTrackerSettings settings) throws JAXBException {
|
||||||
|
return new XmlProcessorImplAnyClasses(Charset.forName(settings.getEncoding()),
|
||||||
|
// unmarshalling classes
|
||||||
|
SgnlOnlineReport.class,
|
||||||
|
SgnlReportMonitorigSetupError.class,
|
||||||
|
MonitoringActivePackagesRequest.class,
|
||||||
|
MonitoringAllPackagesRequest.class,
|
||||||
|
// marshalling classes
|
||||||
|
MonitoringError.class,
|
||||||
|
MonitoringSetupResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public StaxXmlProcessor staxXmlProcessor() {
|
||||||
|
List<Supplier<StaxReader<?>>> staxReader = new ArrayList<>();
|
||||||
|
staxReader.add(SgnlReportStatusStaxReader::new);
|
||||||
|
staxReader.add(MonitoringRequestStaxReader::new);
|
||||||
|
staxReader.add(OnlineDownloadReportPersonsStaxReader::new);
|
||||||
|
staxReader.add(MonitoringSignalResponseStaxXmlReader::new);
|
||||||
|
staxReader.add(MonitoringReportErrorsStaxtReader::new);
|
||||||
|
return new XmlProcessorStaxImpl(staxReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,11 +5,13 @@ import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import ru.nbch.credit_tracker.entities.request.active_packages.MonitoringActivePackagesRequest;
|
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
||||||
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
|
import ru.nbch.credit_tracker.entities.user_request.all_packages.MonitoringAllPackagesRequest;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse;
|
import ru.nbch.credit_tracker.entities.user_response.active_packages.MonitoringActivePackagesResponse;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse;
|
import ru.nbch.credit_tracker.entities.user_response.all_packages.MonitoringAllPackagesResponse;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringPackageDeleteResponse;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringReportListResponse;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringSetupResponse;
|
||||||
import ru.nbch.credit_tracker.facade.SignalFacade;
|
import ru.nbch.credit_tracker.facade.SignalFacade;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|
@ -23,7 +25,7 @@ public class SignalController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/set", produces = MediaType.APPLICATION_XML_VALUE)
|
@PostMapping(value = "/set", produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
public ResponseEntity<MonitoringResponse> setupMonitoring(@RequestParam("file") MultipartFile file) {
|
public ResponseEntity<MonitoringSetupResponse> setupMonitoring(@RequestParam("file") MultipartFile file) {
|
||||||
return signalFacade.setupMonitoring(file);
|
return signalFacade.setupMonitoring(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,6 +34,11 @@ public class SignalController {
|
||||||
return signalFacade.findActivePackages(activePackagesRequest);
|
return signalFacade.findActivePackages(activePackagesRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/all_packages", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
|
public ResponseEntity<MonitoringAllPackagesResponse> findAllPackages(@RequestBody MonitoringAllPackagesRequest allPackagesRequest) {
|
||||||
|
return signalFacade.findAllPackages(allPackagesRequest);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(value = "/delete", params = {"username", "packageName"}, produces = MediaType.APPLICATION_XML_VALUE)
|
@PostMapping(value = "/delete", params = {"username", "packageName"}, produces = MediaType.APPLICATION_XML_VALUE)
|
||||||
public ResponseEntity<MonitoringPackageDeleteResponse> deletePackage(@RequestParam("username") String username, @RequestParam("packageName") String packageName) {
|
public ResponseEntity<MonitoringPackageDeleteResponse> deletePackage(@RequestParam("username") String username, @RequestParam("packageName") String packageName) {
|
||||||
return signalFacade.deletePackage(username, packageName);
|
return signalFacade.deletePackage(username, packageName);
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class HitsData {
|
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;
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.entities.dto;
|
package ru.nbch.credit_tracker.entities.dto;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
|
@ -11,13 +8,15 @@ import java.time.LocalDateTime;
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class SubjectData {
|
@Builder
|
||||||
private Integer id;
|
public class PhoneFidMap {
|
||||||
private Integer packageId;
|
private Long id;
|
||||||
|
private Long packageId;
|
||||||
private String subjectId;
|
private String subjectId;
|
||||||
private String phone;
|
private String phone;
|
||||||
private Integer fid;
|
private Integer fid;
|
||||||
private Integer flagDebt5000;
|
private Integer flagDebt5000;
|
||||||
private Integer flag90days;
|
private Integer flag90days;
|
||||||
private LocalDateTime calculatedAt;
|
private LocalDateTime calculatedAt;
|
||||||
|
private String errorText;
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.nbch.credit_tracker.entities.dto;
|
package ru.nbch.credit_tracker.entities.dto;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
|
@ -7,11 +8,14 @@ import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class PackageData {
|
@Builder
|
||||||
private Integer id;
|
public class UserPackage {
|
||||||
|
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 String lastDownloadedReport;
|
private String lastDownloadedReport;
|
||||||
|
private LocalDateTime monitoringAt;
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.signal_package;
|
package ru.nbch.credit_tracker.entities.external_request.signals;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.signal_package;
|
package ru.nbch.credit_tracker.entities.external_request.signals;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.signal_package;
|
package ru.nbch.credit_tracker.entities.external_request.signals;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -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 String 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)
|
||||||
|
|
@ -34,6 +34,8 @@ public class Person {
|
||||||
protected String pd;
|
protected String pd;
|
||||||
@XmlAttribute(name = "dt", required = true)
|
@XmlAttribute(name = "dt", required = true)
|
||||||
protected String dt;
|
protected String dt;
|
||||||
|
@XmlAttribute(name = "odt")
|
||||||
|
protected String odt;
|
||||||
@XmlAttribute(name = "ip", required = true)
|
@XmlAttribute(name = "ip", required = true)
|
||||||
protected String ip;
|
protected String ip;
|
||||||
@XmlAttribute(name = "consentDate")
|
@XmlAttribute(name = "consentDate")
|
||||||
|
|
@ -73,6 +75,10 @@ public class Person {
|
||||||
protected String consentDivCode;
|
protected String consentDivCode;
|
||||||
@XmlAttribute(name = "consentDt")
|
@XmlAttribute(name = "consentDt")
|
||||||
protected String consentDt;
|
protected String consentDt;
|
||||||
|
@XmlAttribute(name = "consentOdt")
|
||||||
|
protected String consentOdt;
|
||||||
|
@XmlAttribute(name = "consentIssueAuthority")
|
||||||
|
protected String consentIssueAuthority;
|
||||||
@XmlAttribute(name = "inqPurpose")
|
@XmlAttribute(name = "inqPurpose")
|
||||||
protected String inqPurpose;
|
protected String inqPurpose;
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.signal_package;
|
package ru.nbch.credit_tracker.entities.external_request.signals;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
package ru.nbch.credit_tracker.entities.signal_package;
|
package ru.nbch.credit_tracker.entities.external_request.signals;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -25,6 +25,8 @@ public class Signals {
|
||||||
protected Conditions conditions;
|
protected Conditions conditions;
|
||||||
@XmlAttribute(name = "online", required = true)
|
@XmlAttribute(name = "online", required = true)
|
||||||
protected String online;
|
protected String online;
|
||||||
|
@XmlAttribute(name = "processWithErrors", required = true)
|
||||||
|
protected String processWithErrors;
|
||||||
|
|
||||||
public Conditions getConditions() {
|
public Conditions getConditions() {
|
||||||
if (conditions == null) {
|
if (conditions == null) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.external_errors;
|
package ru.nbch.credit_tracker.entities.external_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.external_errors;
|
package ru.nbch.credit_tracker.entities.external_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.external_errors;
|
package ru.nbch.credit_tracker.entities.external_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.external_response.monitoring_report_error;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"id",
|
||||||
|
"version",
|
||||||
|
"user",
|
||||||
|
"reportCreated"
|
||||||
|
})
|
||||||
|
@XmlRootElement(name = "Errors")
|
||||||
|
public class MonitoringReportErrors {
|
||||||
|
|
||||||
|
@XmlElement(name = "Id")
|
||||||
|
protected String id;
|
||||||
|
|
||||||
|
@XmlElement(name = "Version")
|
||||||
|
protected String version;
|
||||||
|
|
||||||
|
@XmlElement(name = "User")
|
||||||
|
protected String user;
|
||||||
|
|
||||||
|
@XmlElement(name = "ReportCreated")
|
||||||
|
protected String reportCreated;
|
||||||
|
|
||||||
|
@XmlElement(name = "p")
|
||||||
|
protected List<P> persons;
|
||||||
|
|
||||||
|
public List<P> getPersons() {
|
||||||
|
if (persons == null) {
|
||||||
|
persons = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return this.persons;
|
||||||
|
}
|
||||||
|
|
||||||
|
private P currentPerson;
|
||||||
|
|
||||||
|
public void createCurrentPerson() {
|
||||||
|
currentPerson = new P();
|
||||||
|
}
|
||||||
|
|
||||||
|
public P getCurrentPerson() {
|
||||||
|
return currentPerson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizePerson() {
|
||||||
|
getPersons().add(currentPerson);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
})
|
||||||
|
public static class P {
|
||||||
|
|
||||||
|
@XmlAttribute(name = "uid")
|
||||||
|
protected Long uid;
|
||||||
|
|
||||||
|
@XmlValue
|
||||||
|
protected String value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.external_response.monitoring_report_file;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
|
import jakarta.xml.bind.annotation.XmlType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"filename"
|
||||||
|
})
|
||||||
|
public class ErrorsForNextReport {
|
||||||
|
|
||||||
|
@XmlElement(name = "filename", required = true)
|
||||||
|
protected String filename;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.external_response.monitoring_report_file;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
|
import jakarta.xml.bind.annotation.XmlType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"memberCode",
|
||||||
|
"packCode"
|
||||||
|
})
|
||||||
|
public class InputParams {
|
||||||
|
|
||||||
|
@XmlElement(name = "memberCode", required = true)
|
||||||
|
protected String memberCode;
|
||||||
|
|
||||||
|
@XmlElement(name = "packCode", required = true)
|
||||||
|
protected String packCode;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.external_response.monitoring_report_file;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
|
import jakarta.xml.bind.annotation.XmlType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"errorsForNextReport"
|
||||||
|
})
|
||||||
|
public class OperationReport {
|
||||||
|
|
||||||
|
@XmlElement(name = "ErrorsForNextReport")
|
||||||
|
protected ErrorsForNextReport errorsForNextReport;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.external_response.monitoring_report_file;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"inputParams",
|
||||||
|
"operationReport"
|
||||||
|
})
|
||||||
|
@XmlRootElement(name = "SgnlReport")
|
||||||
|
public class SgnlReportMonitorigSetupError {
|
||||||
|
|
||||||
|
@XmlElement(name = "InputParams", required = true)
|
||||||
|
protected InputParams inputParams;
|
||||||
|
|
||||||
|
@XmlElement(name = "OperationReport", required = true)
|
||||||
|
protected OperationReport operationReport;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_download;
|
package ru.nbch.credit_tracker.entities.external_response.online_download;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -42,4 +42,18 @@ public class Inquiry {
|
||||||
return this.signals;
|
return this.signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Signal currentSignal;
|
||||||
|
|
||||||
|
public void createCurrentSignal() {
|
||||||
|
currentSignal = new Signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Signal getCurrentSignal() {
|
||||||
|
return currentSignal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizeSignal() {
|
||||||
|
getSignals().add(currentSignal);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_download;
|
package ru.nbch.credit_tracker.entities.external_response.online_download;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_download;
|
package ru.nbch.credit_tracker.entities.external_response.online_download;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -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 String uid;
|
protected Long uid;
|
||||||
|
|
||||||
@XmlElement(name = "Inquiry", required = true)
|
@XmlElement(name = "Inquiry", required = true)
|
||||||
protected List<Inquiry> inquiries;
|
protected List<Inquiry> inquiries;
|
||||||
|
|
@ -27,4 +27,18 @@ public class Person {
|
||||||
}
|
}
|
||||||
return this.inquiries;
|
return this.inquiries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Inquiry currentInquiry;
|
||||||
|
|
||||||
|
public void createCurrentInquiry() {
|
||||||
|
currentInquiry = new Inquiry();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Inquiry getCurrentInquiry() {
|
||||||
|
return currentInquiry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizeInquiry() {
|
||||||
|
getInquiries().add(currentInquiry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_download;
|
package ru.nbch.credit_tracker.entities.external_response.online_download;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -24,5 +24,18 @@ public class Persons {
|
||||||
return this.persons;
|
return this.persons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Person currentPerson;
|
||||||
|
|
||||||
|
public void createCurrentPerson() {
|
||||||
|
currentPerson = new Person();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person getCurrentPerson() {
|
||||||
|
return currentPerson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizePerson() {
|
||||||
|
getPersons().add(currentPerson);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_download;
|
package ru.nbch.credit_tracker.entities.external_response.online_download;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_report;
|
package ru.nbch.credit_tracker.entities.external_response.online_report;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_report;
|
package ru.nbch.credit_tracker.entities.external_response.online_report;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_report;
|
package ru.nbch.credit_tracker.entities.external_response.online_report;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_report;
|
package ru.nbch.credit_tracker.entities.external_response.online_report;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.online_report;
|
package ru.nbch.credit_tracker.entities.external_response.online_report;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
|
|
||||||
package ru.nbch.credit_tracker.entities.request.monitoring_request;
|
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
|
||||||
@XmlType(name = "", propOrder = {
|
|
||||||
"userId",
|
|
||||||
"password",
|
|
||||||
"packageName",
|
|
||||||
"subjects"
|
|
||||||
})
|
|
||||||
@XmlRootElement(name = "MonitoringRequest")
|
|
||||||
public class MonitoringRequest {
|
|
||||||
|
|
||||||
@XmlElement(name = "UserId", required = true)
|
|
||||||
protected String userId;
|
|
||||||
@XmlElement(name = "Password", required = true)
|
|
||||||
protected String password;
|
|
||||||
@XmlElement(name = "PackageName", required = true)
|
|
||||||
protected String packageName;
|
|
||||||
@XmlElement(name = "Subjects", required = true)
|
|
||||||
protected Subjects subjects;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.request.active_packages;
|
package ru.nbch.credit_tracker.entities.user_request.active_packages;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
package ru.nbch.credit_tracker.entities.user_request.all_packages;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"userId",
|
||||||
|
"password"
|
||||||
|
})
|
||||||
|
@XmlRootElement(name = "MonitoringAllPackagesRequest")
|
||||||
|
public class MonitoringAllPackagesRequest {
|
||||||
|
|
||||||
|
@XmlElement(name = "UserId", required = true)
|
||||||
|
protected String userId;
|
||||||
|
@XmlElement(name = "Password", required = true)
|
||||||
|
protected String password;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
|
||||||
|
package ru.nbch.credit_tracker.entities.user_request.monitoring_request;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"userId",
|
||||||
|
"password",
|
||||||
|
"packageName",
|
||||||
|
"subjects"
|
||||||
|
})
|
||||||
|
@XmlRootElement(name = "MonitoringRequest")
|
||||||
|
public class MonitoringRequest {
|
||||||
|
|
||||||
|
@XmlElement(name = "UserId", required = true)
|
||||||
|
protected String userId;
|
||||||
|
@XmlElement(name = "Password", required = true)
|
||||||
|
protected String password;
|
||||||
|
@XmlElement(name = "PackageName", required = true)
|
||||||
|
protected String packageName;
|
||||||
|
@XmlElement(name = "Subjects", required = true)
|
||||||
|
protected Subjects subjects;
|
||||||
|
|
||||||
|
public Subjects getSubjects() {
|
||||||
|
if (subjects == null) {
|
||||||
|
subjects = new Subjects();
|
||||||
|
}
|
||||||
|
return subjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Subject currentSubject;
|
||||||
|
|
||||||
|
public void createCurrentSubject() {
|
||||||
|
currentSubject = new Subject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Subject getCurrentSubject() {
|
||||||
|
return currentSubject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizeSubject() {
|
||||||
|
getSubjects().getSubject().add(currentSubject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
package ru.nbch.credit_tracker.entities.request.monitoring_request;
|
package ru.nbch.credit_tracker.entities.user_request.monitoring_request;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.request.monitoring_request;
|
package ru.nbch.credit_tracker.entities.user_request.monitoring_request;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.active_packages;
|
package ru.nbch.credit_tracker.entities.user_response.active_packages;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.active_packages;
|
package ru.nbch.credit_tracker.entities.user_response.active_packages;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.active_packages;
|
package ru.nbch.credit_tracker.entities.user_response.active_packages;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.user_response.all_packages;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"status",
|
||||||
|
"membercode",
|
||||||
|
"packages"
|
||||||
|
})
|
||||||
|
@XmlRootElement(name = "MonitoringAllPackagesResponse")
|
||||||
|
public class MonitoringAllPackagesResponse {
|
||||||
|
|
||||||
|
@XmlElement(name = "Status", required = true)
|
||||||
|
protected String status;
|
||||||
|
@XmlElement(name = "Membercode", required = true)
|
||||||
|
protected String membercode;
|
||||||
|
@XmlElement(name = "Packages", required = true)
|
||||||
|
protected PackagesAll packages;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.user_response.all_packages;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
|
import jakarta.xml.bind.annotation.XmlType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"packageName",
|
||||||
|
"createdAt",
|
||||||
|
"status",
|
||||||
|
"deactivatedAt"
|
||||||
|
})
|
||||||
|
public class PackageAll {
|
||||||
|
|
||||||
|
@XmlElement(name = "PackageName", required = true)
|
||||||
|
protected String packageName;
|
||||||
|
@XmlElement(name = "CreatedAt", required = true)
|
||||||
|
protected String createdAt;
|
||||||
|
@XmlElement(name = "Status", required = false)
|
||||||
|
protected String status;
|
||||||
|
@XmlElement(name = "DeactivatedAt", required = false)
|
||||||
|
protected String deactivatedAt;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package ru.nbch.credit_tracker.entities.user_response.all_packages;
|
||||||
|
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import jakarta.xml.bind.annotation.XmlElement;
|
||||||
|
import jakarta.xml.bind.annotation.XmlType;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
@XmlType(name = "", propOrder = {
|
||||||
|
"packages"
|
||||||
|
})
|
||||||
|
public class PackagesAll {
|
||||||
|
|
||||||
|
@XmlElement(name = "Package", required = true)
|
||||||
|
protected List<PackageAll> packages;
|
||||||
|
|
||||||
|
public List<PackageAll> getPackages() {
|
||||||
|
if (packages == null) {
|
||||||
|
packages = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return this.packages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.errors;
|
package ru.nbch.credit_tracker.entities.user_response.errors;
|
||||||
|
|
||||||
public interface CommonError {
|
public interface CommonError {
|
||||||
void setStatus(String status);
|
void setStatus(String status);
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.errors;
|
package ru.nbch.credit_tracker.entities.user_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.errors;
|
package ru.nbch.credit_tracker.entities.user_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -17,9 +17,9 @@ public class MonitoringDownloadError implements CommonError {
|
||||||
|
|
||||||
@XmlElement(name = "Status", required = true)
|
@XmlElement(name = "Status", required = true)
|
||||||
protected String status;
|
protected String status;
|
||||||
@XmlElement(name = "ErrorCode",required = true)
|
@XmlElement(name = "Code",required = true)
|
||||||
protected String errorCode;
|
protected String errorCode;
|
||||||
@XmlElement(name = "ErrorText",required = true)
|
@XmlElement(name = "Message",required = true)
|
||||||
protected String errorText;
|
protected String errorText;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.errors;
|
package ru.nbch.credit_tracker.entities.user_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.errors;
|
package ru.nbch.credit_tracker.entities.user_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.errors;
|
package ru.nbch.credit_tracker.entities.user_response.errors;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -17,9 +17,9 @@ public class MonitoringReportListError implements CommonError {
|
||||||
|
|
||||||
@XmlElement(name = "Status", required = true)
|
@XmlElement(name = "Status", required = true)
|
||||||
protected String status;
|
protected String status;
|
||||||
@XmlElement(name = "ErrorCode",required = true)
|
@XmlElement(name = "Code",required = true)
|
||||||
protected String errorCode;
|
protected String errorCode;
|
||||||
@XmlElement(name = "ErrorText",required = true)
|
@XmlElement(name = "Message",required = true)
|
||||||
protected String errorText;
|
protected String errorText;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.monitoring_signal_response;
|
package ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -17,5 +17,5 @@ public class MonitoringSignalResponse {
|
||||||
@XmlElement(name = "PackageName", required = true)
|
@XmlElement(name = "PackageName", required = true)
|
||||||
protected String packageName;
|
protected String packageName;
|
||||||
@XmlElement(name = "Subjects", required = true)
|
@XmlElement(name = "Subjects", required = true)
|
||||||
protected Subjects subjects;
|
protected Subjects subjects = new Subjects();
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.monitoring_signal_response;
|
package ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.monitoring_signal_response;
|
package ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -24,4 +24,17 @@ public class Signals {
|
||||||
return this.signals;
|
return this.signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Signal currentSignal;
|
||||||
|
|
||||||
|
public void createCurrentSignal() {
|
||||||
|
currentSignal = new Signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Signal getCurrentSignal() {
|
||||||
|
return currentSignal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizeSignal() {
|
||||||
|
getSignals().add(currentSignal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
package ru.nbch.credit_tracker.entities.response.monitoring_signal_response;
|
package ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -30,7 +30,7 @@ public class Subject {
|
||||||
@XmlElement(name = "Flag90_12", required = true)
|
@XmlElement(name = "Flag90_12", required = true)
|
||||||
protected Integer flag9012;
|
protected Integer flag9012;
|
||||||
@XmlElement(name = "Signals", required = true)
|
@XmlElement(name = "Signals", required = true)
|
||||||
protected Signals signals;
|
protected Signals signals = new Signals();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.monitoring_signal_response;
|
package ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
@ -24,4 +24,18 @@ public class Subjects {
|
||||||
return this.subjects;
|
return this.subjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Subject currentSubject;
|
||||||
|
|
||||||
|
public void createCurrentSubject() {
|
||||||
|
currentSubject = new Subject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Subject getCurrentSubject() {
|
||||||
|
return currentSubject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalizeSubject() {
|
||||||
|
getSubjects().add(currentSubject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.success;
|
package ru.nbch.credit_tracker.entities.user_response.success;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.success;
|
package ru.nbch.credit_tracker.entities.user_response.success;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ru.nbch.credit_tracker.entities.response.success;
|
package ru.nbch.credit_tracker.entities.user_response.success;
|
||||||
|
|
||||||
import jakarta.xml.bind.annotation.*;
|
import jakarta.xml.bind.annotation.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
@ -11,7 +11,7 @@ import lombok.Setter;
|
||||||
"status",
|
"status",
|
||||||
})
|
})
|
||||||
@XmlRootElement(name = "MonitoringResponse")
|
@XmlRootElement(name = "MonitoringResponse")
|
||||||
public class MonitoringResponse {
|
public class MonitoringSetupResponse {
|
||||||
|
|
||||||
@XmlElement(name = "Status", required = true)
|
@XmlElement(name = "Status", required = true)
|
||||||
protected String status = "OK";
|
protected String status = "OK";
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class EnumKeyMessage {
|
||||||
|
private final IEnumKeyCode subject;
|
||||||
|
/**
|
||||||
|
* Параметры для подстановки в текст сообщения. Все Serializable.
|
||||||
|
* args not null.
|
||||||
|
*/
|
||||||
|
private Object[] args;
|
||||||
|
|
||||||
|
public EnumKeyMessage(IEnumKeyCode subject) {
|
||||||
|
this.subject = subject;
|
||||||
|
this.args = Collections.emptyList().toArray(new Object[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public EnumKeyMessage(IEnumKeyCode subject, Object... args) {
|
||||||
|
this.subject = subject;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumKeyCode getSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArgs(Object[] args) {
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "EnumKeyMessage{subject=" + subject + ", args: " + Arrays.toString(args) + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
102
src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java
Normal file
102
src/main/java/ru/nbch/credit_tracker/enums/IEnumKeyCode.java
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public interface IEnumKeyCode extends Serializable {
|
||||||
|
String getKey();
|
||||||
|
String getCode();
|
||||||
|
|
||||||
|
default boolean equalsByKey(String key) {
|
||||||
|
return key != null && getKey().equalsIgnoreCase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверяет что среди данного набора Enum, присутствует элемент с данным id
|
||||||
|
* id может быть null
|
||||||
|
*/
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean contains(String id, T... enumSet) {
|
||||||
|
for (T e : enumSet) {
|
||||||
|
if (Objects.equals(id, e.getKey()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean containsIgnoreCase(String id, T... enumSet) {
|
||||||
|
for (T e : enumSet) {
|
||||||
|
if (e.getKey() != null && e.getKey().equalsIgnoreCase(id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean contains(T e, T... enumSet) {
|
||||||
|
for (T enumEl : enumSet) {
|
||||||
|
if (enumEl.equals(e))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверяет что среди всех Enum данного класса, присутствует элемент с данным id
|
||||||
|
* id может быть null
|
||||||
|
*/
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> boolean contains(String key, Class<T> enumClass) {
|
||||||
|
for (T e : enumClass.getEnumConstants()) {
|
||||||
|
if (Objects.equals(key, e.getKey()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает Enum по id, если в заданном классе такой определен
|
||||||
|
* id может быть null
|
||||||
|
*
|
||||||
|
* @return Enum если нашел, иначе <tt>null</tt>
|
||||||
|
*/
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> T getEnumByKey(Class<T> enumClass, String key) {
|
||||||
|
for (T e : enumClass.getEnumConstants()) {
|
||||||
|
if (Objects.equals(key, e.getKey()))
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> T getEnumByKeyOrUndefined(Class<T> enumClass, String key) {
|
||||||
|
T enumByKey = getEnumByKey(enumClass, key);
|
||||||
|
return enumByKey == null ? getUndefined(enumClass) : enumByKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Enum<T> & IEnumKeyCode> T getUndefined(Class<T> enumClass) {
|
||||||
|
T enumByKey = getEnumByKey(enumClass, UNDEFINED_VALUE);
|
||||||
|
if (enumByKey == null) {
|
||||||
|
throw new IllegalArgumentException("Undefined value not found in enum " + enumClass);
|
||||||
|
}
|
||||||
|
return enumByKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean theSameAs(Object other) {
|
||||||
|
if (!(other instanceof IEnumKeyCode otherCasted)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.getKey().equalsIgnoreCase(otherCasted.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getErrorCode() {
|
||||||
|
String key = getKey();
|
||||||
|
String[] split = key.split("\\.");
|
||||||
|
if (split.length < 1) return null;
|
||||||
|
String s = split[split.length - 1];
|
||||||
|
if (!s.matches("\\d+")) return null;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getKeyOrNull(IEnumKeyCode enumVal) {
|
||||||
|
return enumVal == null ? null : enumVal.getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
String UNDEFINED_VALUE = "_Undefined";
|
||||||
|
}
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
package ru.nbch.credit_tracker.enums;
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
import lombok.Getter;
|
public enum SignalError implements IEnumKeyCode {
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum SignalError {
|
|
||||||
ERROR_001("001", "Ошибка распаковки архива"),
|
ERROR_001("001", "Ошибка распаковки архива"),
|
||||||
ERROR_002("002", "Отсутствует обязательный элемент: "),
|
ERROR_002("002", "Отсутствует обязательный элемент: {}"),
|
||||||
ERROR_003("003", "Элемент ClientId не соответствует формату XXXXXXXXX"),
|
ERROR_003("003", "Элемент ClientId не соответствует формату XXXXXXXXX. Id: {}"),
|
||||||
ERROR_004("004", "Указан неуникальный Id в пакете: "),
|
|
||||||
ERROR_005("005", "Неверный логин или пароль"),
|
ERROR_005("005", "Неверный логин или пароль"),
|
||||||
ERROR_006("006", "Доступ к услуге закрыт, обратитесь к курирующему менеджеру"),
|
ERROR_006("006", "Доступ к услуге закрыт, обратитесь к курирующему менеджеру"),
|
||||||
ERROR_007("007", "В системе уже существует пакет с таким именем"),
|
ERROR_007("007", "В системе уже существует пакет с таким именем"),
|
||||||
ERROR_008("008", "PackageName не соответствует допустимому формату"),
|
ERROR_008("008", "PackageName не соответствует допустимому формату"),
|
||||||
ERROR_009("009", "Превышен допустимый размер пакета"),
|
ERROR_009("009", "Превышен допустимый размер пакета"),
|
||||||
ERROR_010("010", "Идентификатор субъекта (Id) не соответствует допустимому формату"),
|
ERROR_010("010", "Идентификатор субъекта (Id) не соответствует допустимому формату: {}"),
|
||||||
ERROR_011("011", "Получен невалидный XML"),
|
ERROR_011("011", "Получен невалидный XML"),
|
||||||
ERROR_012("012", "Пакет не найден"),
|
ERROR_012("012", "Пакет {} не найден"),
|
||||||
ERROR_013("013", "На стороне сервиса произошла ошибка, попробуйте повторить запрос позже или сообщите в техническую поддержку"),
|
ERROR_013("013", "На стороне сервиса произошла ошибка, попробуйте повторить запрос позже или сообщите в техническую поддержку"),
|
||||||
ERROR_014("014", "Файл не найден"),
|
ERROR_014("014", "Файл с именем {} не найден "),
|
||||||
ERROR_015("015", "Клиент с указанным membercode не найден"),
|
ERROR_015("015", "У данного пользователя не найдено активных пакетов"),
|
||||||
ERROR_016("016", "Нет активного пакета с именем "),
|
ERROR_016("016", "Нет активного пакета с именем {}"),
|
||||||
ERROR_017("017", "При обработке запроса произошла ошибка. Повторите запрос позже или обратитесь в службу технической поддержки"), // TODO get rid of duplicate?
|
ERROR_017("017", "При обработке запроса произошла ошибка. Повторите запрос позже или обратитесь в службу технической поддержки"), // TODO get rid of duplicate?
|
||||||
|
ERROR_018("018", "Пакет {} находится в обработке. Дождитесь его установки на мониторинг и повторите попытку позже."),
|
||||||
|
ERROR_019("019", "У данного пользователя не найдено ни одного пакета"),
|
||||||
|
ERROR_020("020", "Пакет {} был отклонён при установке на мониторинг. Отчеты не формируются."),
|
||||||
|
ERROR_021("021", "Обработка пакета {} завершилась с ошибкой, отчёты недоступны. Обратитесь в техническую поддержку."),
|
||||||
|
ERROR_022("022", "Пакет {} снят с мониторинга, отчёты больше недоступны.");
|
||||||
|
|
||||||
ERROR_100("100", "Непредвиденная ошибка");
|
|
||||||
|
|
||||||
private final String code;
|
private final String code;
|
||||||
private final String message;
|
private final String message;
|
||||||
|
|
@ -31,4 +31,16 @@ public enum SignalError {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package ru.nbch.credit_tracker.enums;
|
||||||
|
|
||||||
|
public enum XmlErrorFormat {
|
||||||
|
MonitoringActivePackagesError,
|
||||||
|
MonitoringAllPackagesError,
|
||||||
|
MonitoringDownloadError,
|
||||||
|
MonitoringError,
|
||||||
|
MonitoringPackageDeleteError,
|
||||||
|
MonitoringReportListError
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package ru.nbch.credit_tracker.exceptions;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||||
|
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class SignalClientException extends SignalException {
|
||||||
|
|
||||||
|
private final String packageName;
|
||||||
|
|
||||||
|
public SignalClientException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat, String packageName) {
|
||||||
|
super(errorMessage, errorFormat);
|
||||||
|
this.packageName = packageName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.exceptions;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import ru.nbch.credit_tracker.entities.response.errors.CommonError;
|
|
||||||
import ru.nbch.credit_tracker.enums.SignalError;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public class SignalErrorException extends RuntimeException {
|
|
||||||
|
|
||||||
private final boolean isUserError;
|
|
||||||
private final CommonError error;
|
|
||||||
|
|
||||||
public SignalErrorException(SignalError signalError, String tag, CommonError error, boolean isUserError) {
|
|
||||||
this.isUserError = isUserError;
|
|
||||||
this.error = createErrorMessage(error, signalError, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CommonError createErrorMessage(CommonError errorMessage, SignalError error, String tag) {
|
|
||||||
errorMessage.setStatus("error");
|
|
||||||
errorMessage.setErrorCode(error.getCode());
|
|
||||||
if (tag != null) {
|
|
||||||
errorMessage.setErrorText(error.getMessage() + " " + tag);
|
|
||||||
} else {
|
|
||||||
errorMessage.setErrorText(error.getMessage());
|
|
||||||
}
|
|
||||||
return errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ru.nbch.credit_tracker.exceptions;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||||
|
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class SignalException extends RuntimeException {
|
||||||
|
private final EnumKeyMessage errorMessage;
|
||||||
|
private final XmlErrorFormat errorFormat;
|
||||||
|
|
||||||
|
public SignalException(EnumKeyMessage errorMessage,
|
||||||
|
XmlErrorFormat errorFormat) {
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
this.errorFormat = errorFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ru.nbch.credit_tracker.exceptions;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import ru.nbch.credit_tracker.enums.EnumKeyMessage;
|
||||||
|
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class SignalServerException extends SignalException {
|
||||||
|
|
||||||
|
private final Exception cause;
|
||||||
|
|
||||||
|
public SignalServerException(EnumKeyMessage errorMessage, XmlErrorFormat errorFormat, Exception cause) {
|
||||||
|
super(errorMessage, errorFormat);
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,145 +1,154 @@
|
||||||
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.request.active_packages.MonitoringActivePackagesRequest;
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
import ru.nbch.credit_tracker.entities.user_request.active_packages.MonitoringActivePackagesRequest;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
import ru.nbch.credit_tracker.entities.user_request.all_packages.MonitoringAllPackagesRequest;
|
||||||
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.entities.response.errors.*;
|
import ru.nbch.credit_tracker.entities.user_response.active_packages.MonitoringActivePackagesResponse;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse;
|
import ru.nbch.credit_tracker.entities.user_response.active_packages.Package;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringReportListResponse;
|
import ru.nbch.credit_tracker.entities.user_response.active_packages.Packages;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringResponse;
|
import ru.nbch.credit_tracker.entities.user_response.all_packages.MonitoringAllPackagesResponse;
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
import ru.nbch.credit_tracker.entities.user_response.all_packages.PackageAll;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.all_packages.PackagesAll;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringPackageDeleteResponse;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringReportListResponse;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.success.MonitoringSetupResponse;
|
||||||
import ru.nbch.credit_tracker.enums.SignalError;
|
import ru.nbch.credit_tracker.enums.SignalError;
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
import ru.nbch.credit_tracker.exceptions.SignalErrorException;
|
import ru.nbch.credit_tracker.enums.XmlErrorFormat;
|
||||||
|
import ru.nbch.credit_tracker.exceptions.SignalClientException;
|
||||||
|
import ru.nbch.credit_tracker.service.MonitoringErrorProcesingService;
|
||||||
import ru.nbch.credit_tracker.service.SignalService;
|
import ru.nbch.credit_tracker.service.SignalService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
|
||||||
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
import ru.nbch.credit_tracker.service.scoring.AuthorizationService;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
import ru.nbch.credit_tracker.utils.ValidationUtil;
|
import ru.nbch.credit_tracker.utils.ValidationService;
|
||||||
|
import ru.nbch.credit_tracker.utils.ZipUtils;
|
||||||
|
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashSet;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.clientExcp;
|
||||||
|
import static ru.nbch.credit_tracker.utils.error.ExceptionUtils.serverExcp;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||||
public class SignalFacade {
|
public class SignalFacade {
|
||||||
private static final long MAX_XML_FILE_SIZE = 2L * 1024 * 1024 * 1024;
|
|
||||||
|
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 XmlUtilService xmlUtilService;
|
private final MonitoringErrorProcesingService monitoringErrorProcesingService;
|
||||||
|
private final ValidationService validationService;
|
||||||
|
private final StaxXmlProcessor staxXmlProcessor;
|
||||||
|
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
private final long maxXmlFileSize;
|
||||||
|
|
||||||
|
|
||||||
public SignalFacade(CreditTrackerSettings config,
|
public SignalFacade(CreditTrackerSettings config,
|
||||||
AuthorizationService authorizationService,
|
AuthorizationService authorizationService,
|
||||||
SignalService signalService,
|
SignalService signalService,
|
||||||
SignalRestService signalRestService,
|
SignalRestService signalRestService,
|
||||||
XmlUtilService xmlUtilService,
|
MonitoringErrorProcesingService monitoringErrorProcesingService,
|
||||||
|
ValidationService validationService,
|
||||||
|
StaxXmlProcessor staxXmlProcessor,
|
||||||
@Qualifier("executorService") ExecutorService executor) {
|
@Qualifier("executorService") ExecutorService executor) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.authorizationService = authorizationService;
|
this.authorizationService = authorizationService;
|
||||||
this.signalService = signalService;
|
this.signalService = signalService;
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
this.xmlUtilService = xmlUtilService;
|
this.monitoringErrorProcesingService = monitoringErrorProcesingService;
|
||||||
|
this.validationService = validationService;
|
||||||
|
this.staxXmlProcessor = staxXmlProcessor;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
|
this.maxXmlFileSize = config.getMaxXmlFileSize() * 1024 * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<MonitoringResponse> setupMonitoring(MultipartFile file) {
|
public ResponseEntity<MonitoringSetupResponse> setupMonitoring(MultipartFile file) {
|
||||||
// первичные валидации
|
// первичные валидации
|
||||||
if (file.isEmpty()) {
|
if (file.isEmpty() || !isZipFile(file)) {
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||||
}
|
|
||||||
|
|
||||||
if (!isZipFile(file)) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Валидация Архива на количетсво файлов, размер и расширение
|
// Валидация Архива на количетсво файлов, размер и расширение
|
||||||
try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
|
||||||
int fileCount = 0;
|
|
||||||
ZipEntry xmlEntry = null;
|
|
||||||
|
|
||||||
ZipEntry entry = zipInputStream.getNextEntry();
|
|
||||||
while (entry != null) {
|
|
||||||
if (!entry.isDirectory()) {
|
|
||||||
fileCount++;
|
|
||||||
if (fileCount > 1) { // Архив должен содержать ровно один XML-файл
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!entry.getName().toLowerCase().endsWith(".xml")) { // Файл должен быть с расширением xml
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlEntry = entry;
|
|
||||||
} else {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true); // Архив должен содержать ровно один XML-файл. Никаких доп директорий
|
|
||||||
}
|
|
||||||
zipInputStream.closeEntry();
|
|
||||||
entry = zipInputStream.getNextEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileCount == 0) { // Архив должен содержать ровно один XML-файл
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_001, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xmlEntry.getSize() > MAX_XML_FILE_SIZE) { // максимально 2 Гб до запаковки
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_009, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (e instanceof SignalErrorException) {
|
|
||||||
throw (SignalErrorException) e;
|
|
||||||
}
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Теперь знаем, что в архиве лежит ровно один файл с раширением xml и он весит меньше 2гб. Можно валидировать сам xml
|
|
||||||
// Пробуем распарсить xml
|
|
||||||
MonitoringRequest monitoringRequest;
|
MonitoringRequest monitoringRequest;
|
||||||
Integer packageId;
|
Long packageId;
|
||||||
try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
|
ZipInputStream zipInputStream = null;
|
||||||
|
String filePath;
|
||||||
|
try {
|
||||||
|
zipInputStream = new ZipInputStream(file.getInputStream());
|
||||||
|
Optional<ZipEntry> xmlFileEntry = ZipUtils.extractValidEntry(zipInputStream);
|
||||||
|
if (xmlFileEntry.isEmpty()) {
|
||||||
|
throw clientExcp(SignalError.ERROR_001, XmlErrorFormat.MonitoringError);
|
||||||
|
}
|
||||||
|
if (xmlFileEntry.get().getSize() > maxXmlFileSize) {
|
||||||
|
throw clientExcp(SignalError.ERROR_009, XmlErrorFormat.MonitoringError);
|
||||||
|
}
|
||||||
|
|
||||||
|
zipInputStream.close();
|
||||||
|
zipInputStream = new ZipInputStream(file.getInputStream());
|
||||||
zipInputStream.getNextEntry();
|
zipInputStream.getNextEntry();
|
||||||
|
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
filePath = writeTmpFile(zipInputStream);
|
||||||
monitoringRequest = processor.read(zipInputStream, MonitoringRequest.class);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), e);
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringError, e);
|
||||||
throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false);
|
} finally {
|
||||||
|
if (zipInputStream != null) {
|
||||||
|
try {
|
||||||
|
zipInputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringError, e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// валидация xml
|
// валидация xml
|
||||||
try {
|
try {
|
||||||
validateMonitoringRequest(monitoringRequest);
|
monitoringRequest = readAndValidateMonitoringRequest(filePath);
|
||||||
} catch (SignalErrorException e) {
|
} catch (Exception e) {
|
||||||
signalService.rejectPackage(monitoringRequest);
|
CTUtil.removeFile(filePath);
|
||||||
throw e;
|
if (e.getCause() instanceof XMLStreamException) {
|
||||||
|
throw clientExcp(SignalError.ERROR_011, XmlErrorFormat.MonitoringError);
|
||||||
|
}
|
||||||
|
if (e instanceof SignalClientException) {
|
||||||
|
throw (SignalClientException) e;
|
||||||
|
}
|
||||||
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringError, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -147,99 +156,101 @@ public class SignalFacade {
|
||||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword());
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(monitoringRequest.getUserId(), monitoringRequest.getPassword());
|
||||||
if (!authResult.isSuccess()) {
|
if (!authResult.isSuccess()) {
|
||||||
signalService.rejectPackage(monitoringRequest);
|
signalService.rejectPackage(monitoringRequest);
|
||||||
throw new SignalErrorException(authResult.getError(), null, new MonitoringError(), true);
|
throw clientExcp(authResult.getError(), monitoringRequest.getPackageName(), XmlErrorFormat.MonitoringError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// проверка на уникальность пакета
|
// проверка на уникальность пакета
|
||||||
if (signalService.isPackageNotUnique(monitoringRequest)) {
|
if (signalService.isPackageNotUnique(monitoringRequest)) {
|
||||||
signalService.rejectPackage(monitoringRequest);
|
signalService.rejectPackage(monitoringRequest);
|
||||||
throw new SignalErrorException(SignalError.ERROR_007, null, new MonitoringError(), true);
|
throw clientExcp(SignalError.ERROR_007, monitoringRequest.getPackageName(), XmlErrorFormat.MonitoringError);
|
||||||
}
|
}
|
||||||
|
|
||||||
packageId = signalService.registerPackage(monitoringRequest);
|
packageId = signalService.registerPackage(monitoringRequest);
|
||||||
|
log.info("Package registered. PackageId {}. Status: {}", packageId, Status.PROCESSING.name());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
CTUtil.removeFile(filePath);
|
||||||
throw (SignalErrorException) e;
|
if (e instanceof SignalClientException) {
|
||||||
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), e);
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringError, e);
|
||||||
throw new SignalErrorException(SignalError.ERROR_100, null, new MonitoringError(), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// в отдельном потоке запускаем поиск фидов и расчет флагов просрочек
|
// в отдельном потоке запускаем регистрацию субъектов, поиск фидов и расчет флагов просрочек
|
||||||
registerFidsAndDebts(packageId, monitoringRequest.getPackageName());
|
getCurrentProxy().registerFidsAndDebts(packageId, monitoringRequest.getPackageName(), filePath);
|
||||||
|
|
||||||
return ResponseEntity.ok().body(new MonitoringResponse());
|
return ResponseEntity.ok().body(new MonitoringSetupResponse());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateMonitoringRequest(MonitoringRequest request) throws SignalErrorException {
|
private MonitoringRequest readAndValidateMonitoringRequest(String filePath) {
|
||||||
if (request == null) {
|
MonitoringRequest monitoringRequest;
|
||||||
throw new SignalErrorException(SignalError.ERROR_011, null, new MonitoringError(), true);
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(filePath)), 8 * 1024 * 1024)) {
|
||||||
}
|
monitoringRequest = staxXmlProcessor.read(in, MonitoringRequest.class,
|
||||||
|
request -> {
|
||||||
validateReruqredTags(request);
|
|
||||||
|
|
||||||
validateTagsTypes(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateReruqredTags(MonitoringRequest request) throws SignalErrorException {
|
|
||||||
if (request.getUserId() == null) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_002, "UserId", new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.getPackageName() == null) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_002, "PackageName", new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.getPassword() == null) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_002, "Password", new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.getSubjects() == null) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_002, "Subjects", new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.getSubjects().getSubject().isEmpty()) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_002, "Subject", new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateTagsTypes(MonitoringRequest request) throws SignalErrorException {
|
|
||||||
if (!ValidationUtil.validatePackageName(request.getPackageName())) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_008, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> uniqueIds = new HashSet<>();
|
|
||||||
for (Subject subject : request.getSubjects().getSubject()) {
|
|
||||||
if (!ValidationUtil.validatePhone(subject.getClientId())) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_003, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
if (!ValidationUtil.validateNPId(subject.getId())) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_010, null, new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
// проверка на уникальность Id внутри одного пакета
|
|
||||||
if (!uniqueIds.add(subject.getId())) {
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_004, subject.getId(), new MonitoringError(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerFidsAndDebts(Integer packageId, String packageName) {
|
|
||||||
executor.execute(() -> {
|
|
||||||
try {
|
try {
|
||||||
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.registerSubjectsFidAndDebts(packageId);
|
validationService.validateMonitoringRequest(request);
|
||||||
if (!phoneFidsData.isEmpty()) {
|
} catch (SignalClientException e) {
|
||||||
Signals signals = signalService.buildSignals(packageId, phoneFidsData);
|
if (request != null) {
|
||||||
// TODO validate xsd?
|
signalService.rejectPackage(request);
|
||||||
if (signalRestService.update(signals)) {
|
}
|
||||||
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}", packageId, packageName);
|
request = null;
|
||||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
throw e;
|
||||||
|
}
|
||||||
|
request.getSubjects().getSubject().clear();
|
||||||
|
},
|
||||||
|
request -> request.getSubjects().getSubject().isEmpty()
|
||||||
|
,
|
||||||
|
40000, "/MonitoringRequest/Subjects/Subject");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error while parsing and validating monitoring request", e);
|
||||||
|
}
|
||||||
|
return monitoringRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String writeTmpFile(ZipInputStream zipInputStream) throws IOException {
|
||||||
|
String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator;
|
||||||
|
String filePath = folderPath + UUID.randomUUID() + "monitoring_request.xml";
|
||||||
|
CTUtil.createFolder(folderPath);
|
||||||
|
|
||||||
|
try (OutputStream out = Files.newOutputStream(Path.of(filePath))) {
|
||||||
|
|
||||||
|
byte[] buffer = new byte[8 * 1024 * 1024];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = zipInputStream.read(buffer)) > 0) {
|
||||||
|
out.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SetAndClearMdc(argIndex = 1)
|
||||||
|
public void registerFidsAndDebts(Long packageId, String packageName, String filePath) {
|
||||||
|
Map<String, String> context = MDC.getCopyOfContextMap();
|
||||||
|
executor.execute(() -> {
|
||||||
|
if (context != null) {
|
||||||
|
MDC.setContextMap(context);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
signalService.registerSubjects(filePath, packageId);
|
||||||
|
CTUtil.removeFile(filePath);
|
||||||
|
SignalService.UpdateResult updateResult = signalService.updateSubjects(packageId, null);
|
||||||
|
if (updateResult.isNoFidsFound()) {
|
||||||
|
log.info("No fids found for PackageId: {} PackageName: {}. Package status ON_MONITORING. No registration in signal service.", packageId, packageName);
|
||||||
|
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (signalRestService.setupMonitoring(packageId)) {
|
||||||
|
LocalDateTime monitoringAt = LocalDateTime.now();
|
||||||
|
log.info("Package was successfully registered in signal service. PackageId: {} PackageName: {}, MonitoringAt: {}", packageId, packageName, monitoringAt);
|
||||||
|
signalService.updatePackageOnMonitoringSuccess(packageId, monitoringAt);
|
||||||
|
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);
|
||||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
CTUtil.removeFile(filePath);
|
||||||
|
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||||
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -255,46 +266,111 @@ public class SignalFacade {
|
||||||
try {
|
try {
|
||||||
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(activePackagesRequest.getUserId(), activePackagesRequest.getPassword());
|
||||||
if (!authResult.isSuccess()) {
|
if (!authResult.isSuccess()) {
|
||||||
throw new SignalErrorException(authResult.getError(), null, new MonitoringActivePackagesError(), true);
|
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringActivePackagesError);
|
||||||
}
|
}
|
||||||
MonitoringActivePackagesResponse response = signalService.findActivePackages(activePackagesRequest.getUserId());
|
List<UserPackage> activePackages = signalService.findActivePackages(activePackagesRequest.getUserId());
|
||||||
if (response != null) {
|
|
||||||
|
if (!activePackages.isEmpty()) {
|
||||||
|
MonitoringActivePackagesResponse response = new MonitoringActivePackagesResponse();
|
||||||
|
response.setStatus("OK");
|
||||||
|
response.setMembercode(activePackagesRequest.getUserId().substring(0, 6));
|
||||||
|
Packages packages = new Packages();
|
||||||
|
activePackages.forEach(data -> {
|
||||||
|
Package pack = new Package();
|
||||||
|
pack.setPackageName(data.getPackageName());
|
||||||
|
pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null);
|
||||||
|
packages.getPackages().add(pack);
|
||||||
|
});
|
||||||
|
response.setPackages(packages);
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
} else {
|
} else {
|
||||||
throw new SignalErrorException(SignalError.ERROR_015, null, new MonitoringActivePackagesError(), true);
|
throw clientExcp(SignalError.ERROR_015, XmlErrorFormat.MonitoringActivePackagesError);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), e);
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringActivePackagesError, e);
|
||||||
throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringActivePackagesError(), false);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseEntity<MonitoringAllPackagesResponse> findAllPackages(MonitoringAllPackagesRequest allPackagesRequest) {
|
||||||
|
try {
|
||||||
|
AuthorizationService.AuthResult authResult = authorizationService.findAuthInfo(allPackagesRequest.getUserId(), allPackagesRequest.getPassword());
|
||||||
|
if (!authResult.isSuccess()) {
|
||||||
|
throw clientExcp(authResult.getError(), XmlErrorFormat.MonitoringAllPackagesError);
|
||||||
|
}
|
||||||
|
List<UserPackage> activePackages = signalService.findAllPackages(allPackagesRequest.getUserId());
|
||||||
|
|
||||||
|
if (!activePackages.isEmpty()) {
|
||||||
|
MonitoringAllPackagesResponse response = new MonitoringAllPackagesResponse();
|
||||||
|
response.setStatus("OK");
|
||||||
|
response.setMembercode(allPackagesRequest.getUserId().substring(0, 6));
|
||||||
|
PackagesAll packages = new PackagesAll();
|
||||||
|
activePackages.forEach(data -> {
|
||||||
|
PackageAll pack = new PackageAll();
|
||||||
|
pack.setPackageName(data.getPackageName());
|
||||||
|
pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null);
|
||||||
|
pack.setStatus(data.getStatus());
|
||||||
|
if (data.getStatus().equals(Status.DELETED.name())) {
|
||||||
|
pack.setDeactivatedAt(data.getDeactivatedAt() != null ? data.getDeactivatedAt().toString() : null);
|
||||||
|
}
|
||||||
|
packages.getPackages().add(pack);
|
||||||
|
});
|
||||||
|
response.setPackages(packages);
|
||||||
|
return ResponseEntity.ok(response);
|
||||||
|
} else {
|
||||||
|
throw clientExcp(SignalError.ERROR_019, XmlErrorFormat.MonitoringAllPackagesError);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (e instanceof SignalClientException) {
|
||||||
|
throw (SignalClientException) e;
|
||||||
|
}
|
||||||
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringAllPackagesError, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<MonitoringPackageDeleteResponse> deletePackage(String username, String packageName) {
|
public ResponseEntity<MonitoringPackageDeleteResponse> deletePackage(String username, String packageName) {
|
||||||
try {
|
try {
|
||||||
if (!signalService.isPackageExists(username, packageName)) {
|
if (!signalService.isPackageExists(username, packageName)) {
|
||||||
throw new SignalErrorException(SignalError.ERROR_016, packageName, new MonitoringPackageDeleteError(), true);
|
throw clientExcp(SignalError.ERROR_016, XmlErrorFormat.MonitoringPackageDeleteError, packageName);
|
||||||
}
|
}
|
||||||
MonitoringPackageDeleteResponse response = signalService.deletePackage(username, packageName);
|
|
||||||
|
LocalDateTime deactivatedAt = LocalDateTime.now();
|
||||||
|
signalService.deletePackage(username, packageName, deactivatedAt);
|
||||||
|
|
||||||
|
MonitoringPackageDeleteResponse response = new MonitoringPackageDeleteResponse();
|
||||||
|
response.setStatus("Deleted");
|
||||||
|
response.setPackageName(packageName);
|
||||||
|
response.setDeactivatedAt(deactivatedAt.toString());
|
||||||
|
|
||||||
signalRestService.deletePackage(username, packageName);
|
signalRestService.deletePackage(username, packageName);
|
||||||
log.info("Package {} deleted", packageName);
|
log.info("Package {} deleted", packageName);
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), e);
|
throw serverExcp(SignalError.ERROR_017, XmlErrorFormat.MonitoringPackageDeleteError, e);
|
||||||
throw new SignalErrorException(SignalError.ERROR_017, null, new MonitoringPackageDeleteError(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<MonitoringReportListResponse> getReportList(String username, String packageName) {
|
public ResponseEntity<MonitoringReportListResponse> getReportList(String username, String packageName) {
|
||||||
try {
|
try {
|
||||||
if (!signalService.isPackageExists(username, packageName)) {
|
if (signalService.isPackagesByStatusExist(username, packageName, Status.PROCESSING)) {
|
||||||
throw new SignalErrorException(SignalError.ERROR_016, packageName, new MonitoringReportListError(), true);
|
throw clientExcp(SignalError.ERROR_018, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||||
|
}
|
||||||
|
if (signalService.isPackagesByStatusExist(username, packageName, Status.REJECTED)) {
|
||||||
|
throw clientExcp(SignalError.ERROR_020, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||||
|
}
|
||||||
|
if (signalService.isPackagesByStatusExist(username, packageName, Status.ERROR)) {
|
||||||
|
throw clientExcp(SignalError.ERROR_021, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||||
|
}
|
||||||
|
if (signalService.isPackagesByStatusExist(username, packageName, Status.DELETED)) {
|
||||||
|
throw clientExcp(SignalError.ERROR_022, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||||
|
}
|
||||||
|
if (!signalService.isPackagesByStatusExist(username, packageName, Status.ON_MONITORING)) {
|
||||||
|
throw clientExcp(SignalError.ERROR_012, XmlErrorFormat.MonitoringReportListError, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
String memberCode = username.substring(0, 6);
|
String memberCode = username.substring(0, 6);
|
||||||
|
|
@ -302,42 +378,35 @@ public class SignalFacade {
|
||||||
String dirPath = config.getLoadDir() + File.separator + memberCode;
|
String dirPath = config.getLoadDir() + File.separator + memberCode;
|
||||||
File folder = new File(dirPath);
|
File folder = new File(dirPath);
|
||||||
|
|
||||||
if (folder.exists() && folder.isDirectory()) {
|
|
||||||
MonitoringReportListResponse.Reports reports = new MonitoringReportListResponse.Reports();
|
MonitoringReportListResponse.Reports reports = new MonitoringReportListResponse.Reports();
|
||||||
|
if (folder.exists() && folder.isDirectory()) {
|
||||||
File[] files = folder.listFiles();
|
File[] files = folder.listFiles();
|
||||||
if (files == null) {
|
if (files != null) {
|
||||||
throw new SignalErrorException(SignalError.ERROR_012, packageName, new MonitoringReportListError(), true);
|
|
||||||
}
|
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
if (file.isFile() && file.getName().startsWith(filePrefix)) {
|
if (file.isFile() && file.getName().startsWith(filePrefix)) {
|
||||||
reports.getReports().add(file.getName());
|
reports.getReports().add(file.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (reports.getReports().isEmpty()) {
|
}
|
||||||
throw new SignalErrorException(SignalError.ERROR_012, packageName, new MonitoringReportListError(), true);
|
|
||||||
} else {
|
|
||||||
MonitoringReportListResponse response = new MonitoringReportListResponse();
|
MonitoringReportListResponse response = new MonitoringReportListResponse();
|
||||||
response.setPackageName(packageName);
|
response.setPackageName(packageName);
|
||||||
response.setReports(reports);
|
response.setReports(reports);
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.error("Пакет {} был найден в бд для memberCode {}, но ни одного архива не было найдено в папке {}", packageName, username, dirPath);
|
|
||||||
throw new SignalErrorException(SignalError.ERROR_013, packageName, new MonitoringReportListError(), true);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), e);
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringReportListError, e);
|
||||||
throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringReportListError(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseEntity<Resource> downloadFile(String fileName) {
|
public ResponseEntity<Resource> downloadFile(String fileName) {
|
||||||
try {
|
try {
|
||||||
String memberCode = CTUtil.getMemberCodeFromFileName(fileName);
|
String memberCode = CTUtil.getMemberCodeFromFileName(fileName);
|
||||||
|
if (memberCode == null) {
|
||||||
|
throw clientExcp(SignalError.ERROR_014, XmlErrorFormat.MonitoringDownloadError, fileName);
|
||||||
|
}
|
||||||
String dirPath = config.getLoadDir() + File.separator + memberCode;
|
String dirPath = config.getLoadDir() + File.separator + memberCode;
|
||||||
File folder = new File(dirPath);
|
File folder = new File(dirPath);
|
||||||
|
|
||||||
|
|
@ -347,15 +416,21 @@ public class SignalFacade {
|
||||||
return ResponseEntity.ok().body(new FileUrlResource(file.getPath()));
|
return ResponseEntity.ok().body(new FileUrlResource(file.getPath()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new SignalErrorException(SignalError.ERROR_014, null, new MonitoringDownloadError(), true);
|
throw clientExcp(SignalError.ERROR_014, XmlErrorFormat.MonitoringDownloadError, fileName);
|
||||||
}
|
}
|
||||||
throw new SignalErrorException(SignalError.ERROR_014, null, new MonitoringDownloadError(), true);
|
throw clientExcp(SignalError.ERROR_014, XmlErrorFormat.MonitoringDownloadError, fileName);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof SignalErrorException) {
|
if (e instanceof SignalClientException) {
|
||||||
throw (SignalErrorException) e;
|
throw (SignalClientException) e;
|
||||||
}
|
}
|
||||||
log.error(e.getMessage(), e);
|
throw serverExcp(SignalError.ERROR_013, XmlErrorFormat.MonitoringDownloadError, e);
|
||||||
throw new SignalErrorException(SignalError.ERROR_013, null, new MonitoringDownloadError(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SignalFacade getCurrentProxy() {
|
||||||
|
if (self == null) {
|
||||||
|
self = (SignalFacade) AopContext.currentProxy();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package ru.nbch.credit_tracker.mapper.signal;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface HitsMapper {
|
||||||
|
|
||||||
|
void insertHits(@Param("hits") List<Hit> hits);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ru.nbch.credit_tracker.mapper.signal;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.Subject;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PhoneFidMapMapper {
|
||||||
|
|
||||||
|
void registerSubjects(@Param("subjects") List<Subject> subjects, @Param("packageId") Long packageId);
|
||||||
|
|
||||||
|
List<PhoneFidMap> findFullPhoneFidMap(@Param("packageId") Long packageId, @Param("offset") int offset, @Param("limit") int limit);
|
||||||
|
|
||||||
|
void updatePhoneFidMaps(@Param("subjects") List<PhoneFidMap> subjects);
|
||||||
|
|
||||||
|
void updatePhoneFidMapsErrors(@Param("subjects") List<PhoneFidMap> subjects);
|
||||||
|
|
||||||
|
PhoneFidMap findPhoneFidMapById(@Param("id") Long packageId);
|
||||||
|
|
||||||
|
boolean hasNonNullFids(@Param("packageId") Long packageId);
|
||||||
|
boolean hasOldRow(@Param("packageId") Long packageId, @Param("daysCount") Integer daysCount);
|
||||||
|
}
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
package ru.nbch.credit_tracker.mapper.signal;
|
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.HitsData;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mapper
|
|
||||||
public interface SignalMapper {
|
|
||||||
|
|
||||||
boolean isPackageNotUnique(@Param("userId") String userId, @Param("packageName") String packageName);
|
|
||||||
|
|
||||||
boolean isPackageExists(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String status);
|
|
||||||
|
|
||||||
void deletePackage(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String newStatus, @Param("previousStatus") String previousStatus, @Param("deactivatedAt") LocalDateTime deactivatedAt);
|
|
||||||
|
|
||||||
Integer registerPackage(@Param("request") MonitoringRequest request, @Param("creadedAt") LocalDateTime creadedAt, @Param("status") String status);
|
|
||||||
|
|
||||||
void registerSubjects(@Param("subjects") List<Subject> subjects, @Param("packageId") Integer packageId);
|
|
||||||
|
|
||||||
void insertPackage(@Param("request") MonitoringRequest request, @Param("creadedAt") LocalDateTime creadedAt, @Param("status") String status);
|
|
||||||
|
|
||||||
void registerSubjectsFidAndDebts(@Param("id") Integer id, @Param("fid") Integer fid, @Param("flagDebt5000") Integer flagDebt5000, @Param("flag90") Integer flag90, @Param("calculatedAt") LocalDateTime calculatedAt);
|
|
||||||
|
|
||||||
void setPackageStatus(@Param("packageId") Integer packageId, @Param("status") String status);
|
|
||||||
|
|
||||||
List<SubjectData> findSubjectsData(@Param("packageId") Integer packageId);
|
|
||||||
|
|
||||||
List<SubjectData> findFullSubjectsData(@Param("packageId") Integer packageId);
|
|
||||||
|
|
||||||
PackageData findPackageData(@Param("id") Integer id);
|
|
||||||
|
|
||||||
List<PackageData> findPackageDataList(@Param("userId") String userId, @Param("status") String status);
|
|
||||||
|
|
||||||
List<PackageData> findPackagesByStatus(@Param("status") String status);
|
|
||||||
|
|
||||||
void setHits(@Param("hits") List<HitsData> hits);
|
|
||||||
|
|
||||||
void updateSubjects(@Param("subjects") List<SubjectData> subjects);
|
|
||||||
|
|
||||||
void setPackageLastDownloadedReport(@Param("id") Integer id, @Param("fileName") String fileName);
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package ru.nbch.credit_tracker.mapper.signal;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserPackageMapper {
|
||||||
|
|
||||||
|
boolean isPackageNotUnique(@Param("userId") String userId, @Param("packageName") String packageName);
|
||||||
|
|
||||||
|
boolean isPackageExists(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String status);
|
||||||
|
|
||||||
|
boolean hasActivePackages(@Param("userId") String userId, @Param("packageName") String packageName, @Param("statuses") List<String> statuses);
|
||||||
|
|
||||||
|
void deletePackage(@Param("userId") String userId, @Param("packageName") String packageName, @Param("status") String newStatus, @Param("previousStatus") String previousStatus, @Param("deactivatedAt") LocalDateTime deactivatedAt);
|
||||||
|
|
||||||
|
Long insertPackage(@Param("userPackage") UserPackage userPackage);
|
||||||
|
|
||||||
|
void updatePackageStatus(@Param("packageId") Long packageId, @Param("status") String status);
|
||||||
|
|
||||||
|
void updatePackageLastDownloadedReport(@Param("id") Long id, @Param("fileName") String fileName);
|
||||||
|
|
||||||
|
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> findAllPackagesByStatus(@Param("status") String status);
|
||||||
|
|
||||||
|
List<UserPackage> findAllPackagesByUserId(@Param("userId") String userId);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.aop.framework.AopContext;
|
||||||
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
|
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.service.signal.SignalRestService;
|
||||||
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||||
|
public class MonitoringErrorProcesingService {
|
||||||
|
|
||||||
|
private MonitoringErrorProcesingService self;
|
||||||
|
|
||||||
|
private final SignalService signalService;
|
||||||
|
private final SignalRestService signalRestService;
|
||||||
|
|
||||||
|
public MonitoringErrorProcesingService(SignalService signalService, SignalRestService signalRestService) {
|
||||||
|
this.signalService = signalService;
|
||||||
|
this.signalRestService = signalRestService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void findErrors(Long packageId) {
|
||||||
|
UserPackage userPackage = signalService.findPackage(packageId);
|
||||||
|
getCurrentProxy().processPackage(userPackage, packageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SetAndClearMdc
|
||||||
|
public void processPackage(UserPackage userPackage, Long packageId) {
|
||||||
|
if (userPackage != null) {
|
||||||
|
String packCode = userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName();
|
||||||
|
log.info("Проверка на ошибки при постановке на мониторинг. packCode={}, packageId={}", packCode, packageId);
|
||||||
|
String fileName = signalRestService.getErrorFileName(packageId, packCode);
|
||||||
|
if (StringUtils.isNotBlank(fileName)) {
|
||||||
|
String filePath = signalRestService.loadErrorFile(packageId, fileName);
|
||||||
|
if (StringUtils.isNotBlank(filePath)) {
|
||||||
|
try {
|
||||||
|
signalService.updateSubjectsErrors(filePath, packageId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Ошибка при записи сообщений об ошибках в сформированных субъектах для мониторинга. Package_id = {}", packageId, e);
|
||||||
|
}
|
||||||
|
CTUtil.removeFile(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MonitoringErrorProcesingService getCurrentProxy() {
|
||||||
|
if (self == null) {
|
||||||
|
self = (MonitoringErrorProcesingService) AopContext.currentProxy();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,129 +1,213 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.MDC;
|
||||||
|
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;
|
||||||
import ru.nbch.credit_tracker.entities.dto.HitsData;
|
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.entities.response.monitoring_signal_response.*;
|
import ru.nbch.credit_tracker.entities.external_response.online_download.Inquiry;
|
||||||
import ru.nbch.credit_tracker.entities.response.online_download.Inquiry;
|
import ru.nbch.credit_tracker.entities.external_response.online_download.Person;
|
||||||
import ru.nbch.credit_tracker.entities.response.online_download.OnlineDownloadReport;
|
import ru.nbch.credit_tracker.entities.external_response.online_download.Persons;
|
||||||
import ru.nbch.credit_tracker.entities.response.online_download.Person;
|
import ru.nbch.credit_tracker.entities.external_response.online_report.Report;
|
||||||
import ru.nbch.credit_tracker.entities.response.online_report.Report;
|
import ru.nbch.credit_tracker.entities.external_response.online_report.SgnlOnlineReport;
|
||||||
import ru.nbch.credit_tracker.entities.response.online_report.SgnlOnlineReport;
|
import ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response.MonitoringSignalResponse;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response.Signal;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response.Signals;
|
||||||
|
import ru.nbch.credit_tracker.entities.user_response.monitoring_signal_response.Subject;
|
||||||
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.IXmlProcessor;
|
import ru.nbch.credit_tracker.service.xml.stax.MonitoringSignalResponseStaxXmlWriter;
|
||||||
import ru.nbch.credit_tracker.service.xml.jaxb.XmlUtilService;
|
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.*;
|
||||||
import java.io.File;
|
import java.nio.file.Files;
|
||||||
import java.io.FileOutputStream;
|
import java.nio.file.Path;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сервис периодического опроса официального сервиса сигналов на наличие новых отчетов по пакетам находящимся в статусе ON_MONITORING
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class MonitoringService {
|
public class MonitoringService {
|
||||||
|
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final XmlUtilService xmlUtilService;
|
private final StaxXmlProcessor staxXmlProcessor;
|
||||||
private final CreditTrackerSettings config;
|
private final CreditTrackerSettings config;
|
||||||
|
|
||||||
public MonitoringService(SignalRestService signalRestService,
|
public MonitoringService(SignalRestService signalRestService,
|
||||||
SignalService signalService,
|
SignalService signalService,
|
||||||
XmlUtilService xmlUtilService,
|
StaxXmlProcessor staxXmlProcessor,
|
||||||
CreditTrackerSettings config) {
|
CreditTrackerSettings config) {
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
this.signalService = signalService;
|
this.signalService = signalService;
|
||||||
this.xmlUtilService = xmlUtilService;
|
this.staxXmlProcessor = staxXmlProcessor;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("monitoring-"));
|
||||||
long period = config.getMonitoringInterval() != null ? config.getMonitoringInterval() : 15;
|
long period = config.getMonitoringInterval() != null ? config.getMonitoringInterval() : 15;
|
||||||
scheduler.scheduleAtFixedRate(this::monitor, 0, period, TimeUnit.MINUTES);
|
scheduler.scheduleAtFixedRate(this::monitor, 0, period, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void monitor() {
|
private void monitor() {
|
||||||
log.info("Start monitoring");
|
log.info("Start monitoring");
|
||||||
List<PackageData> packages = signalService.findPackagesOnMonitoring();
|
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||||
for (PackageData packageData : packages) {
|
for (UserPackage userPackage : packages) {
|
||||||
log.info("Processing package {}", packageData.getPackageName());
|
MDC.put("ru.nbch.credit_tracker.log.mdc.key", "[" + userPackage.getPackageName() +"]");
|
||||||
SgnlOnlineReport onlineReports = signalRestService.getReports(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName());
|
processPackage(userPackage);
|
||||||
|
MDC.remove("ru.nbch.credit_tracker.log.mdc.key");
|
||||||
if (onlineReports == null) {
|
|
||||||
log.info("No reports found for package {}", packageData.getPackageName());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> fileNames = onlineReports.getOperationReport().getReports().getReports().stream().map(Report::getFilename)
|
|
||||||
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList(); // TODO оптимизировать
|
|
||||||
|
|
||||||
if (fileNames.isEmpty()) {
|
|
||||||
log.info("No new report found for package {}", packageData.getPackageName());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<String> newReport = Optional.of(fileNames)
|
|
||||||
.orElseGet(Collections::emptyList)
|
|
||||||
.stream().max(Comparator.comparing(CTUtil::parseDateFromReportFileName)); // отфильтровали только те имена, которые парсятся в дату, так что null тут не придет
|
|
||||||
|
|
||||||
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(packageData.getLastDownloadedReport());
|
|
||||||
|
|
||||||
if (packageData.getLastDownloadedReport() != null) {
|
|
||||||
log.info("Last downloaded report found for package {}. Last Downloaded Report Name: {}", packageData.getPackageName(), packageData.getLastDownloadedReport());
|
|
||||||
} else {
|
|
||||||
log.info("Last Downloaded Report Name is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
OnlineDownloadReport report = null;
|
|
||||||
if (packageData.getLastDownloadedReport() == null && newReport.isPresent()) {
|
|
||||||
report = loadReport(newReport.get()); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным
|
|
||||||
} else if (lastDownloadedReportDate != null && newReport.isPresent()) {
|
|
||||||
LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport.get());
|
|
||||||
if (newReportDate.isAfter(lastDownloadedReportDate)) {
|
|
||||||
report = loadReport(newReport.get()); // полученный отчет новее записанного в базу
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (report == null) {
|
|
||||||
log.info("Report was not loaded for package {}", packageData.getPackageName());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
MonitoringSignalResponse response = generateResponse(packageData, report.getPersons().getPersons());
|
|
||||||
String fileName = createResponseFile(packageData, response);
|
|
||||||
if (fileName != null) {
|
|
||||||
log.info("New report fileName: {}", fileName);
|
|
||||||
updateSignalHits(packageData, response, fileName);
|
|
||||||
signalService.updateLastDownloadedReport(packageData.getId(), newReport.get());
|
|
||||||
} else {
|
|
||||||
log.info("Report was not created for package {}", packageData.getPackageName());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
log.info("Finish monitoring");
|
log.info("Finish monitoring");
|
||||||
}
|
}
|
||||||
|
|
||||||
private MonitoringSignalResponse generateResponse(PackageData packageData, List<Person> persons) {
|
private void processPackage(UserPackage userPackage) {
|
||||||
|
log.info("Processing package");
|
||||||
|
if (!signalService.hasNonNullfids(userPackage.getId())) {
|
||||||
|
log.info("Package has no fids. Package will be skipped.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SgnlOnlineReport onlineReports = signalRestService.getReports(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName());
|
||||||
|
|
||||||
|
if (onlineReports == null) {
|
||||||
|
log.info("No reports found for package");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Формируем список имен файлов, по которым сработали сигналы. Сюда входят только те имена, у которых парсится дата формирования отчета
|
||||||
|
List<String> fileNames = onlineReports.getOperationReport().getReports().getReports().stream().map(Report::getFilename)
|
||||||
|
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName) != null).toList();
|
||||||
|
|
||||||
|
if (fileNames.isEmpty()) {
|
||||||
|
log.info("No new report found for package");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDateTime lastDownloadedReportDate = CTUtil.parseDateFromReportFileName(userPackage.getLastDownloadedReport());
|
||||||
|
|
||||||
|
if (lastDownloadedReportDate != null) {
|
||||||
|
// Отбираем только те отчеты, дата которых позже даты последнего загруженного отчета
|
||||||
|
fileNames = fileNames.stream()
|
||||||
|
.filter(fileName -> CTUtil.parseDateFromReportFileName(fileName).isAfter(lastDownloadedReportDate)) // отфильтровали только те имена, которые парсятся в дату, так что null тут не придет
|
||||||
|
.sorted(Comparator.comparing(CTUtil::parseDateFromReportFileName)) // Сортируем по дате
|
||||||
|
.toList();
|
||||||
|
} else {
|
||||||
|
fileNames = fileNames.stream()
|
||||||
|
.sorted(Comparator.comparing(CTUtil::parseDateFromReportFileName)) // Сортируем по дате
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(userPackage.getLastDownloadedReport())) {
|
||||||
|
log.info("Last downloaded report found for package. Last Downloaded Report Name: {}", userPackage.getLastDownloadedReport());
|
||||||
|
} else {
|
||||||
|
log.info("Last Downloaded Report Name is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String newReport : fileNames) {
|
||||||
|
try {
|
||||||
|
String loadedReportPath = null;
|
||||||
|
if (StringUtils.isBlank(userPackage.getLastDownloadedReport())) {
|
||||||
|
loadedReportPath = loadReport(userPackage.getId(), newReport); // по этому пакету еще не было загруженных отчетов, продолжаем работу с полученным
|
||||||
|
} else if (lastDownloadedReportDate != null) {
|
||||||
|
LocalDateTime newReportDate = CTUtil.parseDateFromReportFileName(newReport);
|
||||||
|
if (newReportDate.isAfter(lastDownloadedReportDate)) {
|
||||||
|
loadedReportPath = loadReport(userPackage.getId(), newReport); // полученный отчет новее записанного в базу
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loadedReportPath == null) {
|
||||||
|
log.info("Report was not loaded for package");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String responsePath = generateResponse(userPackage, loadedReportPath);
|
||||||
|
String fileName = null;
|
||||||
|
if (responsePath != null) {
|
||||||
|
fileName = createResponseFile(userPackage, responsePath);
|
||||||
|
}
|
||||||
|
if (fileName != null) {
|
||||||
|
log.info("New report fileName: {}", fileName);
|
||||||
|
updateSignalHits(userPackage, responsePath, fileName);
|
||||||
|
signalService.updateLastDownloadedReport(userPackage.getId(), newReport);
|
||||||
|
} else {
|
||||||
|
log.info("Report was not created for package");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Формирует результирующий xml файл для конечного пользователя на основе файла из официального сервиса сигналов
|
||||||
|
* @return Путь к временному рещультирующему файлу
|
||||||
|
*/
|
||||||
|
private String generateResponse(UserPackage userPackage, String loadedReportPath) {
|
||||||
|
AtomicBoolean generateResponse = new AtomicBoolean(false); // Выставляется в true, если хотя бы один субъект с мониторинга подошел под условие срабатывания сигнала. В этом случае отчет сохраняется
|
||||||
|
|
||||||
|
String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator;
|
||||||
|
String responsePath = folderPath + UUID.randomUUID() + "_response_output.xml";
|
||||||
|
CTUtil.createFolder(folderPath);
|
||||||
|
|
||||||
MonitoringSignalResponse response = new MonitoringSignalResponse();
|
MonitoringSignalResponse response = new MonitoringSignalResponse();
|
||||||
response.setPackageName(packageData.getPackageName()); // Имя пакета, переданного при установке
|
response.setPackageName(userPackage.getPackageName()); // Имя пакета, переданного при установке
|
||||||
Subjects subjects = new Subjects();
|
|
||||||
List<SubjectData> subjectDataList = signalService.findFullSubjectsData(packageData.getId());
|
// Запись в результрующий файл
|
||||||
|
MonitoringSignalResponseStaxXmlWriter staxXmlWriter = new MonitoringSignalResponseStaxXmlWriter(config.getEncoding());
|
||||||
|
staxXmlWriter.writeWithStax(responsePath, response,
|
||||||
|
writer -> {
|
||||||
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(loadedReportPath)), 8 * 1024 * 1024)) {
|
||||||
|
staxXmlProcessor.read(in, Persons.class,
|
||||||
|
personsData -> { // как только считали пачку Persons сразу записали ее в результирующий файл
|
||||||
|
List<Subject> subjectsBatch = processPersons(personsData.getPersons());
|
||||||
|
if (!subjectsBatch.isEmpty()) {
|
||||||
|
generateResponse.set(true);
|
||||||
|
}
|
||||||
|
writer.accept(subjectsBatch);
|
||||||
|
personsData.getPersons().clear(); // чистим список для экономии памяти
|
||||||
|
},
|
||||||
|
pesons -> pesons.getPersons().isEmpty()
|
||||||
|
,
|
||||||
|
10000,
|
||||||
|
"/Report/Persons/Person");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error while parsing nbki downloaded report", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
CTUtil.removeFile(loadedReportPath);
|
||||||
|
|
||||||
|
if (!generateResponse.get()) { // ни один субъект не подошел под условие, удаляем временный отчет
|
||||||
|
CTUtil.removeFile(responsePath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return responsePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Subject> processPersons(List<Person> persons) {
|
||||||
|
List<Subject> subjects = new ArrayList<>();
|
||||||
for (Person person : persons) {
|
for (Person person : persons) {
|
||||||
Signals signals = new Signals();
|
Signals signals = new Signals();
|
||||||
for (Inquiry inquiry : person.getInquiries()) {
|
for (Inquiry inquiry : person.getInquiries()) {
|
||||||
// Отбираем только тех фл, у которых bus_category in (MFO, MKK, MFK) и есть сигналы с кодом 16
|
// Отбираем только тех фл, у которых bus_category in (MFO, MKK, MFK) и есть сигналы с кодом 16
|
||||||
if (!CTUtil.checkBusCategory(inquiry.getBusCategory()) && inquiry.getSignals().stream().anyMatch(signal -> signal.getN().equals(16))) {
|
if (!CTUtil.checkBusCategory(inquiry.getBusCategory()) || inquiry.getSignals().stream().noneMatch(signal -> signal.getN().equals(16))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Signal signal = new Signal();
|
Signal signal = new Signal();
|
||||||
|
|
@ -135,86 +219,101 @@ public class MonitoringService {
|
||||||
|
|
||||||
// Если есть хотя бы один заполненный сигнал, значит заполняем остальные данные
|
// Если есть хотя бы один заполненный сигнал, значит заполняем остальные данные
|
||||||
if (!signals.getSignals().isEmpty()) {
|
if (!signals.getSignals().isEmpty()) {
|
||||||
subjectDataList.stream().filter(p -> p.getSubjectId().equals(person.getUid())).findFirst().ifPresent(subjectData -> {
|
PhoneFidMap subjectData = signalService.findPhoneFidMapById(person.getUid());
|
||||||
|
if (subjectData != null) {
|
||||||
Subject subject = new Subject();
|
Subject subject = new Subject();
|
||||||
subject.setId(subjectData.getSubjectId()); // Уникальный идентификатор субъекта (равен Id из XML-пакета при установке мониторинга)
|
subject.setId(subjectData.getSubjectId()); // Уникальный идентификатор субъекта (равен Id из XML-пакета при установке мониторинга)
|
||||||
subject.setClientId(subjectData.getPhone());
|
subject.setClientId(subjectData.getPhone());
|
||||||
subject.setFlagDebt5000(subjectData.getFlagDebt5000());
|
subject.setFlagDebt5000(subjectData.getFlagDebt5000());
|
||||||
subject.setFlag9012(subjectData.getFlag90days());
|
subject.setFlag9012(subjectData.getFlag90days());
|
||||||
subject.setSignals(signals);
|
subject.setSignals(signals);
|
||||||
subjects.getSubjects().add(subject);
|
subjects.add(subject);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response.setSubjects(subjects);
|
}
|
||||||
return response;
|
return subjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createResponseFile(PackageData packageData, MonitoringSignalResponse response) {
|
/**
|
||||||
|
* Архивирует результирующий xml файл для пользователя
|
||||||
|
* @return Путь к результрующему файлу. Пример <loadDir>/<member_code>/0001ZZ_MY_BATCH_TEST_0717_04_20250723_101929.zip
|
||||||
|
*/
|
||||||
|
private String createResponseFile(UserPackage userPackage, String responsePath) {
|
||||||
try {
|
try {
|
||||||
String fileName = CTUtil.generateResponseReportFileName(packageData.getUserId(), packageData.getPackageName());
|
String fileName = CTUtil.generateResponseReportFileName(userPackage.getUserId(), userPackage.getPackageName());
|
||||||
String filePath = config.getLoadDir() + File.separator + packageData.getUserId().substring(0, 6) + File.separator;
|
Thread.sleep(1000); // Если отчеты формируются слишком быстро, нужно подождать секунду, тк в имени отчета LocalDateTime до секунд
|
||||||
|
String folderPath = config.getLoadDir() + File.separator + userPackage.getUserId().substring(0, 6) + File.separator;
|
||||||
|
|
||||||
File folder = new File(filePath);
|
File folder = new File(folderPath);
|
||||||
if (!folder.exists()) {
|
if (!folder.exists()) {
|
||||||
folder.mkdir();
|
folder.mkdir();
|
||||||
}
|
}
|
||||||
|
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(responsePath)), 8 * 1024 * 1024);
|
||||||
String xmlStr = processor.asString(response, true);
|
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(folderPath + fileName + ".zip"));
|
||||||
|
ZipOutputStream zos = new ZipOutputStream(bos)) {
|
||||||
byte[] xmlBytes = xmlStr.getBytes(Charset.forName("windows-1251"));
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(filePath + fileName + ".zip");
|
|
||||||
ZipOutputStream zos = new ZipOutputStream(fos)) {
|
|
||||||
|
|
||||||
ZipEntry zipEntry = new ZipEntry(fileName + ".xml");
|
ZipEntry zipEntry = new ZipEntry(fileName + ".xml");
|
||||||
zos.putNextEntry(zipEntry);
|
zos.putNextEntry(zipEntry);
|
||||||
zos.write(xmlBytes);
|
byte[] buffer = new byte[8 * 1024 * 1024];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = in.read(buffer)) > 0) {
|
||||||
|
zos.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
zos.finish();
|
||||||
zos.closeEntry();
|
zos.closeEntry();
|
||||||
}
|
}
|
||||||
return fileName;
|
return fileName;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Ошибка при записи отчета пользователя в файл: ", e);
|
log.error("Ошибка при записи отчета пользователя в файл: ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CTUtil.removeFile(responsePath);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSignalHits(PackageData packageData, MonitoringSignalResponse response, String reportFileName) {
|
private void updateSignalHits(UserPackage userPackage, String responsePath, String reportFileName) {
|
||||||
log.info("Updating signal hits for {}", packageData.getPackageName());
|
log.info("Updating signal hits for {}", userPackage.getPackageName());
|
||||||
LocalDateTime responseSentAt = LocalDateTime.now();
|
LocalDateTime responseSentAt = LocalDateTime.now();
|
||||||
List<HitsData> hits = new ArrayList<>();
|
// Считываем результирующий файл пачками и обновляем таблицу hits
|
||||||
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(responsePath)), 8 * 1024 * 1024)) {
|
||||||
|
staxXmlProcessor.read(in, MonitoringSignalResponse.class,
|
||||||
|
response -> { // как только считали пачку Subjects сразу обновлям таблицу hits
|
||||||
|
List<Hit> hits = new ArrayList<>();
|
||||||
response.getSubjects().getSubjects().forEach(subject -> {
|
response.getSubjects().getSubjects().forEach(subject -> {
|
||||||
subject.getSignals().getSignals().forEach(signal -> {
|
subject.getSignals().getSignals().forEach(signal -> {
|
||||||
HitsData hitsData = new HitsData();
|
Hit hit = new Hit();
|
||||||
hitsData.setPackageId(packageData.getId());
|
hit.setPackageId(userPackage.getId());
|
||||||
hitsData.setSubjectId(subject.getId());
|
hit.setSubjectId(subject.getId());
|
||||||
hitsData.setSignalType(1);
|
hit.setSignalType(1);
|
||||||
hitsData.setResponseSentAt(responseSentAt);
|
hit.setResponseSentAt(responseSentAt);
|
||||||
hitsData.setReportFileName(reportFileName);
|
hit.setReportFileName(reportFileName);
|
||||||
hits.add(hitsData);
|
hits.add(hit);
|
||||||
});
|
});
|
||||||
|
if (!hits.isEmpty()) {
|
||||||
|
signalService.insertHits(hits);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
signalService.setHits(hits);
|
response.getSubjects().getSubjects().clear(); // чистим список для экономии памяти
|
||||||
log.info("Signal hits updated for package {}", packageData.getPackageName());
|
},
|
||||||
|
response -> response.getSubjects().getSubjects().isEmpty()
|
||||||
|
,
|
||||||
|
10000,
|
||||||
|
"/MonitoringSignalResponse/Subjects/Subject");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error while updating hits", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OnlineDownloadReport loadReport(String reportName) {
|
CTUtil.removeFile(responsePath); // удалям результирующий xml файл с диска (Он уже заархивирован к этому моменту)
|
||||||
byte[] archive = signalRestService.downloadReport(reportName);
|
|
||||||
if (archive == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
OnlineDownloadReport report;
|
|
||||||
try (GZIPInputStream zipInputStream = new GZIPInputStream(new ByteArrayInputStream(archive))) {
|
|
||||||
|
|
||||||
IXmlProcessor processor = xmlUtilService.createJaxbProcessor();
|
log.info("Signal hits updated for package {}", userPackage.getPackageName());
|
||||||
report = processor.read(zipInputStream, OnlineDownloadReport.class);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e.getMessage(), e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return report;
|
public String loadReport(Long packageId, String reportName) {
|
||||||
|
return signalRestService.downloadReport(packageId, reportName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,149 +1,279 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.nbch.credit_tracker.builder.PersonFactoryBuilder;
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
||||||
import ru.nbch.credit_tracker.entities.dto.HitsData;
|
import ru.nbch.credit_tracker.entities.dto.Hit;
|
||||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
import ru.nbch.credit_tracker.entities.dto.UserPackage;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.MonitoringRequest;
|
import ru.nbch.credit_tracker.entities.external_request.signals.Auth;
|
||||||
import ru.nbch.credit_tracker.entities.request.monitoring_request.Subject;
|
import ru.nbch.credit_tracker.entities.external_request.signals.Person;
|
||||||
import ru.nbch.credit_tracker.entities.response.active_packages.MonitoringActivePackagesResponse;
|
import ru.nbch.credit_tracker.entities.external_request.signals.Signals;
|
||||||
import ru.nbch.credit_tracker.entities.response.active_packages.Package;
|
import ru.nbch.credit_tracker.entities.external_response.monitoring_report_error.MonitoringReportErrors;
|
||||||
import ru.nbch.credit_tracker.entities.response.active_packages.Packages;
|
import ru.nbch.credit_tracker.entities.user_request.monitoring_request.MonitoringRequest;
|
||||||
import ru.nbch.credit_tracker.entities.response.success.MonitoringPackageDeleteResponse;
|
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Auth;
|
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Person;
|
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
import ru.nbch.credit_tracker.enums.Status;
|
||||||
import ru.nbch.credit_tracker.mapper.signal.SignalMapper;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
import ru.nbch.credit_tracker.service.indic.FlagsService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PersonService;
|
import ru.nbch.credit_tracker.service.indic.PersonService;
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
||||||
|
import ru.nbch.credit_tracker.service.signal.HitsService;
|
||||||
|
import ru.nbch.credit_tracker.service.signal.PhoneFidMapService;
|
||||||
|
import ru.nbch.credit_tracker.service.signal.UserPackageService;
|
||||||
|
import ru.nbch.credit_tracker.service.xml.stax.SignalsStaxXmlWriter;
|
||||||
|
import ru.nbch.credit_tracker.service.xml.stax.StaxXmlProcessor;
|
||||||
import ru.nbch.credit_tracker.utils.CTUtil;
|
import ru.nbch.credit_tracker.utils.CTUtil;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.io.BufferedInputStream;
|
||||||
import java.text.SimpleDateFormat;
|
import java.io.File;
|
||||||
import java.time.LocalDate;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.function.Consumer;
|
||||||
import java.util.Map;
|
import java.util.function.Predicate;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class SignalService {
|
public class SignalService {
|
||||||
|
|
||||||
private final static DateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy");
|
|
||||||
|
|
||||||
private final CreditTrackerSettings config;
|
private final CreditTrackerSettings config;
|
||||||
private final SignalMapper mapper;
|
private final HitsService hitsService;
|
||||||
|
private final UserPackageService userPackageService;
|
||||||
|
private final PhoneFidMapService phoneFidMapService;
|
||||||
private final PhoneService phoneService;
|
private final PhoneService phoneService;
|
||||||
private final FlagsService flagsService;
|
private final FlagsService flagsService;
|
||||||
private final PersonService personService;
|
private final PersonService personService;
|
||||||
|
private final StaxXmlProcessor staxXmlProcessor;
|
||||||
|
|
||||||
private final int batchSize = 10000;
|
private final int batchSize = 10000;
|
||||||
|
|
||||||
public SignalService(CreditTrackerSettings config,
|
public SignalService(CreditTrackerSettings config,
|
||||||
SignalMapper mapper,
|
HitsService hitsService,
|
||||||
|
UserPackageService userPackageService,
|
||||||
|
PhoneFidMapService phoneFidMapService,
|
||||||
PhoneService phoneService,
|
PhoneService phoneService,
|
||||||
FlagsService flagsService,
|
FlagsService flagsService,
|
||||||
PersonService personService) {
|
PersonService personService,
|
||||||
|
StaxXmlProcessor staxXmlProcessor) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.mapper = mapper;
|
this.hitsService = hitsService;
|
||||||
|
this.userPackageService = userPackageService;
|
||||||
|
this.phoneFidMapService = phoneFidMapService;
|
||||||
this.phoneService = phoneService;
|
this.phoneService = phoneService;
|
||||||
this.flagsService = flagsService;
|
this.flagsService = flagsService;
|
||||||
this.personService = personService;
|
this.personService = personService;
|
||||||
|
this.staxXmlProcessor = staxXmlProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPackageNotUnique(MonitoringRequest request) {
|
public boolean isPackageNotUnique(MonitoringRequest request) {
|
||||||
String userId = request.getUserId();
|
return userPackageService.isPackageNotUnique(request.getUserId(), request.getPackageName());
|
||||||
return mapper.isPackageNotUnique(userId.substring(0, 6), request.getPackageName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer registerPackage(MonitoringRequest request) {
|
public Long registerPackage(MonitoringRequest request) {
|
||||||
Integer packageId = mapper.registerPackage(request, LocalDateTime.now(), Status.PROCESSING.name());
|
UserPackage userPackage = UserPackage.builder()
|
||||||
List<Subject> subjects = request.getSubjects().getSubject();
|
.userId(request.getUserId())
|
||||||
for (int i = 0; i < subjects.size(); i += batchSize) {
|
.packageName(request.getPackageName())
|
||||||
int end = Math.min(i + batchSize, subjects.size());
|
.createdAt(LocalDateTime.now())
|
||||||
mapper.registerSubjects(subjects.subList(i, end), packageId);
|
.status(Status.PROCESSING.name())
|
||||||
}
|
.build();
|
||||||
return packageId;
|
return userPackageService.insertPackage(userPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PhoneService.FidsPhoneData> registerSubjectsFidAndDebts(Integer packageId) {
|
public void registerSubjects(String filePath, Long packageId) {
|
||||||
List<SubjectData> subjects = mapper.findSubjectsData(packageId);
|
log.info("Start registering subjects. PackageId: {}", packageId);
|
||||||
return updateFlags(subjects, packageId);
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(filePath)), 8 * 1024 * 1024)) {
|
||||||
|
staxXmlProcessor.read(in, MonitoringRequest.class,
|
||||||
|
request -> {
|
||||||
|
if (!request.getSubjects().getSubject().isEmpty()) {
|
||||||
|
phoneFidMapService.registerSubjects(request.getSubjects().getSubject(), packageId);
|
||||||
|
log.trace("Registered subject's batch. Total count: {}. PackageId: {}", request.getSubjects().getSubject().size(), packageId);
|
||||||
|
request.getSubjects().getSubject().clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
request -> request.getSubjects().getSubject().isEmpty()
|
||||||
|
,
|
||||||
|
batchSize, "/MonitoringRequest/Subjects/Subject");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error while parsing monitoring request", e);
|
||||||
|
}
|
||||||
|
log.info("Subjects were registered. PackageId: {}", packageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PhoneService.FidsPhoneData> updateFlags(List<SubjectData> subjects, Integer packageId) {
|
/**
|
||||||
List<PhoneService.FidsPhoneData> fidsPhoneDataList = phoneService.findFidsPhoneData(subjects, true);
|
* Обрабатывает все PhoneFidMap по packageId, выгружая их пачками и фильтруя по переданному фильтру
|
||||||
LocalDateTime calculatedAt = LocalDateTime.now();
|
*/
|
||||||
for (int i = 0; i < fidsPhoneDataList.size(); i += batchSize) {
|
public UpdateResult updateSubjects(Long packageId, Predicate<PhoneFidMap> filter) {
|
||||||
int end = Math.min(i + batchSize, fidsPhoneDataList.size());
|
boolean updated = false;
|
||||||
List<PhoneService.FidsPhoneData> currentList = fidsPhoneDataList.subList(i, end);
|
boolean noFidsFound = true;
|
||||||
Map<Integer, FlagsService.FlagsData> flagsDataMap = flagsService.findFlags(currentList.stream().map(PhoneService.FidsPhoneData::getFid).filter(Objects::nonNull).toList());
|
int offset = 0;
|
||||||
List<SubjectData> subjectToUpdate = new ArrayList<>();
|
List<PhoneFidMap> batch;
|
||||||
|
do {
|
||||||
|
batch = phoneFidMapService.findFullPhoneFidMap(packageId, offset, batchSize);
|
||||||
|
|
||||||
currentList.forEach(data -> {
|
List<PhoneFidMap> filteredItems;
|
||||||
SubjectData subject;
|
if (filter != null) {
|
||||||
if (data.getFid() != null) {
|
filteredItems = batch.stream().filter(filter).toList();
|
||||||
FlagsService.FlagsData flagsData = flagsDataMap.get(data.getFid());
|
|
||||||
subject = new SubjectData(data.getId(), packageId, data.getSubjectId(), data.getPhone(), data.getFid(), flagsData.getFlagDebt5000(), flagsData.getFlag90days(), calculatedAt);
|
|
||||||
} else {
|
} else {
|
||||||
subject = new SubjectData(data.getId(), packageId, data.getSubjectId(), data.getPhone(), null, null, null, calculatedAt);
|
filteredItems = batch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!updated && !filteredItems.isEmpty()) {
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filteredItems.isEmpty()) {
|
||||||
|
boolean fidsFound = updateFlags(filteredItems, packageId);
|
||||||
|
if (noFidsFound) {
|
||||||
|
noFidsFound = !fidsFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += batchSize;
|
||||||
|
} while (!batch.isEmpty());
|
||||||
|
|
||||||
|
return new UpdateResult(updated, noFidsFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обрабатывает пачку PhoneFidMap: обновляет фиды и флаги просрочек
|
||||||
|
* @return fidsFound true - если хотя бы по одному номеру был найден фид, false - в противном случае
|
||||||
|
*/
|
||||||
|
public boolean updateFlags(List<PhoneFidMap> subjects, Long packageId) {
|
||||||
|
log.info("Start calculating fids and flags for subjects batch. PackageId: {}", packageId);
|
||||||
|
Map<String, Integer> fidsMap = phoneService.findFidsPhoneData(subjects);
|
||||||
|
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<>();
|
||||||
|
|
||||||
|
subjects.forEach(subject -> {
|
||||||
|
Integer fid = fidsMap.get("9" + subject.getPhone());
|
||||||
|
if (fid != null) {
|
||||||
|
FlagsService.FlagsData flagsData = flagsDataMap.get(fid);
|
||||||
|
subject = PhoneFidMap.builder()
|
||||||
|
.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);
|
subjectToUpdate.add(subject);
|
||||||
});
|
});
|
||||||
|
|
||||||
int updateBatchSize = batchSize / 8; // 8 параметров на одну запись для обновления. Максимальное количество параметров ~65000
|
int updateBatchSize = batchSize / 9; // 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());
|
||||||
mapper.updateSubjects(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fidsPhoneDataList;
|
log.info("Finish calculating fids and flags for subjects. PackageId: {}. Batch size: {}", packageId, subjects.size());
|
||||||
|
|
||||||
|
return fidsFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rejectPackage(MonitoringRequest request) {
|
public void rejectPackage(MonitoringRequest request) {
|
||||||
mapper.insertPackage(request, LocalDateTime.now(), Status.REJECTED.name());
|
UserPackage userPackage = UserPackage.builder()
|
||||||
|
.userId(request.getUserId())
|
||||||
|
.packageName(request.getPackageName())
|
||||||
|
.createdAt(LocalDateTime.now())
|
||||||
|
.status(Status.REJECTED.name())
|
||||||
|
.build();
|
||||||
|
userPackageService.insertPackage(userPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPackageStatus(Integer packageId, Status status) {
|
public void updatePackageStatus(Long packageId, Status status) {
|
||||||
mapper.setPackageStatus(packageId, status.name());
|
userPackageService.updatePackageStatus(packageId, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Signals buildSignals(Integer packageId, List<PhoneService.FidsPhoneData> fids) {
|
public void updatePackageOnMonitoringSuccess(Long packageId, LocalDateTime monitoringAt) {
|
||||||
PackageData packageData = mapper.findPackageData(packageId);
|
userPackageService.updatePackageOnMonitoringSuccess(packageId, monitoringAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Формирует файл запроса в официальный сервис сигналов, выгружая паспортные данные пачками и сразу записывая их в файл
|
||||||
|
*
|
||||||
|
* @return Путь к файлу запроса к официальному сервису сигналов на постановку на мониторинг
|
||||||
|
*/
|
||||||
|
public String writeSignals(Long packageId) {
|
||||||
|
String folderPath = config.getLoadDir() + File.separator + "tmp_folder" + File.separator;
|
||||||
|
String filePath = folderPath + UUID.randomUUID() + "_output.xml";
|
||||||
|
CTUtil.createFolder(folderPath);
|
||||||
|
|
||||||
|
Signals signals = buildSignals(packageId);
|
||||||
|
|
||||||
|
SignalsStaxXmlWriter signalsStaxXmlWriter = new SignalsStaxXmlWriter(config.getEncoding());
|
||||||
|
|
||||||
|
signalsStaxXmlWriter.writeWithStax(filePath,
|
||||||
|
signals,
|
||||||
|
writer -> buildPersons(packageId, writer));
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Signals buildSignals(Long packageId) {
|
||||||
|
UserPackage userPackage = userPackageService.findPackage(packageId);
|
||||||
Signals signals = new Signals();
|
Signals signals = new Signals();
|
||||||
signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы)
|
signals.setOnline("2"); // Всегда=2 (только онлайн-сигналы)
|
||||||
signals.setId(packageData.getUserId().substring(0, 6) + "_" + packageData.getPackageName()); // <MEMBERCODE>_<PackageName>
|
signals.setProcessWithErrors("1"); // Всегда=1 (обработать пакет полностью, по обнаруженным ошибкам (при наличии) сформировать файл отказа, записи без ошибок установить на мониторинг)
|
||||||
|
signals.setId(userPackage.getUserId().substring(0, 6) + "_" + userPackage.getPackageName()); // <MEMBERCODE>_<PackageName>
|
||||||
Auth auth = new Auth();
|
Auth auth = new Auth();
|
||||||
auth.setUser(config.getSignalsuser());
|
auth.setUser(config.getSignalsuser());
|
||||||
signals.setAuth(auth);
|
signals.setAuth(auth);
|
||||||
for (int i = 0; i < fids.size(); i += batchSize) {
|
|
||||||
int end = Math.min(i + batchSize, fids.size());
|
|
||||||
List<Person> persons = findPersons(fids.subList(i, end));
|
|
||||||
if (!persons.isEmpty()) {
|
|
||||||
signals.getConditions().getPersons().getPerson().addAll(persons);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return signals;
|
return signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Person> findPersons(List<PhoneService.FidsPhoneData> fidsPhoneData) {
|
/**
|
||||||
|
* Обрабатывает все PhoneFidMap по packageId, выгружая их пачками и фильтруя по переданному фильтру.
|
||||||
|
* writer записывает пачку сразу в файл
|
||||||
|
*/
|
||||||
|
private void buildPersons(Long packageId, Consumer<List<Person>> writer) {
|
||||||
|
int offset = 0;
|
||||||
|
List<PhoneFidMap> batch;
|
||||||
|
do {
|
||||||
|
batch = phoneFidMapService.findFullPhoneFidMap(packageId, offset, batchSize);
|
||||||
|
List<Person> persons = findPersons(batch);
|
||||||
|
if (!persons.isEmpty()) {
|
||||||
|
writer.accept(persons); // записывает пачку Persons в файл
|
||||||
|
}
|
||||||
|
offset += batchSize;
|
||||||
|
} while (!batch.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Формирует список Person для постановки на мониторинг в официальный сервис сигналов на основе списка PhoneFidMap
|
||||||
|
*/
|
||||||
|
private List<Person> findPersons(List<PhoneFidMap> subjects) {
|
||||||
|
if (subjects.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
List<Person> persons = new ArrayList<>();
|
List<Person> persons = new ArrayList<>();
|
||||||
Map<Integer, PersonService.PersonData> personFidMap = personService.findPersonData(fidsPhoneData.stream()
|
Map<Integer, PersonService.PersonData> personFidMap = personService.findPersonData(subjects.stream()
|
||||||
.map(PhoneService.FidsPhoneData::getFid)
|
.map(PhoneFidMap::getFid)
|
||||||
.filter(Objects::nonNull).toList());
|
.filter(Objects::nonNull).toList());
|
||||||
fidsPhoneData.forEach(data -> {
|
subjects.forEach(data -> {
|
||||||
if (data.getFid() != null) {
|
if (data.getFid() != null) {
|
||||||
PersonService.PersonData personData = personFidMap.get(data.getFid());
|
PersonService.PersonData personData = personFidMap.get(data.getFid());
|
||||||
Person person = getPerson(personData, data.getSubjectId());
|
Person person = PersonFactoryBuilder.builder()
|
||||||
|
.personData(personData)
|
||||||
|
.uid(data.getId())
|
||||||
|
.build();
|
||||||
if (person != null) {
|
if (person != null) {
|
||||||
persons.add(person);
|
persons.add(person);
|
||||||
}
|
}
|
||||||
|
|
@ -152,101 +282,85 @@ public class SignalService {
|
||||||
return persons;
|
return persons;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Person getPerson(PersonService.PersonData personData, String id) {
|
public void updateSubjectsErrors(String filePath, Long packageId) {
|
||||||
if (personData == null) {
|
log.info("Start updating subjects errors. PackageId: {}", packageId);
|
||||||
return null;
|
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(Path.of(filePath)), 8 * 1024 * 1024)) {
|
||||||
|
staxXmlProcessor.read(in, MonitoringReportErrors.class,
|
||||||
|
request -> {
|
||||||
|
if (!request.getPersons().isEmpty()) {
|
||||||
|
List<PhoneFidMap> subjects = request.getPersons().stream().map(p -> {
|
||||||
|
log.warn("Ошибка при формировании субъекта. package_id = {}, id = {}. Описание: {}", packageId, p.getUid(), p.getValue());
|
||||||
|
return PhoneFidMap.builder()
|
||||||
|
.id(p.getUid())
|
||||||
|
.errorText(p.getValue())
|
||||||
|
.build();
|
||||||
|
}).toList();
|
||||||
|
phoneFidMapService.updatePhoneFidMapsErrors(subjects);
|
||||||
|
log.trace("Updated subject's batch. Total count: {}. PackageId: {}", request.getPersons().size(), packageId);
|
||||||
|
request.getPersons().clear();
|
||||||
}
|
}
|
||||||
PersonService.NameData nameData = personData.getName();
|
},
|
||||||
PersonService.PassportData passportData = personData.getPassport();
|
request -> request.getPersons().isEmpty()
|
||||||
Person person = new Person();
|
,
|
||||||
person.setS(nameData.getLastName());
|
batchSize, "/Errors/p");
|
||||||
person.setN(nameData.getFirstName());
|
} catch (IOException e) {
|
||||||
person.setM(StringUtils.isNotBlank(nameData.getMiddleName()) ? nameData.getMiddleName() : null);
|
throw new RuntimeException("Error while parsing MonitoringReportErrors", e);
|
||||||
person.setD(DATE_FORMAT.format(CTUtil.localDatetoDate(nameData.getBirthDate())));
|
}
|
||||||
|
log.info("Subject's errors were updated. PackageId: {}", packageId);
|
||||||
person.setPn(getPn(passportData.getSerNum(), passportData.getIdNum()));
|
|
||||||
person.setPd(passportData.getIssDate() != null ? DATE_FORMAT.format(CTUtil.localDatetoDate(passportData.getIssDate())) : "01.01.2000");
|
|
||||||
person.setDt(StringUtils.isNotBlank(passportData.getIdType2()) ? passportData.getIdType2() : passportData.getIdType());
|
|
||||||
person.setIp("0");
|
|
||||||
person.setUid(id);
|
|
||||||
person.setOksm("999");
|
|
||||||
person.setConsentDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
|
|
||||||
person.setConsentPurpose("16");
|
|
||||||
person.setReportUser("АО «НБКИ»");
|
|
||||||
person.setLiability("1");
|
|
||||||
person.setConsentPeriod("3");
|
|
||||||
person.setAgrDate(DATE_FORMAT.format(CTUtil.localDatetoDate(LocalDate.now())));
|
|
||||||
person.setReportUserRegNum("1057746710713");
|
|
||||||
person.setReportUserTaxID("7703548386");
|
|
||||||
person.setConsentHash("hash");
|
|
||||||
|
|
||||||
person.setCs(person.getS());
|
|
||||||
person.setConsentN(person.getN());
|
|
||||||
person.setConsentM(person.getM());
|
|
||||||
person.setConsentBd(person.getD());
|
|
||||||
person.setConsentPn(person.getPn());
|
|
||||||
person.setConsentPd(person.getPd());
|
|
||||||
person.setConsentDivCode("000-000");
|
|
||||||
person.setConsentDt(person.getDt());
|
|
||||||
person.setInqPurpose("16");
|
|
||||||
return person;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPn(String serNum, String idNum) {
|
public List<UserPackage> findActivePackages(String userId) {
|
||||||
String normSerNum = CTUtil.normalize(serNum);
|
return userPackageService.findUserPackages(userId, Status.ON_MONITORING);
|
||||||
String normIdNum = CTUtil.normalize(idNum);
|
|
||||||
return StringUtils.isNotBlank(normSerNum) ? normSerNum + normIdNum : normIdNum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<UserPackage> findAllPackages(String userId) {
|
||||||
public MonitoringActivePackagesResponse findActivePackages(String userId) {
|
return userPackageService.findAllPackagesByUserId(userId);
|
||||||
String memberCode = userId.substring(0, 6);
|
|
||||||
MonitoringActivePackagesResponse activePackages = new MonitoringActivePackagesResponse();
|
|
||||||
activePackages.setStatus("OK");
|
|
||||||
activePackages.setMembercode(memberCode);
|
|
||||||
Packages packages = new Packages();
|
|
||||||
mapper.findPackageDataList(memberCode, Status.ON_MONITORING.name()).forEach(data -> {
|
|
||||||
Package pack = new Package();
|
|
||||||
pack.setPackageName(data.getPackageName());
|
|
||||||
pack.setCreatedAt(data.getCreatedAt() != null ? data.getCreatedAt().toString() : null);
|
|
||||||
packages.getPackages().add(pack);
|
|
||||||
});
|
|
||||||
activePackages.setPackages(packages);
|
|
||||||
|
|
||||||
if (packages.getPackages() == null || packages.getPackages().isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return activePackages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPackageExists(String username, String packageName) {
|
public boolean isPackageExists(String username, String packageName) {
|
||||||
return mapper.isPackageExists(username.substring(0, 6), packageName, Status.ON_MONITORING.name());
|
return userPackageService.isPackageExists(username, packageName, Status.ON_MONITORING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonitoringPackageDeleteResponse deletePackage(String username, String packageName) {
|
public boolean isPackagesByStatusExist(String username, String packageName, Status status) {
|
||||||
LocalDateTime deactivatedAt = LocalDateTime.now();
|
return userPackageService.hasActivePackages(username, packageName, status);
|
||||||
mapper.deletePackage(username.substring(0, 6), packageName, Status.DELETED.name(), Status.ON_MONITORING.name(), deactivatedAt);
|
|
||||||
|
|
||||||
MonitoringPackageDeleteResponse deleteResponse = new MonitoringPackageDeleteResponse();
|
|
||||||
deleteResponse.setStatus("Deleted");
|
|
||||||
deleteResponse.setPackageName(packageName);
|
|
||||||
deleteResponse.setDeactivatedAt(deactivatedAt.toString());
|
|
||||||
return deleteResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PackageData> findPackagesOnMonitoring() {
|
public void deletePackage(String username, String packageName, LocalDateTime deactivatedAt) {
|
||||||
return mapper.findPackagesByStatus(Status.ON_MONITORING.name());
|
userPackageService.deletePackage(username, packageName, Status.DELETED, Status.ON_MONITORING, deactivatedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SubjectData> findFullSubjectsData(Integer packageId) {
|
public List<UserPackage> findPackagesOnMonitoring() {
|
||||||
return mapper.findFullSubjectsData(packageId);
|
return userPackageService.findAllPackagesByStatus(Status.ON_MONITORING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHits(List<HitsData> hits) {
|
public List<UserPackage> findPackagesOnProcessing() {
|
||||||
mapper.setHits(hits);
|
return userPackageService.findAllPackagesByStatus(Status.PROCESSING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLastDownloadedReport(Integer id, String fileName) {
|
public void insertHits(List<Hit> hits) {
|
||||||
mapper.setPackageLastDownloadedReport(id, fileName);
|
hitsService.insertHits(hits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateLastDownloadedReport(Long id, String fileName) {
|
||||||
|
userPackageService.updatePackageLastDownloadedReport(id, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PhoneFidMap findPhoneFidMapById(Long id) {
|
||||||
|
return phoneFidMapService.findPhoneFidMapById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNonNullfids(Long packageId) {
|
||||||
|
return phoneFidMapService.hasNonNullfids(packageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserPackage findPackage(Long packageId) {
|
||||||
|
return userPackageService.findPackage(packageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class UpdateResult {
|
||||||
|
private boolean updated;
|
||||||
|
private boolean noFidsFound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.aop.framework.AopContext;
|
||||||
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
|
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.enums.Status;
|
||||||
|
import ru.nbch.credit_tracker.service.signal.SignalRestService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сервис для завершения обработки пакетов находящихся в статусе PROCESSING
|
||||||
|
* Запускается при старте приложения и отрабатывает 1 раз
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@EnableAspectJAutoProxy(exposeProxy = true)
|
||||||
|
public class UpdateProcessingPackagesService {
|
||||||
|
|
||||||
|
private UpdateProcessingPackagesService self;
|
||||||
|
|
||||||
|
private final SignalService signalService;
|
||||||
|
private final SignalRestService signalRestService;
|
||||||
|
private final MonitoringErrorProcesingService monitoringErrorProcesingService;
|
||||||
|
|
||||||
|
public UpdateProcessingPackagesService(SignalService signalService,
|
||||||
|
SignalRestService signalRestService,
|
||||||
|
MonitoringErrorProcesingService monitoringErrorProcesingService) {
|
||||||
|
this.signalService = signalService;
|
||||||
|
this.signalRestService = signalRestService;
|
||||||
|
this.monitoringErrorProcesingService = monitoringErrorProcesingService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
log.info("Start updating processing packages");
|
||||||
|
List<UserPackage> packages = signalService.findPackagesOnProcessing();
|
||||||
|
for (UserPackage userPackage : packages) {
|
||||||
|
log.info("Updating flags for Package {}", userPackage.getPackageName());
|
||||||
|
getCurrentProxy().process(userPackage.getId(), userPackage.getPackageName());
|
||||||
|
}
|
||||||
|
log.info("Finish updating processing packages");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SetAndClearMdc(argIndex = 1)
|
||||||
|
public void process(Long packageId, String packageName) {
|
||||||
|
try {
|
||||||
|
SignalService.UpdateResult updateResult = signalService.updateSubjects(packageId, null);
|
||||||
|
if (updateResult.isNoFidsFound()) {
|
||||||
|
log.info("No fids found for PackageId: {} . Package status ON_MONITORING. No registration in signal service.", packageId);
|
||||||
|
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (signalRestService.setupMonitoring(packageId)) {
|
||||||
|
log.info("Package was successfully registered in signal service. PackageId: {}", packageId);
|
||||||
|
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||||
|
monitoringErrorProcesingService.findErrors(packageId);
|
||||||
|
} else {
|
||||||
|
log.info("Package registration was rejected by signal service. PackageId: {}", packageId);
|
||||||
|
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||||
|
log.error("Ошибка при поиске фидов или расчете флагов просрочек. Package_id {}", packageId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private UpdateProcessingPackagesService getCurrentProxy() {
|
||||||
|
if (self == null) {
|
||||||
|
self = (UpdateProcessingPackagesService) AopContext.currentProxy();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,73 +1,89 @@
|
||||||
package ru.nbch.credit_tracker.service;
|
package ru.nbch.credit_tracker.service;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import ru.nbch.credit_tracker.config.settings.CreditTrackerSettings;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.PackageData;
|
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
|
||||||
import ru.nbch.credit_tracker.entities.signal_package.Signals;
|
|
||||||
import ru.nbch.credit_tracker.enums.Status;
|
|
||||||
import ru.nbch.credit_tracker.service.indic.PhoneService;
|
|
||||||
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 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
|
||||||
|
* По обновленным пакетам формируется новый запрос постановки на мониторинг в официальный сервис сигналов
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class UpdatingFlagsService {
|
public class UpdatingFlagsService {
|
||||||
|
|
||||||
private final SignalService signalService;
|
private final SignalService signalService;
|
||||||
private final SignalRestService signalRestService;
|
private final SignalRestService signalRestService;
|
||||||
|
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,
|
||||||
CreditTrackerSettings config) {
|
MonitoringErrorProcesingService monitoringErrorProcesingService,
|
||||||
|
CreditTrackerSettings config,
|
||||||
|
PhoneFidMapMapper phoneFidMapMapper) {
|
||||||
this.signalService = signalService;
|
this.signalService = signalService;
|
||||||
this.signalRestService = signalRestService;
|
this.signalRestService = signalRestService;
|
||||||
|
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();
|
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<PackageData> packages = signalService.findPackagesOnMonitoring();
|
List<UserPackage> packages = signalService.findPackagesOnMonitoring();
|
||||||
for (PackageData packageData : packages) {
|
for (UserPackage userPackage : packages) {
|
||||||
log.info("Updating flags for Package {}", packageData.getPackageName());
|
MDC.put("ru.nbch.credit_tracker.log.mdc.key", "[" + userPackage.getPackageName() +"]");
|
||||||
List<SubjectData> subjects = signalService.findFullSubjectsData(packageData.getId())
|
log.info("Check on updating flags for Package {}", userPackage.getPackageName());
|
||||||
.stream().filter(subject -> subject.getCalculatedAt() != null && hasDaysPassed(subject.getCalculatedAt())).toList();
|
boolean hasOldRow = phoneFidMapMapper.hasOldRow(userPackage.getId(), daysToUpdateFlags.intValue());
|
||||||
updateFlags(packageData.getId(), subjects, packageData.getPackageName());
|
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, List<SubjectData> subjects, String packageName) {
|
private void updateFlags(UserPackage userPackage) {
|
||||||
|
Long packageId = userPackage.getId();
|
||||||
|
String packageName = userPackage.getPackageName();
|
||||||
try {
|
try {
|
||||||
signalService.setPackageStatus(packageId, Status.PROCESSING);
|
signalService.updatePackageStatus(packageId, Status.PROCESSING);
|
||||||
List<PhoneService.FidsPhoneData> phoneFidsData = signalService.updateFlags(subjects, packageId);
|
SignalService.UpdateResult updateResult = signalService.updateSubjects(packageId, null);
|
||||||
if (!phoneFidsData.isEmpty()) {
|
if (updateResult.isUpdated()) {
|
||||||
Signals signals = signalService.buildSignals(packageId, phoneFidsData);
|
if (signalRestService.setupMonitoring(packageId)) {
|
||||||
if (signalRestService.update(signals)) {
|
LocalDateTime monitoringAt = userPackage.getMonitoringAt() != null ? userPackage.getMonitoringAt() : LocalDateTime.now();
|
||||||
log.info("Flags were updated successfully. PackageId: {} PackageName: {}. Package status changed to ON_MONITORING", packageId, packageName);
|
log.info("Flags were updated successfully. PackageId: {} PackageName: {} MonitoringAt: {}. Package status changed to ON_MONITORING", packageId, packageName, monitoringAt);
|
||||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
signalService.updatePackageOnMonitoringSuccess(packageId, monitoringAt);
|
||||||
|
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);
|
||||||
signalService.setPackageStatus(packageId, Status.ERROR);
|
signalService.updatePackageStatus(packageId, Status.ERROR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.info("No flags were updated for package id {}. Package status changed to ON_MONITORING", packageId);
|
log.info("No flags were updated for package id {}. Package status changed to ON_MONITORING", packageId);
|
||||||
signalService.setPackageStatus(packageId, Status.ON_MONITORING);
|
signalService.updatePackageStatus(packageId, Status.ON_MONITORING);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Ошибка при поиске фидов или перерасчете флагов просрочек. Package_id {}", packageId, e);
|
log.error("Ошибка при поиске фидов или перерасчете флагов просрочек. Package_id {}", packageId, e);
|
||||||
|
|
|
||||||
|
|
@ -70,23 +70,27 @@ public class PersonService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Integer, PassportData> findPassportData(List<Integer> fids) {
|
private Map<Integer, PassportData> findPassportData(List<Integer> fids) {
|
||||||
Map<Integer, PassportData> passportDataMap = new HashMap<>();
|
Map<Integer, PassportData> resultMap = new HashMap<>();
|
||||||
|
|
||||||
List<PassportData> passports = mapper.findPassportData(fids);
|
List<PassportData> passports = mapper.findPassportData(fids);
|
||||||
|
|
||||||
|
Map<Integer, List<PassportData>> passportsMap = passports.stream()
|
||||||
|
.collect(Collectors.groupingBy(PassportData::getFid));
|
||||||
|
|
||||||
fids.forEach(fid -> {
|
fids.forEach(fid -> {
|
||||||
PassportData passport = findPassport(passports.stream()
|
PassportData passport = findPassport(passportsMap.get(fid));
|
||||||
.filter(passportData -> passportData.getFid().equals(fid))
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
if (passport != null) {
|
if (passport != null) {
|
||||||
passportDataMap.put(fid, passport);
|
resultMap.put(fid, passport);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return passportDataMap;
|
return resultMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PassportData findPassport(List<PassportData> passports) {
|
private PassportData findPassport(List<PassportData> passports) {
|
||||||
|
if (passports == null || passports.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
List<PassportData> documents = passports.stream()
|
List<PassportData> documents = passports.stream()
|
||||||
.filter(this::isDUL)
|
.filter(this::isDUL)
|
||||||
.toList(); // берем только ДУЛ
|
.toList(); // берем только ДУЛ
|
||||||
|
|
@ -139,7 +143,7 @@ public class PersonService {
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
idType2 = null;
|
idType2 = null;
|
||||||
}
|
}
|
||||||
return (idType != null && idType <= 30) || (idType2 != null && (idType2 >= 1 || idType2 <= 999));
|
return (idType != null && idType <= 30 && idType != 12) || (idType2 != null && (idType2 >= 1 || idType2 <= 999));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean requiredFieldPresent(NameData nameData, PassportData passportData) {
|
private boolean requiredFieldPresent(NameData nameData, PassportData passportData) {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
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.Setter;
|
import lombok.Setter;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.nbch.credit_tracker.entities.dto.SubjectData;
|
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
|
||||||
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
|
@ -20,32 +22,13 @@ public class PhoneService {
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects) {
|
/**
|
||||||
return findFidsPhoneData(subjects, false);
|
* Ищет фиды по номерам телефона
|
||||||
}
|
* @return Map: key - номер телефона; value - fid
|
||||||
|
*/
|
||||||
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects, boolean processNullFids) {
|
public Map<String, Integer> findFidsPhoneData(List<PhoneFidMap> subjects) {
|
||||||
List<FidsPhoneData> fidsPhoneDataList = new ArrayList<>();
|
List<String> phones = subjects.stream().map(subject -> "9" + subject.getPhone()).toList();
|
||||||
int batchSize = 10000;
|
return convertFidsDataToMap(mapper.findFids(phones));
|
||||||
for (int i = 0; i < subjects.size(); i += batchSize) {
|
|
||||||
int end = Math.min(i + batchSize, subjects.size());
|
|
||||||
List<SubjectData> currentSubjects = subjects.subList(i, end);
|
|
||||||
List<String> phones = currentSubjects.stream().map(subject -> "9" + subject.getPhone()).toList();
|
|
||||||
List<FidsData> fidsData = mapper.findFids(phones);
|
|
||||||
|
|
||||||
Map<String, Integer> fidsMap = convertFidsDataToMap(fidsData);
|
|
||||||
|
|
||||||
currentSubjects.forEach(subject -> {
|
|
||||||
String phone = "9" + subject.getPhone();
|
|
||||||
Integer fid = fidsMap.get(phone);
|
|
||||||
if (fid != null) {
|
|
||||||
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), fid, subject.getPhone(), subject.getSubjectId()));
|
|
||||||
} else if (processNullFids) {
|
|
||||||
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), null, subject.getPhone(), subject.getSubjectId()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return fidsPhoneDataList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Integer> convertFidsDataToMap(List<FidsData> fidsData) {
|
private Map<String, Integer> convertFidsDataToMap(List<FidsData> fidsData) {
|
||||||
|
|
@ -65,16 +48,6 @@ public class PhoneService {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public static class FidsPhoneData {
|
|
||||||
private Integer id;
|
|
||||||
private Integer fid;
|
|
||||||
private String phone;
|
|
||||||
private String subjectId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public static class FidsData {
|
public static class FidsData {
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue