initial import
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
build/
|
||||||
|
dist/
|
||||||
|
logs/
|
||||||
73
build.xml
Normal file
73
build.xml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- You may freely edit this file. See commented blocks below for -->
|
||||||
|
<!-- some examples of how to customize the build. -->
|
||||||
|
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||||
|
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||||
|
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||||
|
<!-- the Compile on Save feature is turned off for the project. -->
|
||||||
|
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||||
|
<!-- in the project's Project Properties dialog box.-->
|
||||||
|
<project name="utms-agent" default="default" basedir=".">
|
||||||
|
<description>Builds, tests, and runs the project utms-agent.</description>
|
||||||
|
<import file="nbproject/build-impl.xml"/>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
There exist several targets which are by default empty and which can be
|
||||||
|
used for execution of your tasks. These targets are usually executed
|
||||||
|
before and after some main targets. They are:
|
||||||
|
|
||||||
|
-pre-init: called before initialization of project properties
|
||||||
|
-post-init: called after initialization of project properties
|
||||||
|
-pre-compile: called before javac compilation
|
||||||
|
-post-compile: called after javac compilation
|
||||||
|
-pre-compile-single: called before javac compilation of single file
|
||||||
|
-post-compile-single: called after javac compilation of single file
|
||||||
|
-pre-compile-test: called before javac compilation of JUnit tests
|
||||||
|
-post-compile-test: called after javac compilation of JUnit tests
|
||||||
|
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||||
|
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||||
|
-pre-jar: called before JAR building
|
||||||
|
-post-jar: called after JAR building
|
||||||
|
-post-clean: called after cleaning build products
|
||||||
|
|
||||||
|
(Targets beginning with '-' are not intended to be called on their own.)
|
||||||
|
|
||||||
|
Example of inserting an obfuscator after compilation could look like this:
|
||||||
|
|
||||||
|
<target name="-post-compile">
|
||||||
|
<obfuscate>
|
||||||
|
<fileset dir="${build.classes.dir}"/>
|
||||||
|
</obfuscate>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
For list of available properties check the imported
|
||||||
|
nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
|
||||||
|
Another way to customize the build is by overriding existing main targets.
|
||||||
|
The targets of interest are:
|
||||||
|
|
||||||
|
-init-macrodef-javac: defines macro for javac compilation
|
||||||
|
-init-macrodef-junit: defines macro for junit execution
|
||||||
|
-init-macrodef-debug: defines macro for class debugging
|
||||||
|
-init-macrodef-java: defines macro for class execution
|
||||||
|
-do-jar: JAR building
|
||||||
|
run: execution of project
|
||||||
|
-javadoc-build: Javadoc generation
|
||||||
|
test-report: JUnit report generation
|
||||||
|
|
||||||
|
An example of overriding the target for project execution could look like this:
|
||||||
|
|
||||||
|
<target name="run" depends="utms-agent-impl.jar">
|
||||||
|
<exec dir="bin" executable="launcher.exe">
|
||||||
|
<arg file="${dist.jar}"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
Notice that the overridden target depends on the jar target and not only on
|
||||||
|
the compile target as the regular run target does. Again, for a list of available
|
||||||
|
properties which you can use, check the target you are overriding in the
|
||||||
|
nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
-->
|
||||||
|
</project>
|
||||||
16
conf/mqtt-agents-log4j.cfg
Normal file
16
conf/mqtt-agents-log4j.cfg
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#
|
||||||
|
# our log4j properties / configuration FILE
|
||||||
|
#
|
||||||
|
# Direct log messages to a rolling log file.
|
||||||
|
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
|
||||||
|
log4j.appender.FILE.File=logs/utms-agent.log
|
||||||
|
log4j.appender.FILE.MaxFileSize=100MB
|
||||||
|
log4j.appender.FILE.MaxBackupIndex=10
|
||||||
|
log4j.appender.FILE.Append=true
|
||||||
|
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.FILE.layout.ConversionPattern=%d [%-5p] [%t] [%c{1}] - %m%n
|
||||||
|
|
||||||
|
# Log only to FILE.
|
||||||
|
log4j.rootLogger=WARN, FILE
|
||||||
|
log4j.logger.id.iptek.utms.agent=INFO, FILE
|
||||||
|
log4j.additivity.id.iptek.utms.agent=false
|
||||||
114
conf/mqtt-agents.cfg
Normal file
114
conf/mqtt-agents.cfg
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
## Logger
|
||||||
|
log4j.file = ${Config.Dir}/mqtt-agents-log4j.cfg
|
||||||
|
|
||||||
|
## Database
|
||||||
|
### if 'db.datasource' has been set or not empty, ignore the rest
|
||||||
|
db.driver = org.postgresql.Driver
|
||||||
|
db.url = jdbc:postgresql://localhost:5432/utms_new
|
||||||
|
db.user = utms
|
||||||
|
db.password = utms1234
|
||||||
|
|
||||||
|
# Mqtt Configuration
|
||||||
|
#mqtt.broker.url = tcp://unifiedtms.id:1883
|
||||||
|
mqtt.broker.url = tcp://192.168.4.112:1883
|
||||||
|
mqtt.clientid_prefix = SENDER_
|
||||||
|
mqtt.user = user1
|
||||||
|
mqtt.password = P@ssw0rd
|
||||||
|
mqtt.keepalive = 10
|
||||||
|
mqtt.maxinflight = 32
|
||||||
|
mqtt.cleansession = true
|
||||||
|
mqtt.autoreconnect = true
|
||||||
|
## Pending Task Configuration
|
||||||
|
pendingtask.query.limit = 100
|
||||||
|
pendingtask.periode.minutes = 30
|
||||||
|
|
||||||
|
# Minio
|
||||||
|
fileserver.endpoint = https://download.unifiedtms.id:9000
|
||||||
|
fileserver.access_key = i9ZB0sNhHaiQe7oEP0sL
|
||||||
|
fileserver.secret_key = 4bxVnKwKgkXpZJ9Dou4oprZ1E8oe3s1HuvKLRn0N
|
||||||
|
fileserver.bucket = application-bucket
|
||||||
|
fileserver.icon.path = icons
|
||||||
|
fileserver.icon.expiry = 7
|
||||||
|
fileserver.icon.timeunit = DAYS
|
||||||
|
fileserver.app.path = apps
|
||||||
|
fileserver.app.expiry = 7
|
||||||
|
fileserver.app.timeunit = DAYS
|
||||||
|
|
||||||
|
## Consumers
|
||||||
|
mqtt.consumers = heartbeat_c, diagnostic_c, device_init_c, download_ack_c
|
||||||
|
#, diagnostic_c, device_init_c, download_ack_c
|
||||||
|
### heartbeat_c
|
||||||
|
mqtt.consumer.heartbeat_c.loggingid = $queue/HEARTBEAT
|
||||||
|
#mqtt.consumer.heartbeat_c.topic = $share/def/SERVER_IN_HB_2
|
||||||
|
mqtt.consumer.heartbeat_c.topic = SERVER_IN_HB_2
|
||||||
|
mqtt.consumer.heartbeat_c.threads = 3
|
||||||
|
mqtt.consumer.heartbeat_c.clientid_prefix = SNHB_
|
||||||
|
mqtt.consumer.heartbeat_c.user = user1
|
||||||
|
mqtt.consumer.heartbeat_c.password = P@ssw0rd
|
||||||
|
mqtt.consumer.heartbeat_c.sleep = 300000
|
||||||
|
mqtt.consumer.heartbeat_c.keepalive = 10
|
||||||
|
mqtt.consumer.heartbeat_c.maxinflight = 32
|
||||||
|
mqtt.consumer.heartbeat_c.cleansession = true
|
||||||
|
mqtt.consumer.heartbeat_c.autoreconnect = true
|
||||||
|
mqtt.consumer.heartbeat_c.workerclass = id.iptek.utms.agent.worker.HeartbeatWorker
|
||||||
|
mqtt.consumer.heartbeat_c.consumermode = BATCH
|
||||||
|
mqtt.consumer.heartbeat_c.batch.capacity = 100
|
||||||
|
### diagnostic_c
|
||||||
|
mqtt.consumer.diagnostic_c.loggingid = DIAGNOSTIC
|
||||||
|
mqtt.consumer.diagnostic_c.topic = $share/def/SERVER_IN_DIAG_2
|
||||||
|
mqtt.consumer.diagnostic_c.threads = 1
|
||||||
|
mqtt.consumer.diagnostic_c.clientid_prefix = SNDIAG
|
||||||
|
mqtt.consumer.diagnostic_c.workerclass = SNDIAG_
|
||||||
|
mqtt.consumer.diagnostic_c.user = user1
|
||||||
|
mqtt.consumer.diagnostic_c.password = P@ssw0rd
|
||||||
|
mqtt.consumer.diagnostic_c.sleep = 300000
|
||||||
|
mqtt.consumer.diagnostic_c.keepalive = 10
|
||||||
|
mqtt.consumer.diagnostic_c.maxinflight = 32
|
||||||
|
mqtt.consumer.diagnostic_c.cleansession = true
|
||||||
|
mqtt.consumer.diagnostic_c.autoreconnect = true
|
||||||
|
mqtt.consumer.diagnostic_c.workerclass = id.iptek.utms.agent.worker.DiagnosticWorker
|
||||||
|
mqtt.consumer.diagnostic_c.consumermode = BATCH
|
||||||
|
mqtt.consumer.diagnostic_c.batch.capacity = 10
|
||||||
|
### device_init_c
|
||||||
|
mqtt.consumer.device_init_c.loggingid = DEVICE_INIT
|
||||||
|
mqtt.consumer.device_init_c.topic = $share/def/SERVER_IN_INIT_2
|
||||||
|
mqtt.consumer.device_init_c.threads = 10
|
||||||
|
mqtt.consumer.device_init_c.clientid_prefix = SNINIT
|
||||||
|
mqtt.consumer.device_init_c.workerclass = SNINIT_
|
||||||
|
mqtt.consumer.device_init_c.user = user1
|
||||||
|
mqtt.consumer.device_init_c.password = P@ssw0rd
|
||||||
|
mqtt.consumer.device_init_c.sleep = 300000
|
||||||
|
mqtt.consumer.device_init_c.keepalive = 10
|
||||||
|
mqtt.consumer.device_init_c.maxinflight = 32
|
||||||
|
mqtt.consumer.device_init_c.cleansession = true
|
||||||
|
mqtt.consumer.device_init_c.autoreconnect = true
|
||||||
|
mqtt.consumer.device_init_c.workerclass = id.iptek.utms.agent.worker.DeviceInitWorker
|
||||||
|
mqtt.consumer.device_init_c.consumermode = SINGLE
|
||||||
|
mqtt.consumer.device_init_c.batch.capacity = 5
|
||||||
|
### download_ack_c
|
||||||
|
mqtt.consumer.download_ack_c.loggingid = DOWNLOAD_ACK
|
||||||
|
mqtt.consumer.download_ack_c.topic = $share/def/SERVER_IN_DL_ACK
|
||||||
|
mqtt.consumer.download_ack_c.threads = 5
|
||||||
|
mqtt.consumer.download_ack_c.clientid_prefix = SNDLACK
|
||||||
|
mqtt.consumer.download_ack_c.workerclass = SNDLACK_
|
||||||
|
mqtt.consumer.download_ack_c.user = user1
|
||||||
|
mqtt.consumer.download_ack_c.password = P@ssw0rd
|
||||||
|
mqtt.consumer.download_ack_c.sleep = 60000
|
||||||
|
mqtt.consumer.download_ack_c.keepalive = 10
|
||||||
|
mqtt.consumer.download_ack_c.maxinflight = 32
|
||||||
|
mqtt.consumer.download_ack_c.cleansession = true
|
||||||
|
mqtt.consumer.download_ack_c.autoreconnect = true
|
||||||
|
mqtt.consumer.download_ack_c.workerclass = id.iptek.utms.agent.worker.DownloadTaskAckWorker
|
||||||
|
|
||||||
|
## Schedulers
|
||||||
|
#schedulers = download_task_publisher
|
||||||
|
# download_task_publisher
|
||||||
|
#scheduler.download_task_publisher.jobclass = id.iptek.utms.agent.scheduler.DownloadTaskPublisher
|
||||||
|
## CRON | SIMPLE
|
||||||
|
#scheduler.download_task_publisher.trigger.type = SIMPLE
|
||||||
|
#scheduler.download_task_publisher.trigger.interval = 10
|
||||||
|
#scheduler.download_task_publisher.trigger.repeat = 10
|
||||||
|
#scheduler.download_task_publisher.trigger.type = CRON
|
||||||
|
#scheduler.download_task_publisher.trigger.expression = 0 0/2 8-17 * * ?
|
||||||
|
|
||||||
|
scheduler.periode.minutes = 1
|
||||||
Binary file not shown.
BIN
lib/Minio-Client/minio-8.5.5-all.jar
Normal file
BIN
lib/Minio-Client/minio-8.5.5-all.jar
Normal file
Binary file not shown.
BIN
lib/Minio-Client/minio-8.5.5.jar
Normal file
BIN
lib/Minio-Client/minio-8.5.5.jar
Normal file
Binary file not shown.
BIN
lib/Mqtt/org.eclipse.paho.client.mqttv3-1.2.5.jar
Normal file
BIN
lib/Mqtt/org.eclipse.paho.client.mqttv3-1.2.5.jar
Normal file
Binary file not shown.
BIN
lib/Quartz/quartz-2.3.0-SNAPSHOT.jar
Normal file
BIN
lib/Quartz/quartz-2.3.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
lib/Quartz/quartz-jobs-2.3.0-SNAPSHOT.jar
Normal file
BIN
lib/Quartz/quartz-jobs-2.3.0-SNAPSHOT.jar
Normal file
Binary file not shown.
BIN
lib/commons-codec-1.15.jar
Normal file
BIN
lib/commons-codec-1.15.jar
Normal file
Binary file not shown.
BIN
lib/commons-collections4-4.4.jar
Normal file
BIN
lib/commons-collections4-4.4.jar
Normal file
Binary file not shown.
BIN
lib/commons-compress-1.23.0.jar
Normal file
BIN
lib/commons-compress-1.23.0.jar
Normal file
Binary file not shown.
BIN
lib/commons-id.jar
Normal file
BIN
lib/commons-id.jar
Normal file
Binary file not shown.
BIN
lib/commons-io-2.13.0.jar
Normal file
BIN
lib/commons-io-2.13.0.jar
Normal file
Binary file not shown.
BIN
lib/commons-lang-2.0.jar
Normal file
BIN
lib/commons-lang-2.0.jar
Normal file
Binary file not shown.
BIN
lib/commons-math3-3.6.1.jar
Normal file
BIN
lib/commons-math3-3.6.1.jar
Normal file
Binary file not shown.
BIN
lib/gson-2.8.9.jar
Normal file
BIN
lib/gson-2.8.9.jar
Normal file
Binary file not shown.
BIN
lib/log4j-1.2.14.jar
Normal file
BIN
lib/log4j-1.2.14.jar
Normal file
Binary file not shown.
BIN
lib/log4j-api-2.20.0.jar
Normal file
BIN
lib/log4j-api-2.20.0.jar
Normal file
Binary file not shown.
BIN
lib/log4j-core-2.20.0.jar
Normal file
BIN
lib/log4j-core-2.20.0.jar
Normal file
Binary file not shown.
BIN
lib/log4j-rolling-appender-20120206-1607-1.2.15.jar
Normal file
BIN
lib/log4j-rolling-appender-20120206-1607-1.2.15.jar
Normal file
Binary file not shown.
14
lib/nblibraries.properties
Normal file
14
lib/nblibraries.properties
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
libs.CopyLibs.classpath=\
|
||||||
|
${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar
|
||||||
|
libs.CopyLibs.displayName=CopyLibs Task
|
||||||
|
libs.CopyLibs.prop-version=3.0
|
||||||
|
libs.Minio-Client.classpath=\
|
||||||
|
${base}/Minio-Client/minio-8.5.5-all.jar
|
||||||
|
libs.Minio-Client.displayName=Minio-Client
|
||||||
|
libs.Mqtt.classpath=\
|
||||||
|
${base}/Mqtt/org.eclipse.paho.client.mqttv3-1.2.5.jar
|
||||||
|
libs.Mqtt.displayName=Mqtt
|
||||||
|
libs.Quartz.classpath=\
|
||||||
|
${base}/Quartz/quartz-2.3.0-SNAPSHOT.jar;\
|
||||||
|
${base}/Quartz/quartz-jobs-2.3.0-SNAPSHOT.jar
|
||||||
|
libs.Quartz.displayName=Quartz
|
||||||
BIN
lib/postgresql-42.2.9.jar
Normal file
BIN
lib/postgresql-42.2.9.jar
Normal file
Binary file not shown.
BIN
lib/slf4j-api-1.7.2.jar
Normal file
BIN
lib/slf4j-api-1.7.2.jar
Normal file
Binary file not shown.
BIN
lib/slf4j-log4j12-1.7.2.jar
Normal file
BIN
lib/slf4j-log4j12-1.7.2.jar
Normal file
Binary file not shown.
BIN
lib/xmlbeans-5.1.1.jar
Normal file
BIN
lib/xmlbeans-5.1.1.jar
Normal file
Binary file not shown.
3
manifest.mf
Normal file
3
manifest.mf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
X-COMMENT: Main-Class will be added automatically by build
|
||||||
|
|
||||||
1796
nbproject/build-impl.xml
Normal file
1796
nbproject/build-impl.xml
Normal file
File diff suppressed because it is too large
Load Diff
8
nbproject/genfiles.properties
Normal file
8
nbproject/genfiles.properties
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
build.xml.data.CRC32=070afaed
|
||||||
|
build.xml.script.CRC32=b80da75b
|
||||||
|
build.xml.stylesheet.CRC32=f85dc8f2@1.106.0.48
|
||||||
|
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||||
|
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||||
|
nbproject/build-impl.xml.data.CRC32=070afaed
|
||||||
|
nbproject/build-impl.xml.script.CRC32=7415c0b1
|
||||||
|
nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.106.0.48
|
||||||
0
nbproject/private/config.properties
Normal file
0
nbproject/private/config.properties
Normal file
8
nbproject/private/private.properties
Normal file
8
nbproject/private/private.properties
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
compile.on.save=true
|
||||||
|
do.depend=false
|
||||||
|
do.jar=true
|
||||||
|
do.jlink=false
|
||||||
|
javac.debug=true
|
||||||
|
javadoc.preview=true
|
||||||
|
jlink.strip=false
|
||||||
|
user.properties.file=C:\\Users\\Ega\\AppData\\Roaming\\NetBeans\\17\\build.properties
|
||||||
15
nbproject/private/private.xml
Normal file
15
nbproject/private/private.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||||
|
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
|
||||||
|
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||||
|
<group name="UTMS">
|
||||||
|
<file>file:/D:/Projects/Personal/verifone/utms-agent/src/id/iptek/utms/agent/Main.java</file>
|
||||||
|
<file>file:/D:/Projects/Personal/verifone/utms-agent/conf/mqtt-agents.cfg</file>
|
||||||
|
<file>file:/D:/Projects/Personal/verifone/utms-agent/src/id/iptek/utms/agent/sample/MqttPublishSample.java</file>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<file>file:/F:/Projects/Personal/verifone/utms-agent/src/id/iptek/utms/agent/Main.java</file>
|
||||||
|
<file>file:/F:/Projects/Personal/verifone/utms-agent/src/id/iptek/utms/agent/model/ApplicationSimple.java</file>
|
||||||
|
</group>
|
||||||
|
</open-files>
|
||||||
|
</project-private>
|
||||||
132
nbproject/project.properties
Normal file
132
nbproject/project.properties
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
annotation.processing.enabled=true
|
||||||
|
annotation.processing.enabled.in.editor=false
|
||||||
|
annotation.processing.processors.list=
|
||||||
|
annotation.processing.run.all.processors=true
|
||||||
|
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||||
|
application.title=utms-agent
|
||||||
|
application.vendor=jakar
|
||||||
|
build.classes.dir=${build.dir}/classes
|
||||||
|
build.classes.excludes=**/*.java,**/*.form
|
||||||
|
# This directory is removed when the project is cleaned:
|
||||||
|
build.dir=build
|
||||||
|
build.generated.dir=${build.dir}/generated
|
||||||
|
build.generated.sources.dir=${build.dir}/generated-sources
|
||||||
|
# Only compile against the classpath explicitly listed here:
|
||||||
|
build.sysclasspath=ignore
|
||||||
|
build.test.classes.dir=${build.dir}/test/classes
|
||||||
|
build.test.results.dir=${build.dir}/test/results
|
||||||
|
# Uncomment to specify the preferred debugger connection transport:
|
||||||
|
#debug.transport=dt_socket
|
||||||
|
debug.classpath=\
|
||||||
|
${run.classpath}
|
||||||
|
debug.modulepath=\
|
||||||
|
${run.modulepath}
|
||||||
|
debug.test.classpath=\
|
||||||
|
${run.test.classpath}
|
||||||
|
debug.test.modulepath=\
|
||||||
|
${run.test.modulepath}
|
||||||
|
# Files in build.classes.dir which should be excluded from distribution jar
|
||||||
|
dist.archive.excludes=
|
||||||
|
# This directory is removed when the project is cleaned:
|
||||||
|
dist.dir=dist
|
||||||
|
dist.jar=${dist.dir}/utms-agent.jar
|
||||||
|
dist.javadoc.dir=${dist.dir}/javadoc
|
||||||
|
dist.jlink.dir=${dist.dir}/jlink
|
||||||
|
dist.jlink.output=${dist.jlink.dir}/utms-agent
|
||||||
|
endorsed.classpath=
|
||||||
|
excludes=
|
||||||
|
file.reference.commons-codec-1.15.jar=lib\\commons-codec-1.15.jar
|
||||||
|
file.reference.commons-collections4-4.4.jar=lib\\commons-collections4-4.4.jar
|
||||||
|
file.reference.commons-compress-1.23.0.jar=lib\\commons-compress-1.23.0.jar
|
||||||
|
file.reference.commons-id.jar=lib\\commons-id.jar
|
||||||
|
file.reference.commons-io-2.13.0.jar=lib\\commons-io-2.13.0.jar
|
||||||
|
file.reference.commons-lang-2.0.jar=lib\\commons-lang-2.0.jar
|
||||||
|
file.reference.commons-math3-3.6.1.jar=lib\\commons-math3-3.6.1.jar
|
||||||
|
file.reference.gson-2.8.9.jar=lib\\gson-2.8.9.jar
|
||||||
|
file.reference.log4j-1.2.14.jar=lib\\log4j-1.2.14.jar
|
||||||
|
file.reference.log4j-api-2.20.0.jar=lib\\log4j-api-2.20.0.jar
|
||||||
|
file.reference.log4j-core-2.20.0.jar=lib\\log4j-core-2.20.0.jar
|
||||||
|
file.reference.log4j-rolling-appender-20120206-1607-1.2.15.jar=lib\\log4j-rolling-appender-20120206-1607-1.2.15.jar
|
||||||
|
file.reference.postgresql-42.2.9.jar=lib\\postgresql-42.2.9.jar
|
||||||
|
file.reference.slf4j-api-1.7.2.jar=lib\\slf4j-api-1.7.2.jar
|
||||||
|
file.reference.slf4j-log4j12-1.7.2.jar=lib\\slf4j-log4j12-1.7.2.jar
|
||||||
|
file.reference.xmlbeans-5.1.1.jar=lib\\xmlbeans-5.1.1.jar
|
||||||
|
includes=**
|
||||||
|
jar.compress=false
|
||||||
|
javac.classpath=\
|
||||||
|
${libs.Mqtt.classpath}:\
|
||||||
|
${file.reference.postgresql-42.2.9.jar}:\
|
||||||
|
${file.reference.log4j-1.2.14.jar}:\
|
||||||
|
${file.reference.log4j-api-2.20.0.jar}:\
|
||||||
|
${file.reference.log4j-core-2.20.0.jar}:\
|
||||||
|
${file.reference.log4j-rolling-appender-20120206-1607-1.2.15.jar}:\
|
||||||
|
${file.reference.slf4j-api-1.7.2.jar}:\
|
||||||
|
${file.reference.slf4j-log4j12-1.7.2.jar}:\
|
||||||
|
${file.reference.gson-2.8.9.jar}:\
|
||||||
|
${file.reference.commons-codec-1.15.jar}:\
|
||||||
|
${file.reference.commons-collections4-4.4.jar}:\
|
||||||
|
${file.reference.commons-compress-1.23.0.jar}:\
|
||||||
|
${file.reference.commons-io-2.13.0.jar}:\
|
||||||
|
${file.reference.commons-math3-3.6.1.jar}:\
|
||||||
|
${file.reference.xmlbeans-5.1.1.jar}:\
|
||||||
|
${file.reference.commons-id.jar}:\
|
||||||
|
${file.reference.commons-lang-2.0.jar}:\
|
||||||
|
${libs.Quartz.classpath}:\
|
||||||
|
${libs.Minio-Client.classpath}
|
||||||
|
# Space-separated list of extra javac options
|
||||||
|
javac.compilerargs=
|
||||||
|
javac.deprecation=false
|
||||||
|
javac.external.vm=true
|
||||||
|
javac.modulepath=
|
||||||
|
javac.processormodulepath=
|
||||||
|
javac.processorpath=\
|
||||||
|
${javac.classpath}
|
||||||
|
javac.source=1.8
|
||||||
|
javac.target=1.8
|
||||||
|
javac.test.classpath=\
|
||||||
|
${javac.classpath}:\
|
||||||
|
${build.classes.dir}
|
||||||
|
javac.test.modulepath=\
|
||||||
|
${javac.modulepath}
|
||||||
|
javac.test.processorpath=\
|
||||||
|
${javac.test.classpath}
|
||||||
|
javadoc.additionalparam=
|
||||||
|
javadoc.author=false
|
||||||
|
javadoc.encoding=${source.encoding}
|
||||||
|
javadoc.html5=false
|
||||||
|
javadoc.noindex=false
|
||||||
|
javadoc.nonavbar=false
|
||||||
|
javadoc.notree=false
|
||||||
|
javadoc.private=false
|
||||||
|
javadoc.splitindex=true
|
||||||
|
javadoc.use=true
|
||||||
|
javadoc.version=false
|
||||||
|
javadoc.windowtitle=
|
||||||
|
# The jlink additional root modules to resolve
|
||||||
|
jlink.additionalmodules=
|
||||||
|
# The jlink additional command line parameters
|
||||||
|
jlink.additionalparam=
|
||||||
|
jlink.launcher=true
|
||||||
|
jlink.launcher.name=utms-agent
|
||||||
|
main.class=id.iptek.utms.agent.Main
|
||||||
|
manifest.file=manifest.mf
|
||||||
|
meta.inf.dir=${src.dir}/META-INF
|
||||||
|
mkdist.disabled=false
|
||||||
|
platform.active=default_platform
|
||||||
|
run.classpath=\
|
||||||
|
${javac.classpath}:\
|
||||||
|
${build.classes.dir}
|
||||||
|
# Space-separated list of JVM arguments used when running the project.
|
||||||
|
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||||
|
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||||
|
run.jvmargs=
|
||||||
|
run.modulepath=\
|
||||||
|
${javac.modulepath}
|
||||||
|
run.test.classpath=\
|
||||||
|
${javac.test.classpath}:\
|
||||||
|
${build.test.classes.dir}
|
||||||
|
run.test.modulepath=\
|
||||||
|
${javac.test.modulepath}
|
||||||
|
source.encoding=UTF-8
|
||||||
|
src.dir=src
|
||||||
|
test.src.dir=test
|
||||||
18
nbproject/project.xml
Normal file
18
nbproject/project.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>org.netbeans.modules.java.j2seproject</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<name>utms-agent</name>
|
||||||
|
<source-roots>
|
||||||
|
<root id="src.dir"/>
|
||||||
|
</source-roots>
|
||||||
|
<test-roots>
|
||||||
|
<root id="test.src.dir"/>
|
||||||
|
</test-roots>
|
||||||
|
</data>
|
||||||
|
<libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
|
||||||
|
<definitions>.\lib\nblibraries.properties</definitions>
|
||||||
|
</libraries>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
||||||
113
src/id/iptek/utms/agent/AppConfig.java
Normal file
113
src/id/iptek/utms/agent/AppConfig.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package id.iptek.utms.agent;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.util.IOUtil;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public final class AppConfig {
|
||||||
|
|
||||||
|
private static AppConfig self = null;
|
||||||
|
private Logger logger = LoggerFactory.getLogger(AppConfig.class);
|
||||||
|
private Properties props = new Properties();
|
||||||
|
|
||||||
|
private AppConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(String configFile) throws Exception {
|
||||||
|
init(new File(configFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(File configFile) throws Exception {
|
||||||
|
InputStream in = new FileInputStream(configFile);
|
||||||
|
try {
|
||||||
|
props.load(in);
|
||||||
|
} finally {
|
||||||
|
IOUtil.close(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(String name, String value) {
|
||||||
|
props.setProperty(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String get(String name, String defaultValue) {
|
||||||
|
String value = get(name);
|
||||||
|
if(value == null) {
|
||||||
|
value = defaultValue;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String get(String name) {
|
||||||
|
logger.trace("#get('{}');", name);
|
||||||
|
String value = props.getProperty(name);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAsInt(String name) {
|
||||||
|
String value = get(name);
|
||||||
|
if(value != null) {
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAsInt(String name, int defaultValue) {
|
||||||
|
String value = get(name);
|
||||||
|
if(value != null) {
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getAsBoolean(String name) {
|
||||||
|
String value = get(name);
|
||||||
|
if(value != null) {
|
||||||
|
return "true".equalsIgnoreCase(value);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getAsBoolean(String name, boolean defaultValue) {
|
||||||
|
String value = get(name);
|
||||||
|
if(value != null) {
|
||||||
|
return "true".equalsIgnoreCase(value);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAsLong(String name) {
|
||||||
|
return getAsLong(name, 0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAsLong(String name, long defaultValue) {
|
||||||
|
String value = get(name);
|
||||||
|
if(value != null) {
|
||||||
|
return Long.parseLong(value);
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getAll(String name) {
|
||||||
|
String value = get(name);
|
||||||
|
if(value != null) {
|
||||||
|
return value.trim().split("\\s*,\\s*");
|
||||||
|
}
|
||||||
|
return new String[] {};
|
||||||
|
}
|
||||||
|
|
||||||
|
public Properties getProps() {
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AppConfig getInstance() {
|
||||||
|
if (self == null) {
|
||||||
|
self = new AppConfig();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/id/iptek/utms/agent/DiagnosticFileCache.java
Normal file
117
src/id/iptek/utms/agent/DiagnosticFileCache.java
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package id.iptek.utms.agent;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.model.FileReaderCacheObj;
|
||||||
|
import id.iptek.utms.agent.model.FileWriterCacheObj;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public final class DiagnosticFileCache {
|
||||||
|
|
||||||
|
protected Logger logger = LoggerFactory.getLogger(DiagnosticFileCache.class);
|
||||||
|
private static DiagnosticFileCache self = null;
|
||||||
|
private FileWriterCacheObj writerObj;
|
||||||
|
private FileReaderCacheObj readerObj;
|
||||||
|
private String fileBaseDir = null;
|
||||||
|
private int maxLinePerFile = 1000;
|
||||||
|
private DiagnosticFileChangeListener listener;
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
private DiagnosticFileCache() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(DiagnosticFileChangeListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileBaseDir(String fileBaseDir) {
|
||||||
|
this.fileBaseDir = fileBaseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File startWriter(File file) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
// there is previous writer, return old file
|
||||||
|
File previousFile = null;
|
||||||
|
if (writerObj != null) {
|
||||||
|
previousFile = writerObj.getFile();
|
||||||
|
} else {
|
||||||
|
writerObj = new FileWriterCacheObj();
|
||||||
|
}
|
||||||
|
writerObj.pointToFile(file);
|
||||||
|
return previousFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxLinePerFile(int maxLinePerFile) {
|
||||||
|
this.maxLinePerFile = maxLinePerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLinePerFile() {
|
||||||
|
return maxLinePerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileWriterCacheObj getWriter() {
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileWriterCacheObj writeLine(String line) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (writerObj == null) {
|
||||||
|
logger.debug("Create new WriterObj!!");
|
||||||
|
// create new file
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||||
|
File newFile = new File(fileBaseDir, sdf.format(new Date()) + UUID.randomUUID().toString() + ".tmp");
|
||||||
|
File oldFile = startWriter(newFile);
|
||||||
|
logger.debug("Pointed to file: \"{}\"", newFile.getAbsolutePath());
|
||||||
|
if (listener != null) {
|
||||||
|
listener.fileChanged(oldFile, newFile);
|
||||||
|
}
|
||||||
|
writerObj.writeLine(line);
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
if (!writerObj.writeLineWithMaxLineNo(maxLinePerFile, line)) {
|
||||||
|
// create new file
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||||
|
File newFile = new File(fileBaseDir, sdf.format(new Date()) + UUID.randomUUID().toString() + ".tmp");
|
||||||
|
File oldFile = startWriter(newFile);
|
||||||
|
logger.debug("Pointed to file: \"{}\"", newFile.getAbsolutePath());
|
||||||
|
if (listener != null) {
|
||||||
|
listener.fileChanged(oldFile, newFile);
|
||||||
|
}
|
||||||
|
// write the un-written line above
|
||||||
|
writerObj.writeLine(line);
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReaderObj(FileReaderCacheObj readerObj) {
|
||||||
|
this.readerObj = readerObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileReaderCacheObj getReaderObj() {
|
||||||
|
return readerObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DiagnosticFileCache getInstance() {
|
||||||
|
if(self == null) {
|
||||||
|
self = new DiagnosticFileCache();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DiagnosticFileChangeListener {
|
||||||
|
|
||||||
|
void fileChanged(File oldFile, File newFile);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/id/iptek/utms/agent/GenericCache.java
Normal file
41
src/id/iptek/utms/agent/GenericCache.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package id.iptek.utms.agent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public final class GenericCache {
|
||||||
|
|
||||||
|
private final static Map<String, GenericCache> caches = new HashMap<>();
|
||||||
|
private final Map<String, Object> cache = new HashMap<>();
|
||||||
|
|
||||||
|
private GenericCache() {}
|
||||||
|
|
||||||
|
public void put(String name, Object value) {
|
||||||
|
cache.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(String name) {
|
||||||
|
return cache.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return cache.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GenericCache getCache(String name) {
|
||||||
|
GenericCache cache = caches.get(name);
|
||||||
|
if(cache == null) {
|
||||||
|
cache = new GenericCache();
|
||||||
|
caches.put(name, cache);
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/id/iptek/utms/agent/HeartbeatFileCache.java
Normal file
117
src/id/iptek/utms/agent/HeartbeatFileCache.java
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package id.iptek.utms.agent;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.model.FileReaderCacheObj;
|
||||||
|
import id.iptek.utms.agent.model.FileWriterCacheObj;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public final class HeartbeatFileCache {
|
||||||
|
|
||||||
|
protected Logger logger = LoggerFactory.getLogger(HeartbeatFileCache.class);
|
||||||
|
private static HeartbeatFileCache self = null;
|
||||||
|
private FileWriterCacheObj writerObj;
|
||||||
|
private FileReaderCacheObj readerObj;
|
||||||
|
private String fileBaseDir = null;
|
||||||
|
private int maxLinePerFile = 1000;
|
||||||
|
private HeartbeatFileChangeListener listener;
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
private HeartbeatFileCache() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(HeartbeatFileChangeListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileBaseDir(String fileBaseDir) {
|
||||||
|
this.fileBaseDir = fileBaseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File startWriter(File file) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
// there is previous writer, return old file
|
||||||
|
File previousFile = null;
|
||||||
|
if (writerObj != null) {
|
||||||
|
previousFile = writerObj.getFile();
|
||||||
|
} else {
|
||||||
|
writerObj = new FileWriterCacheObj();
|
||||||
|
}
|
||||||
|
writerObj.pointToFile(file);
|
||||||
|
return previousFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxLinePerFile(int maxLinePerFile) {
|
||||||
|
this.maxLinePerFile = maxLinePerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLinePerFile() {
|
||||||
|
return maxLinePerFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileWriterCacheObj getWriter() {
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileWriterCacheObj writeLine(String line) throws IOException {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (writerObj == null) {
|
||||||
|
logger.debug("Create new WriterObj!!");
|
||||||
|
// create new file
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||||
|
File newFile = new File(fileBaseDir, sdf.format(new Date()) + UUID.randomUUID().toString() + ".tmp");
|
||||||
|
File oldFile = startWriter(newFile);
|
||||||
|
logger.debug("Pointed to file: \"{}\"", newFile.getAbsolutePath());
|
||||||
|
if (listener != null) {
|
||||||
|
listener.fileChanged(oldFile, newFile);
|
||||||
|
}
|
||||||
|
writerObj.writeLine(line);
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
if (!writerObj.writeLineWithMaxLineNo(maxLinePerFile, line)) {
|
||||||
|
// create new file
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
|
||||||
|
File newFile = new File(fileBaseDir, sdf.format(new Date()) + UUID.randomUUID().toString() + ".tmp");
|
||||||
|
File oldFile = startWriter(newFile);
|
||||||
|
logger.debug("Pointed to file: \"{}\"", newFile.getAbsolutePath());
|
||||||
|
if (listener != null) {
|
||||||
|
listener.fileChanged(oldFile, newFile);
|
||||||
|
}
|
||||||
|
// write the un-written line above
|
||||||
|
writerObj.writeLine(line);
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
return writerObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReaderObj(FileReaderCacheObj readerObj) {
|
||||||
|
this.readerObj = readerObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileReaderCacheObj getReaderObj() {
|
||||||
|
return readerObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HeartbeatFileCache getInstance() {
|
||||||
|
if(self == null) {
|
||||||
|
self = new HeartbeatFileCache();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface HeartbeatFileChangeListener {
|
||||||
|
|
||||||
|
void fileChanged(File oldFile, File newFile);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
429
src/id/iptek/utms/agent/Main.java
Normal file
429
src/id/iptek/utms/agent/Main.java
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
package id.iptek.utms.agent;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.dao.TerminalDao;
|
||||||
|
import id.iptek.utms.agent.db.DBConn;
|
||||||
|
import id.iptek.utms.agent.model.TerminalIdObj;
|
||||||
|
import id.iptek.utms.agent.queue.ConsumerMode;
|
||||||
|
import id.iptek.utms.agent.queue.DelayMessageQueue;
|
||||||
|
import id.iptek.utms.agent.queue.DeviceInitQueueMessageHandler;
|
||||||
|
import id.iptek.utms.agent.queue.DiagnosticInfoQueueMessageHandler;
|
||||||
|
import id.iptek.utms.agent.queue.HeartBeatQueueMessageHandler;
|
||||||
|
import id.iptek.utms.agent.scheduler.job.DownloadTaskSchedulerJob;
|
||||||
|
import id.iptek.utms.agent.util.Singleton;
|
||||||
|
import id.iptek.utms.agent.worker.Worker;
|
||||||
|
import id.iptek.utms.agent.worker.WorkerFactory;
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
|
import org.apache.log4j.BasicConfigurator;
|
||||||
|
import org.apache.log4j.PropertyConfigurator;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||||
|
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||||
|
import static org.quartz.JobBuilder.newJob;
|
||||||
|
import org.quartz.JobDetail;
|
||||||
|
import org.quartz.Scheduler;
|
||||||
|
import org.quartz.SchedulerFactory;
|
||||||
|
import org.quartz.SimpleScheduleBuilder;
|
||||||
|
import org.quartz.Trigger;
|
||||||
|
import org.quartz.TriggerBuilder;
|
||||||
|
import org.quartz.impl.StdSchedulerFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(Main.class);
|
||||||
|
private List<Worker> workers;
|
||||||
|
private List<DelayMessageQueue> queueHandlers;
|
||||||
|
private ExecutorService executorService = Executors.newCachedThreadPool();
|
||||||
|
private final CountDownLatch shutdownLatch = new CountDownLatch(1);
|
||||||
|
private final AtomicBoolean stopping = new AtomicBoolean(false);
|
||||||
|
private static final long QUEUE_SHUTDOWN_TIMEOUT_SECONDS = 30L;
|
||||||
|
|
||||||
|
public void start(String[] args) {
|
||||||
|
String configFile = getConfigFile(args);
|
||||||
|
File config = new File(configFile);
|
||||||
|
File configParent = config.getAbsoluteFile().getParentFile();
|
||||||
|
String baseDir = configParent != null && configParent.getParentFile() != null ? configParent.getParentFile().getAbsolutePath() : ".";
|
||||||
|
if (baseDir == null) {
|
||||||
|
baseDir = ".";
|
||||||
|
}
|
||||||
|
String configDir = (new StringBuilder()).append(baseDir).append(File.separator).append("conf").toString();
|
||||||
|
AppConfig appConfig = AppConfig.getInstance();
|
||||||
|
//init config
|
||||||
|
try {
|
||||||
|
initConfig(appConfig, baseDir, configDir, configFile);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//init logging
|
||||||
|
try {
|
||||||
|
initLogging(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.debug("Error initializing Logging: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//init db
|
||||||
|
try {
|
||||||
|
initDB(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error initializing DB: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//init mqtt client
|
||||||
|
try {
|
||||||
|
initMqttClient(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error init Mqtt Client: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//init minio client
|
||||||
|
try {
|
||||||
|
initMinioClient(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error init Minio Client: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//load data async
|
||||||
|
try {
|
||||||
|
loadDataAsync(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error load data async: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//build message queue handlers
|
||||||
|
try {
|
||||||
|
buildQueueHandlers(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error build & start queue handlers: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//build & start workers
|
||||||
|
try {
|
||||||
|
buildAndStartWorkers(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error build & start workers: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
//start schedulers
|
||||||
|
try {
|
||||||
|
startSchedulers(appConfig);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error starting schedulers: {}", ex.getMessage(), ex);
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getConfigFile(String[] args) {
|
||||||
|
if (args == null || args.length == 0) {
|
||||||
|
throw new IllegalArgumentException("Usage: java -jar utms-agent.jar <config-file>");
|
||||||
|
}
|
||||||
|
if (args.length > 1 && Main.class.getName().equals(args[0])) {
|
||||||
|
return args[1];
|
||||||
|
}
|
||||||
|
return args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initConfig(AppConfig appConfig, String baseDir, String configDir, String configFile) throws Exception {
|
||||||
|
File _configFile = new File(configFile);
|
||||||
|
/*if(!_configFile.isAbsolute()) {
|
||||||
|
_configFile = new File(configDir, configFile);
|
||||||
|
}*/
|
||||||
|
appConfig.init(_configFile);
|
||||||
|
appConfig.set("Config.File", _configFile.getAbsolutePath());
|
||||||
|
appConfig.set("Base.Dir", baseDir);
|
||||||
|
appConfig.set("Config.Dir", configDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initLogging(AppConfig appConfig) throws Exception {
|
||||||
|
String configFile = appConfig.get("log4j.file");
|
||||||
|
String configDir = appConfig.get("Config.Dir");
|
||||||
|
configFile = configFile.replace("${Config.Dir}", configDir);
|
||||||
|
BasicConfigurator.resetConfiguration();
|
||||||
|
PropertyConfigurator.configure(configFile);
|
||||||
|
logger.info("Config file: {}", appConfig.get("Config.File"));
|
||||||
|
logger.info("Base dir: {}", appConfig.get("Base.Dir"));
|
||||||
|
logger.info("Config dir: {}", configDir);
|
||||||
|
logger.info("Logging config file: {}", configFile);
|
||||||
|
logger.info("Logging initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDB(AppConfig appConfig) throws Exception {
|
||||||
|
logger.info("Init DB ...");
|
||||||
|
String datasource = appConfig.get("db.datasource");
|
||||||
|
String driver = appConfig.get("db.driver");
|
||||||
|
String url = appConfig.get("db.url");
|
||||||
|
String user = appConfig.get("db.user");
|
||||||
|
String password = appConfig.get("db.password");
|
||||||
|
|
||||||
|
if (datasource != null && !"".equals(datasource.trim())) {
|
||||||
|
logger.debug("Using datasource.");
|
||||||
|
DBConn.getInstance().init(datasource);
|
||||||
|
} else {
|
||||||
|
logger.debug("Using traditional url, username, and password.");
|
||||||
|
DBConn.getInstance().init(driver, url, user, password);
|
||||||
|
}
|
||||||
|
logger.info("DB initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initMqttClient(AppConfig appConfig) throws Exception {
|
||||||
|
logger.info("Init Mqtt client ...");
|
||||||
|
String clientId = appConfig.get("mqtt.clientid_prefix") + RandomStringUtils.randomAlphanumeric(10);
|
||||||
|
String brokerUrl = appConfig.get("mqtt.broker.url");
|
||||||
|
String username = appConfig.get("mqtt.user");
|
||||||
|
String password = appConfig.get("mqtt.password");
|
||||||
|
int keepAlive = appConfig.getAsInt("mqtt.keepalive", 10);
|
||||||
|
int maxInFlight = appConfig.getAsInt("mqtt.maxinflight", 32);
|
||||||
|
boolean cleanSession = appConfig.getAsBoolean("mqtt.cleansession", true);
|
||||||
|
boolean autoReconnect = appConfig.getAsBoolean("mqtt.autoreconnect", true);
|
||||||
|
|
||||||
|
MemoryPersistence persistence = new MemoryPersistence();
|
||||||
|
MqttClient mqttClient = new MqttClient(brokerUrl, clientId, persistence);
|
||||||
|
MqttConnectOptions connOpts = new MqttConnectOptions();
|
||||||
|
connOpts.setCleanSession(cleanSession);
|
||||||
|
connOpts.setUserName(username);
|
||||||
|
connOpts.setPassword(password.toCharArray());
|
||||||
|
connOpts.setAutomaticReconnect(autoReconnect);
|
||||||
|
connOpts.setKeepAliveInterval(keepAlive);
|
||||||
|
connOpts.setMaxInflight(maxInFlight);
|
||||||
|
logger.info("Try to connect ...");
|
||||||
|
mqttClient.connect(connOpts);
|
||||||
|
|
||||||
|
// put into Singleton
|
||||||
|
Singleton.getInstance("MQTT_CLIENT").setObject(mqttClient);
|
||||||
|
logger.info("Mqtt client initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initMinioClient(AppConfig appConfig) throws Exception {
|
||||||
|
MinioClient minioClient
|
||||||
|
= MinioClient.builder()
|
||||||
|
.endpoint(appConfig.get("fileserver.endpoint"))
|
||||||
|
.credentials(appConfig.get("fileserver.access_key"), appConfig.get("fileserver.secret_key"))
|
||||||
|
.build();
|
||||||
|
// put into Singleton
|
||||||
|
Singleton.getInstance("MINIO_CLIENT").setObject(minioClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildAndStartWorkers(AppConfig appConfig) throws Exception {
|
||||||
|
logger.info("Build & Start workers ...");
|
||||||
|
workers = WorkerFactory.getInstance().buildWorkers(appConfig);
|
||||||
|
for (Worker worker : workers) {
|
||||||
|
logger.info("Start worker .. '{}'", worker.getLoggingId());
|
||||||
|
worker.setExecutorService(executorService);
|
||||||
|
worker.start();
|
||||||
|
logger.info("Worker started");
|
||||||
|
executorService.execute(worker);
|
||||||
|
}
|
||||||
|
logger.info("Workers build & started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildQueueHandlers(AppConfig appConfig) throws Exception {
|
||||||
|
queueHandlers = new ArrayList<>();
|
||||||
|
|
||||||
|
logger.info("Build & Start queue handlers ...");
|
||||||
|
// heartbeat queue handler
|
||||||
|
logger.info("Start Heartbeat queue handler .. ");
|
||||||
|
DelayMessageQueue hbQueue = new DelayMessageQueue(executorService, new HeartBeatQueueMessageHandler(), 10);
|
||||||
|
hbQueue.setMode(ConsumerMode.BATCH);
|
||||||
|
hbQueue.setTotalThread(3);
|
||||||
|
hbQueue.run();
|
||||||
|
// put to singleton
|
||||||
|
Singleton.getInstance(HeartBeatQueueMessageHandler.NAME).setObject(hbQueue);
|
||||||
|
queueHandlers.add(hbQueue);
|
||||||
|
logger.info("Heartbeat queue handler started");
|
||||||
|
|
||||||
|
// diagnostic queue handler
|
||||||
|
logger.info("Start Diagnostic queue handler .. ");
|
||||||
|
DelayMessageQueue diagQueue = new DelayMessageQueue(executorService, new DiagnosticInfoQueueMessageHandler(), 3);
|
||||||
|
diagQueue.setMode(ConsumerMode.BATCH);
|
||||||
|
diagQueue.setTotalThread(2);
|
||||||
|
diagQueue.run();
|
||||||
|
// put to singleton
|
||||||
|
Singleton.getInstance(DiagnosticInfoQueueMessageHandler.NAME).setObject(diagQueue);
|
||||||
|
queueHandlers.add(diagQueue);
|
||||||
|
logger.info("Diagnostic queue handler started");
|
||||||
|
|
||||||
|
// init queue handler
|
||||||
|
logger.info("Start Init queue handler .. ");
|
||||||
|
DelayMessageQueue initQueue = new DelayMessageQueue(executorService, new DeviceInitQueueMessageHandler(), 3);
|
||||||
|
initQueue.setMode(ConsumerMode.BATCH);
|
||||||
|
initQueue.setTotalThread(2);
|
||||||
|
initQueue.run();
|
||||||
|
// put to singleton
|
||||||
|
Singleton.getInstance(DeviceInitQueueMessageHandler.NAME).setObject(initQueue);
|
||||||
|
queueHandlers.add(initQueue);
|
||||||
|
logger.info("Init queue handler started");
|
||||||
|
|
||||||
|
logger.info("Queue handlers build & started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadDataAsync(AppConfig appConfig) throws Exception {
|
||||||
|
logger.info("Load data async ...");
|
||||||
|
// load terminal Id Generic Cache
|
||||||
|
loadTerminalIdCache();
|
||||||
|
logger.info("End of load data async.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadTerminalIdCache() throws Exception {
|
||||||
|
executorService.submit(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
logger.debug("Load Terminal Id data ...");
|
||||||
|
TerminalDao terminalDao = new TerminalDao();
|
||||||
|
GenericCache cache = GenericCache.getCache("terminalId");
|
||||||
|
|
||||||
|
List<TerminalIdObj> terminalList = terminalDao.getTerminalIds();
|
||||||
|
terminalList.forEach((t) -> {
|
||||||
|
cache.put(t.getSn().toLowerCase(), t.getTerminalId());
|
||||||
|
});
|
||||||
|
logger.debug("Terminal Id data loaded: {} data.", terminalList.size());
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error loading Terminal Id cache: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startSchedulers(AppConfig appConfig) throws Exception {
|
||||||
|
logger.info("Start schedulers ...");
|
||||||
|
// download task scheduler
|
||||||
|
JobDetail job = newJob(DownloadTaskSchedulerJob.class)
|
||||||
|
.withIdentity("downloadTaskScheduler", "task")
|
||||||
|
.build();
|
||||||
|
Trigger trigger = TriggerBuilder.newTrigger()
|
||||||
|
.withIdentity("myTrigger", "task")
|
||||||
|
.startNow()
|
||||||
|
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
|
||||||
|
.withIntervalInMinutes(appConfig.getAsInt("scheduler.periode.minutes", 5))
|
||||||
|
.repeatForever())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SchedulerFactory sf = new StdSchedulerFactory();
|
||||||
|
Scheduler sched = sf.getScheduler();
|
||||||
|
sched.scheduleJob(job, trigger);
|
||||||
|
sched.start();
|
||||||
|
|
||||||
|
Singleton.getInstance("SCHEDULER").setObject(sched);
|
||||||
|
logger.info("Schedulers started.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopQueueHandlers() throws Exception {
|
||||||
|
logger.info("Stop queue handlers ...");
|
||||||
|
if (queueHandlers == null) {
|
||||||
|
logger.info("Queue handlers have not been started.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(QUEUE_SHUTDOWN_TIMEOUT_SECONDS);
|
||||||
|
for (DelayMessageQueue queue : queueHandlers) {
|
||||||
|
try {
|
||||||
|
logger.info("Stop queue handler .. '{}'", queue.getClass());
|
||||||
|
long remainingNanos = deadline - System.nanoTime();
|
||||||
|
if (remainingNanos <= 0L) {
|
||||||
|
logger.warn("Queue graceful shutdown timeout reached, forcing queue handler '{}'", queue.getClass());
|
||||||
|
queue.stop(true);
|
||||||
|
} else {
|
||||||
|
boolean graceful = queue.stop(false, remainingNanos, TimeUnit.NANOSECONDS);
|
||||||
|
if (!graceful) {
|
||||||
|
logger.warn("Force queue handler .. '{}'", queue.getClass());
|
||||||
|
queue.stop(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("Queue handler stopped");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error stopping queue handler: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("Queue handlers stopped.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopWorkers() throws Exception {
|
||||||
|
logger.info("Stop workers ...");
|
||||||
|
if (workers == null) {
|
||||||
|
logger.info("Workers have not been started.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Worker worker : workers) {
|
||||||
|
try {
|
||||||
|
logger.info("Stop worker .. '{}'", worker.getLoggingId());
|
||||||
|
worker.stop();
|
||||||
|
logger.info("Worker stopped");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error stopping worker '{}': {}", worker.getLoggingId(), ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("Workers stopped.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (stopping.compareAndSet(false, true)) {
|
||||||
|
try {
|
||||||
|
stopScheduler();
|
||||||
|
stopQueueHandlers();
|
||||||
|
stopWorkers();
|
||||||
|
stopMqttClient();
|
||||||
|
executorService.shutdownNow();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error stopping: {}", ex.getMessage(), ex);
|
||||||
|
} finally {
|
||||||
|
shutdownLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopMqttClient() throws Exception {
|
||||||
|
Object object = Singleton.getInstance("MQTT_CLIENT").getObject();
|
||||||
|
if (object instanceof MqttClient) {
|
||||||
|
MqttClient mqttClient = (MqttClient) object;
|
||||||
|
if (mqttClient.isConnected()) {
|
||||||
|
logger.info("Disconnect MQTT client ...");
|
||||||
|
mqttClient.disconnectForcibly(0L, 250L, false);
|
||||||
|
logger.info("MQTT client disconnected.");
|
||||||
|
}
|
||||||
|
mqttClient.close(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopScheduler() throws Exception {
|
||||||
|
Object scheduler = Singleton.getInstance("SCHEDULER").getObject();
|
||||||
|
if (scheduler instanceof Scheduler) {
|
||||||
|
logger.info("Stop scheduler ...");
|
||||||
|
((Scheduler) scheduler).shutdown(false);
|
||||||
|
logger.info("Scheduler stopped.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void awaitShutdown() throws InterruptedException {
|
||||||
|
shutdownLatch.await();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final Main main = new Main();
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
main.stop();
|
||||||
|
}
|
||||||
|
}, "utms-agent-shutdown"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
main.start(args);
|
||||||
|
main.awaitShutdown();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
main.stop();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
src/id/iptek/utms/agent/dao/ApplicationDao.java
Normal file
76
src/id/iptek/utms/agent/dao/ApplicationDao.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package id.iptek.utms.agent.dao;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.db.DBConn;
|
||||||
|
import id.iptek.utms.agent.db.DBUtil;
|
||||||
|
import id.iptek.utms.agent.db.DatabaseException;
|
||||||
|
import id.iptek.utms.agent.model.ApplicationExt;
|
||||||
|
import id.iptek.utms.agent.model.PendingDownloadTask;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class ApplicationDao {
|
||||||
|
|
||||||
|
public boolean updateIconUrl(ApplicationExt app) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_application set icon_url=?,icon_url_exp=? where id=?::uuid");
|
||||||
|
int idx = 1;
|
||||||
|
pstmt.setString(idx++, app.getIconUrl());
|
||||||
|
pstmt.setTimestamp(idx++, new Timestamp(app.getIconUrlExp().getTime()));
|
||||||
|
pstmt.setString(idx++, app.getId());
|
||||||
|
saved = pstmt.executeUpdate() == 1;
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
DBUtil.close(conn);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean updateAppUrl(PendingDownloadTask task, ApplicationExt app) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_download_task_application_link set download_url=?,download_url_exp=? where download_task_id=?::uuid and application_id=?::uuid");
|
||||||
|
int idx = 1;
|
||||||
|
pstmt.setString(idx++, app.getDownloadUrl());
|
||||||
|
pstmt.setTimestamp(idx++, new Timestamp(app.getDownloadUrlExp().getTime()));
|
||||||
|
pstmt.setString(idx++, task.getId());
|
||||||
|
pstmt.setString(idx++, app.getId());
|
||||||
|
saved = pstmt.executeUpdate() == 1;
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
DBUtil.close(conn);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
256
src/id/iptek/utms/agent/dao/DeleteTaskDao.java
Normal file
256
src/id/iptek/utms/agent/dao/DeleteTaskDao.java
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
package id.iptek.utms.agent.dao;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.db.DBConn;
|
||||||
|
import id.iptek.utms.agent.db.DBUtil;
|
||||||
|
import id.iptek.utms.agent.db.DatabaseException;
|
||||||
|
import id.iptek.utms.agent.model.ApplicationSimple;
|
||||||
|
import id.iptek.utms.agent.model.PendingDeleteTask;
|
||||||
|
import id.iptek.utms.agent.model.TaskAckReq;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class DeleteTaskDao {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
public DeleteTaskDao() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PendingDeleteTask> getPendingTaskForOnlineTerminals(int minutes, int limit) throws DatabaseException {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<PendingDeleteTask> list = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select "
|
||||||
|
+ " terminal.sn, "
|
||||||
|
+ " task.id,task.\"name\",task.delete_time, "
|
||||||
|
+ " app.id app_id,app.app_name,app.package_name, "
|
||||||
|
+ " log.id log_id "
|
||||||
|
+ "from public.tms_delete_task task "
|
||||||
|
+ " inner join public.tms_delete_task_log log on log.task_id=task.id "
|
||||||
|
+ " inner join public.tms_terminal terminal on log.terminal_id=terminal.id and terminal.delete_ts is null and terminal.heartbeat_status=1 "
|
||||||
|
+ " inner join public.tms_delete_task_application_simple_link link on link.delete_task_id=task.id and link.application_simple_id=log.application_simple_id "
|
||||||
|
+ " inner join public.tms_application_simple app on link.application_simple_id=app.id "
|
||||||
|
+ "where log.activity=0 and (log.last_broadcast_ts is null or (log.last_broadcast_ts < current_timestamp - interval '"+minutes+" minutes')) "
|
||||||
|
+ "order by task.create_ts desc,log.last_broadcast_ts asc "
|
||||||
|
+ "limit ? offset 0");
|
||||||
|
pstmt.setInt(1, limit);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
PendingDeleteTask task = new PendingDeleteTask();
|
||||||
|
task.setTerminalSN(rs.getString(1));
|
||||||
|
task.setId(rs.getString(2));
|
||||||
|
task.setName(rs.getString(3));
|
||||||
|
task.setDeleteTime(rs.getTimestamp(4));
|
||||||
|
ApplicationSimple app = new ApplicationSimple();
|
||||||
|
app.setId(rs.getString(5));
|
||||||
|
app.setAppName(rs.getString(6));
|
||||||
|
app.setPackageName(rs.getString(7));
|
||||||
|
task.setApp(app);
|
||||||
|
task.setLogId(rs.getString(8));
|
||||||
|
list.add(task);
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn, pstmt, rs);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PendingDeleteTask> getPendingTaskForTerminals(int minutes, int limit) throws DatabaseException {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<PendingDeleteTask> list = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select "
|
||||||
|
+ " terminal.sn, "
|
||||||
|
+ " task.id,task.\"name\",task.delete_time, "
|
||||||
|
+ " app.id app_id,app.app_name,app.package_name, "
|
||||||
|
+ " log.id log_id "
|
||||||
|
+ "from public.tms_delete_task task "
|
||||||
|
+ " inner join public.tms_delete_task_log log on log.task_id=task.id "
|
||||||
|
+ " inner join public.tms_terminal terminal on log.terminal_id=terminal.id and terminal.delete_ts is null "
|
||||||
|
+ " inner join public.tms_delete_task_application_simple_link link on link.delete_task_id=task.id and link.application_simple_id=log.application_simple_id "
|
||||||
|
+ " inner join public.tms_application_simple app on link.application_simple_id=app.id "
|
||||||
|
+ "where log.activity=0 and (log.last_broadcast_ts is null or (log.last_broadcast_ts < current_timestamp - interval '"+minutes+" minutes')) "
|
||||||
|
+ "order by task.create_ts desc,log.last_broadcast_ts asc "
|
||||||
|
+ "limit ? offset 0");
|
||||||
|
pstmt.setInt(1, limit);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
PendingDeleteTask task = new PendingDeleteTask();
|
||||||
|
task.setTerminalSN(rs.getString(1));
|
||||||
|
task.setId(rs.getString(2));
|
||||||
|
task.setName(rs.getString(3));
|
||||||
|
task.setDeleteTime(rs.getTimestamp(4));
|
||||||
|
ApplicationSimple app = new ApplicationSimple();
|
||||||
|
app.setId(rs.getString(5));
|
||||||
|
app.setAppName(rs.getString(6));
|
||||||
|
app.setPackageName(rs.getString(7));
|
||||||
|
task.setApp(app);
|
||||||
|
task.setLogId(rs.getString(8));
|
||||||
|
list.add(task);
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn, pstmt, rs);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PendingDeleteTask> getPendingTaskForTerminal(String terminalSN) throws DatabaseException {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<PendingDeleteTask> list = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select "
|
||||||
|
+ " terminal.sn, "
|
||||||
|
+ " task.id,task.\"name\",task.delete_time, "
|
||||||
|
+ " app.id app_id,app.app_name,app.package_name, "
|
||||||
|
+ " log.id log_id "
|
||||||
|
+ "from public.tms_delete_task task "
|
||||||
|
+ " inner join public.tms_delete_task_log log on log.task_id=task.id "
|
||||||
|
+ " inner join public.tms_terminal terminal on log.terminal_id=terminal.id and terminal.delete_ts is null "
|
||||||
|
+ " inner join public.tms_delete_task_application_simple_link link on link.delete_task_id=task.id and link.application_simple_id=log.application_simple_id "
|
||||||
|
+ " inner join public.tms_application_simple app on link.application_simple_id=app.id "
|
||||||
|
+ "where lower(terminal.sn)=? "
|
||||||
|
+ " and log.activity=0");
|
||||||
|
pstmt.setString(1, terminalSN.toLowerCase());
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
PendingDeleteTask task = new PendingDeleteTask();
|
||||||
|
task.setTerminalSN(rs.getString(1));
|
||||||
|
task.setId(rs.getString(2));
|
||||||
|
task.setName(rs.getString(3));
|
||||||
|
task.setDeleteTime(rs.getTimestamp(4));
|
||||||
|
ApplicationSimple app = new ApplicationSimple();
|
||||||
|
app.setId(rs.getString(5));
|
||||||
|
app.setAppName(rs.getString(6));
|
||||||
|
app.setPackageName(rs.getString(7));
|
||||||
|
task.setApp(app);
|
||||||
|
task.setLogId(rs.getString(8));
|
||||||
|
list.add(task);
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn, pstmt, rs);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean saveLastBroadcastTs(PendingDeleteTask task) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_delete_task_log set last_broadcast_ts=NOW() where id=?::uuid");
|
||||||
|
pstmt.setString(1, task.getLogId());
|
||||||
|
int affectedRows = pstmt.executeUpdate();
|
||||||
|
saved = affectedRows == 1;
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn, pstmt, null);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean save(TaskAckReq ackReq) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
// update download task log activity
|
||||||
|
saved |= updateDeleteTaskLogActivity(conn, ackReq);
|
||||||
|
if (saved) {
|
||||||
|
int totalUnfinished = getUnfinishedTask(conn, ackReq);
|
||||||
|
if (totalUnfinished == 0) {
|
||||||
|
//logger.debug("Total unfinished is 0, set to DONE");
|
||||||
|
//boolean taskStatusUpdated = updateDownloadTaskLogStatus(conn, ackReq);
|
||||||
|
//logger.debug("Download Task status updated? {}", taskStatusUpdated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateDeleteTaskLogActivity(Connection conn, TaskAckReq ackReq) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_delete_task_log set activity=?,message=?,update_ts=NOW(),updated_by=? where id=?::uuid");
|
||||||
|
int idx = 1;
|
||||||
|
pstmt.setInt(idx++, ackReq.getActivity());
|
||||||
|
pstmt.setString(idx++, ackReq.getMessage());
|
||||||
|
pstmt.setString(idx++, ackReq.getTerminalSN());
|
||||||
|
pstmt.setString(idx++, ackReq.getAckId());
|
||||||
|
saved = pstmt.executeUpdate() >= 1;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getUnfinishedTask(Connection conn, TaskAckReq ackReq) throws DatabaseException {
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
int total = 0;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select count(*) from public.tms_delete_task_log "
|
||||||
|
+ "where task_id = (select id from tms_delete_task_log where id = ?::uuid) "
|
||||||
|
+ " and activity not in (3,4)");
|
||||||
|
pstmt.setString(1, ackReq.getAckId());
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
total = rs.getInt(1);
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(rs);
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
296
src/id/iptek/utms/agent/dao/DiagnosticDao.java
Normal file
296
src/id/iptek/utms/agent/dao/DiagnosticDao.java
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
package id.iptek.utms.agent.dao;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.db.DBConn;
|
||||||
|
import id.iptek.utms.agent.db.DBUtil;
|
||||||
|
import id.iptek.utms.agent.db.DatabaseException;
|
||||||
|
import id.iptek.utms.agent.model.ApplicationSimple;
|
||||||
|
import id.iptek.utms.agent.model.CellInfo;
|
||||||
|
import id.iptek.utms.agent.model.Diagnostic;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class DiagnosticDao {
|
||||||
|
|
||||||
|
public DiagnosticDao() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean save(Diagnostic diagnostic) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
// save heartbeat first
|
||||||
|
saved |= saveDiagnostic(conn, diagnostic);
|
||||||
|
if (saved) {
|
||||||
|
saved |= updateTerminalLastDiagnostic(conn, diagnostic);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean saveAll(List<Diagnostic> diagnostics) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
// save heartbeat first
|
||||||
|
saved |= saveDiagnostics(conn, diagnostics);
|
||||||
|
if (saved) {
|
||||||
|
saved |= updateAllTerminalLastDiagnostic(conn, diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean saveDiagnostic(Connection conn, Diagnostic diagnostic) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "insert into tms_diagnostic_info (id,sn,battery_temp,battery_percentage,latitude,longitude,"
|
||||||
|
+ " meid,switching_times,swiping_card_times,dip_inserting_times,nfc_card_reading_times, "
|
||||||
|
+ " front_camera_open_times,rear_camera_open_times,charge_times, "
|
||||||
|
+ " total_memory,available_memory,total_flash_memory,available_flash_memory,total_mobile_data, "
|
||||||
|
+ " current_boot_time,total_boot_time,installed_apps_string,total_length_printed, "
|
||||||
|
+ " cell_name, cell_type, cell_strength, "
|
||||||
|
+ " create_ts,created_by,version) "
|
||||||
|
+ "values (?::uuid,?,?,?,?,?,"
|
||||||
|
+ " ?,?,?,?,?, "
|
||||||
|
+ " ?,?,?, "
|
||||||
|
+ " ?,?,?,?,?, "
|
||||||
|
+ " ?,?,?,?, "
|
||||||
|
+ " ?,?,?, "
|
||||||
|
+ " ?,?,1) ");
|
||||||
|
int idx = 1;
|
||||||
|
pstmt.setString(idx++, diagnostic.getId());
|
||||||
|
pstmt.setString(idx++, diagnostic.getDeviceSn());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getDiagnosticInfo().getBatteryTemp());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getDiagnosticInfo().getBatteryPercentage());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getLocationInfo().getLat());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getLocationInfo().getLng());
|
||||||
|
pstmt.setString(idx++, diagnostic.getDiagnosticInfo().getMeid());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getSwitchingTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getSwipingCardTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getDipInsertingTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getNfcCardReadingTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getFrontCameraOpenTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getRearCameraOpenTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getChargeTimes());
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getTotalMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getAvailableMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getTotalFlashMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getAvailableFlashMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getTotalMobileData()));
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getCurrentBootTime());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getTotalBootTime());
|
||||||
|
pstmt.setString(idx++, diagnostic.getDiagnosticInfo().getInstalledAppString());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getDiagnosticInfo().getTotalLengthPrinted());
|
||||||
|
if(diagnostic.getCellInfo() != null && !diagnostic.getCellInfo().isEmpty()) {
|
||||||
|
CellInfo cellInfo = diagnostic.getCellInfo().get(0);
|
||||||
|
pstmt.setString(idx++, cellInfo.getName());
|
||||||
|
pstmt.setString(idx++, cellInfo.getType());
|
||||||
|
pstmt.setInt(idx++, cellInfo.getStrength());
|
||||||
|
} else {
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.INTEGER);
|
||||||
|
}
|
||||||
|
pstmt.setTimestamp(idx++, new java.sql.Timestamp(diagnostic.getCreateTime().getTime()));
|
||||||
|
pstmt.setString(idx++, "system");
|
||||||
|
|
||||||
|
saved = pstmt.executeUpdate() == 1;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean saveDiagnostics(Connection conn, List<Diagnostic> diagnostics) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "insert into tms_diagnostic_info (id,sn,battery_temp,battery_percentage,latitude,longitude,"
|
||||||
|
+ " meid,switching_times,swiping_card_times,dip_inserting_times,nfc_card_reading_times, "
|
||||||
|
+ " front_camera_open_times,rear_camera_open_times,charge_times, "
|
||||||
|
+ " total_memory,available_memory,total_flash_memory,available_flash_memory,total_mobile_data, "
|
||||||
|
+ " current_boot_time,total_boot_time,installed_apps_string,total_length_printed, "
|
||||||
|
+ " cell_name, cell_type, cell_strength, "
|
||||||
|
+ " create_ts,created_by,version) "
|
||||||
|
+ "values (?::uuid,?,?,?,?,?,"
|
||||||
|
+ " ?,?,?,?,?, "
|
||||||
|
+ " ?,?,?, "
|
||||||
|
+ " ?,?,?,?,?, "
|
||||||
|
+ " ?,?,?,?, "
|
||||||
|
+ " ?,?,?, "
|
||||||
|
+ " ?,?,1) ");
|
||||||
|
for (Diagnostic diagnostic : diagnostics) {
|
||||||
|
int idx = 1;
|
||||||
|
pstmt.setString(idx++, diagnostic.getId());
|
||||||
|
pstmt.setString(idx++, diagnostic.getDeviceSn());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getDiagnosticInfo().getBatteryTemp());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getDiagnosticInfo().getBatteryPercentage());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getLocationInfo().getLat());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getLocationInfo().getLng());
|
||||||
|
pstmt.setString(idx++, diagnostic.getDiagnosticInfo().getMeid());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getSwitchingTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getSwipingCardTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getDipInsertingTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getNfcCardReadingTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getFrontCameraOpenTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getRearCameraOpenTimes());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getChargeTimes());
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getTotalMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getAvailableMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getTotalFlashMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getAvailableFlashMemory()));
|
||||||
|
pstmt.setLong(idx++, getLong(diagnostic.getDiagnosticInfo().getTotalMobileData()));
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getCurrentBootTime());
|
||||||
|
pstmt.setInt(idx++, diagnostic.getDiagnosticInfo().getTotalBootTime());
|
||||||
|
pstmt.setString(idx++, diagnostic.getDiagnosticInfo().getInstalledAppString());
|
||||||
|
pstmt.setDouble(idx++, diagnostic.getDiagnosticInfo().getTotalLengthPrinted());
|
||||||
|
if(diagnostic.getCellInfo() != null && !diagnostic.getCellInfo().isEmpty()) {
|
||||||
|
CellInfo cellInfo = diagnostic.getCellInfo().get(0);
|
||||||
|
pstmt.setString(idx++, cellInfo.getName());
|
||||||
|
pstmt.setString(idx++, cellInfo.getType());
|
||||||
|
pstmt.setInt(idx++, cellInfo.getStrength());
|
||||||
|
} else {
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.INTEGER);
|
||||||
|
}
|
||||||
|
pstmt.setTimestamp(idx++, new java.sql.Timestamp(diagnostic.getCreateTime().getTime()));
|
||||||
|
pstmt.setString(idx++, "system");
|
||||||
|
pstmt.addBatch();
|
||||||
|
pstmt.clearParameters();
|
||||||
|
}
|
||||||
|
int[] xs = pstmt.executeBatch();
|
||||||
|
int affectedRows = 0;
|
||||||
|
for (int x : xs) {
|
||||||
|
affectedRows += x;
|
||||||
|
}
|
||||||
|
saved = affectedRows == diagnostics.size();
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateTerminalLastDiagnostic(Connection conn, Diagnostic diagnostic) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
String appVersion = null;
|
||||||
|
String launcherVersion = null;
|
||||||
|
String vfsVersion = null;
|
||||||
|
String vfssVersion = null;
|
||||||
|
for (ApplicationSimple app : diagnostic.getInstalledApps()) {
|
||||||
|
if ("com.briit.brimobile".equals(app.getPackageName())) {
|
||||||
|
appVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
if ("com.unified.launcher".equals(app.getPackageName())) {
|
||||||
|
launcherVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
if ("com.vfi.smartpos.system_service".equals(app.getPackageName())) {
|
||||||
|
vfsVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
if ("com.vfi.smartpos.deviceservice".equals(app.getPackageName())) {
|
||||||
|
vfssVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_last_diagnostic_info set diagnostic_info_id=?::uuid,update_ts=now() where terminal_sn=?");
|
||||||
|
pstmt.setString(1, diagnostic.getId());
|
||||||
|
pstmt.setString(2, diagnostic.getDeviceSn());
|
||||||
|
saved = pstmt.executeUpdate() == 1;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateAllTerminalLastDiagnostic(Connection conn, List<Diagnostic> diagnostics) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_last_diagnostic_info set diagnostic_info_id=?::uuid,update_ts=now() where terminal_sn=?");
|
||||||
|
for (Diagnostic diagnostic : diagnostics) {
|
||||||
|
String appVersion = null;
|
||||||
|
String launcherVersion = null;
|
||||||
|
String vfsVersion = null;
|
||||||
|
String vfssVersion = null;
|
||||||
|
for (ApplicationSimple app : diagnostic.getInstalledApps()) {
|
||||||
|
if ("com.briit.brimobile".equals(app.getPackageName())) {
|
||||||
|
appVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
if ("com.unified.launcher".equals(app.getPackageName())) {
|
||||||
|
launcherVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
if ("com.vfi.smartpos.system_service".equals(app.getPackageName())) {
|
||||||
|
vfsVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
if ("com.vfi.smartpos.deviceservice".equals(app.getPackageName())) {
|
||||||
|
vfssVersion = app.getVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pstmt.setString(1, diagnostic.getId());
|
||||||
|
pstmt.setString(2, diagnostic.getDeviceSn());
|
||||||
|
pstmt.addBatch();
|
||||||
|
pstmt.clearParameters();
|
||||||
|
}
|
||||||
|
int[] xs = pstmt.executeBatch();
|
||||||
|
int affectedRows = 0;
|
||||||
|
for (int x : xs) {
|
||||||
|
affectedRows += x;
|
||||||
|
}
|
||||||
|
saved = affectedRows > 0;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getLong(Object val) {
|
||||||
|
if (val instanceof String) {
|
||||||
|
String sVal = (String) val;
|
||||||
|
if (sVal.contains("B")) {
|
||||||
|
sVal = sVal.replace("B", "");
|
||||||
|
}
|
||||||
|
return Long.parseLong(sVal.trim());
|
||||||
|
} else if (val instanceof Long) {
|
||||||
|
return (Long) val;
|
||||||
|
} else if (val instanceof Double) {
|
||||||
|
return ((Double) val).longValue();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
1013
src/id/iptek/utms/agent/dao/DownloadTaskDao.java
Normal file
1013
src/id/iptek/utms/agent/dao/DownloadTaskDao.java
Normal file
File diff suppressed because it is too large
Load Diff
196
src/id/iptek/utms/agent/dao/HeartbeatDao.java
Normal file
196
src/id/iptek/utms/agent/dao/HeartbeatDao.java
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
package id.iptek.utms.agent.dao;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.db.DBConn;
|
||||||
|
import id.iptek.utms.agent.db.DBUtil;
|
||||||
|
import id.iptek.utms.agent.db.DatabaseException;
|
||||||
|
import id.iptek.utms.agent.model.CellInfo;
|
||||||
|
import id.iptek.utms.agent.model.HeartBeat;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class HeartbeatDao {
|
||||||
|
|
||||||
|
private Logger logger = LoggerFactory.getLogger(HeartbeatDao.class);
|
||||||
|
|
||||||
|
public HeartbeatDao() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean save(HeartBeat hearbeat) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
// save heartbeat first
|
||||||
|
saved |= saveHeartBeat(conn, hearbeat);
|
||||||
|
if (saved) {
|
||||||
|
saved |= updateTerminalLastHearbeat(conn, hearbeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getDBConnection() throws SQLException {
|
||||||
|
Connection conn = DBConn.getInstance().getConnection();
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean saveHeartBeat(Connection conn, HeartBeat heartbeat) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "insert into tms_heart_beat (id,sn,battery_temp,battery_percentage,latitude,longitude,cell_name,cell_type,cell_strength,create_ts,created_by,version) "
|
||||||
|
+ "values (?::uuid,?,?,?,?,?,?,?,?,?,?,1) ");
|
||||||
|
int idx = 1;
|
||||||
|
pstmt.setString(idx++, heartbeat.getId());
|
||||||
|
pstmt.setString(idx++, heartbeat.getDeviceSn());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getDiagnosticInfo().getBatteryTemp());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getDiagnosticInfo().getBatteryPercentage());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getLocationInfo().getLat());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getLocationInfo().getLng());
|
||||||
|
if(heartbeat.getCellInfo() != null && !heartbeat.getCellInfo().isEmpty()) {
|
||||||
|
CellInfo cellInfo = heartbeat.getCellInfo().get(0);
|
||||||
|
pstmt.setString(idx++, cellInfo.getName());
|
||||||
|
pstmt.setString(idx++, cellInfo.getType());
|
||||||
|
pstmt.setInt(idx++, cellInfo.getStrength());
|
||||||
|
} else {
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.INTEGER);
|
||||||
|
}
|
||||||
|
pstmt.setTimestamp(idx++, new java.sql.Timestamp(heartbeat.getCreateTime().getTime()));
|
||||||
|
pstmt.setString(idx++, "system");
|
||||||
|
//saved = pstmt.executeUpdate() == 1;
|
||||||
|
saved = pstmt.executeUpdate() >= 0;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean saveAll(List<HeartBeat> hearbeats) throws DatabaseException {
|
||||||
|
boolean saved = false;
|
||||||
|
Connection conn = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
// save heartbeat first
|
||||||
|
saved |= saveHeartBeats(conn, hearbeats);
|
||||||
|
if (saved) {
|
||||||
|
saved |= updateTerminalLastHearbeats(conn, hearbeats);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
DBUtil.rollback(conn);
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean saveHeartBeats(Connection conn, List<HeartBeat> heartbeats) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "insert into tms_heart_beat (id,sn,battery_temp,battery_percentage,latitude,longitude,cell_name,cell_type,cell_strength,create_ts,created_by,version) "
|
||||||
|
+ "values (?::uuid,?,?,?,?,?,?,?,?,?,?,1) ");
|
||||||
|
for(HeartBeat heartbeat : heartbeats) {
|
||||||
|
int idx = 1;
|
||||||
|
pstmt.setString(idx++, heartbeat.getId());
|
||||||
|
pstmt.setString(idx++, heartbeat.getDeviceSn());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getDiagnosticInfo().getBatteryTemp());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getDiagnosticInfo().getBatteryPercentage());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getLocationInfo().getLat());
|
||||||
|
pstmt.setDouble(idx++, heartbeat.getLocationInfo().getLng());
|
||||||
|
if(heartbeat.getCellInfo() != null && !heartbeat.getCellInfo().isEmpty()) {
|
||||||
|
CellInfo cellInfo = heartbeat.getCellInfo().get(0);
|
||||||
|
pstmt.setString(idx++, cellInfo.getName());
|
||||||
|
pstmt.setString(idx++, cellInfo.getType());
|
||||||
|
pstmt.setInt(idx++, cellInfo.getStrength());
|
||||||
|
} else {
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.VARCHAR);
|
||||||
|
pstmt.setNull(idx++, java.sql.Types.INTEGER);
|
||||||
|
}
|
||||||
|
pstmt.setTimestamp(idx++, new java.sql.Timestamp(heartbeat.getCreateTime().getTime()));
|
||||||
|
pstmt.setString(idx++, "system");
|
||||||
|
pstmt.addBatch();
|
||||||
|
pstmt.clearParameters();
|
||||||
|
}
|
||||||
|
int[] xs = pstmt.executeBatch();
|
||||||
|
int affectedRows = 0;
|
||||||
|
for(int x : xs) {
|
||||||
|
affectedRows += x;
|
||||||
|
}
|
||||||
|
//saved = affectedRows > 0;
|
||||||
|
saved = affectedRows >= 0;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateTerminalLastHearbeat(Connection conn, HeartBeat heartbeat) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_last_heartbeat set heart_beat_id=?::uuid,update_ts=now() where terminal_sn=?");
|
||||||
|
pstmt.setString(1, heartbeat.getId());
|
||||||
|
pstmt.setString(2, heartbeat.getDeviceSn());
|
||||||
|
saved = pstmt.executeUpdate() == 1;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateTerminalLastHearbeats(Connection conn, List<HeartBeat> heartbeats) throws SQLException {
|
||||||
|
boolean saved = false;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "update tms_last_heartbeat set heart_beat_id=?::uuid,update_ts=now() where terminal_sn=?");
|
||||||
|
for(HeartBeat heartbeat : heartbeats) {
|
||||||
|
pstmt.setString(1, heartbeat.getId());
|
||||||
|
pstmt.setString(2, heartbeat.getDeviceSn());
|
||||||
|
pstmt.addBatch();
|
||||||
|
pstmt.clearParameters();
|
||||||
|
}
|
||||||
|
int[] xs = pstmt.executeBatch();
|
||||||
|
int affectedRows = 0;
|
||||||
|
for(int x : xs) {
|
||||||
|
affectedRows += x;
|
||||||
|
}
|
||||||
|
saved = affectedRows > 0;
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(pstmt);
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
111
src/id/iptek/utms/agent/dao/ProfileDao.java
Normal file
111
src/id/iptek/utms/agent/dao/ProfileDao.java
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package id.iptek.utms.agent.dao;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.db.DBConn;
|
||||||
|
import id.iptek.utms.agent.db.DBUtil;
|
||||||
|
import id.iptek.utms.agent.db.DatabaseException;
|
||||||
|
import id.iptek.utms.agent.model.Profile;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class ProfileDao {
|
||||||
|
|
||||||
|
public Profile getProfileForTerminal(String terminalSN) throws DatabaseException {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
Profile profile = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select "
|
||||||
|
+ " terminal.sn, "
|
||||||
|
+ " profile.id profile_id,profile.\"name\",profile.heartbeat_interval,profile.diagnostic_interval, "
|
||||||
|
+ " profile.mask_home_button,profile.mask_status_bar,profile.schedule_reboot,profile.schedule_reboot_time, "
|
||||||
|
+ " profile.is_default,profile.relocation_alert,profile.moving_threshold,profile.admin_password,profile.front_app "
|
||||||
|
+ "from public.tms_terminal terminal "
|
||||||
|
+ " inner join public.tms_device_profile profile on terminal.profile_id=profile.id "
|
||||||
|
+ "where lower(terminal.sn)=? and terminal.delete_ts is null;");
|
||||||
|
pstmt.setString(1, terminalSN.toLowerCase());
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
profile = new Profile();
|
||||||
|
profile.setTerminalSN(rs.getString(1));
|
||||||
|
profile.setId(rs.getString(2));
|
||||||
|
profile.setName(rs.getString(3));
|
||||||
|
profile.setHeartbeatInterval(rs.getInt(4));
|
||||||
|
profile.setDiagnosticInterval(rs.getInt(5));
|
||||||
|
profile.setMaskHomeButton(rs.getBoolean(6));
|
||||||
|
profile.setMaskStatusButton(rs.getBoolean(7));
|
||||||
|
profile.setScheduleReboot(rs.getBoolean(8));
|
||||||
|
profile.setScheduleRebootTime(rs.getTimestamp(9));
|
||||||
|
profile.setDefault(rs.getBoolean(10));
|
||||||
|
profile.setRelocationAlert(rs.getBoolean(11));
|
||||||
|
profile.setMovingThreshold(rs.getInt(12));
|
||||||
|
profile.setAdminPassword(rs.getString(13));
|
||||||
|
profile.setFrontApp(rs.getString(14));
|
||||||
|
|
||||||
|
profile.setApps(getProfileApps(conn, profile.getId()));
|
||||||
|
profile.setGroupIds(getTerminalGroupIds(conn, terminalSN));
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn, pstmt, rs);
|
||||||
|
}
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getProfileApps(Connection conn, String profileId) throws SQLException {
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<String> apps = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select "
|
||||||
|
+ " app.package_name "
|
||||||
|
+ "from public.tms_device_profile_app app "
|
||||||
|
+ "where app.profile_id=?::uuid");
|
||||||
|
pstmt.setString(1, profileId);
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
String packageName = rs.getString(1);
|
||||||
|
apps.add(packageName);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(null, pstmt, rs);
|
||||||
|
}
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTerminalGroupIds(Connection conn, String terminalSN) throws SQLException {
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<String> apps = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select ttg.id group_id "
|
||||||
|
+ "from tms_terminal_group ttg "
|
||||||
|
+ " inner join tms_terminal_group_link ttgl on ttgl.terminal_group_id = ttg.id "
|
||||||
|
+ " inner join tms_terminal tt on ttgl.terminal_id = tt.id and tt.delete_ts is null "
|
||||||
|
+ "where lower(tt.sn) = ?");
|
||||||
|
pstmt.setString(1, terminalSN.toLowerCase());
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
String groupId = rs.getString(1);
|
||||||
|
apps.add(groupId);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(null, pstmt, rs);
|
||||||
|
}
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
74
src/id/iptek/utms/agent/dao/TerminalDao.java
Normal file
74
src/id/iptek/utms/agent/dao/TerminalDao.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package id.iptek.utms.agent.dao;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.db.DBConn;
|
||||||
|
import id.iptek.utms.agent.db.DBUtil;
|
||||||
|
import id.iptek.utms.agent.db.DatabaseException;
|
||||||
|
import id.iptek.utms.agent.model.TerminalIdObj;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class TerminalDao {
|
||||||
|
|
||||||
|
public TerminalDao() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TerminalIdObj> getTerminalIds() throws DatabaseException {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
List<TerminalIdObj> list = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select id, sn "
|
||||||
|
+ "from tms_terminal "
|
||||||
|
+ "where delete_ts is null");
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
while (rs.next()) {
|
||||||
|
String terminalId = rs.getString(1);
|
||||||
|
String sn = rs.getString(2);
|
||||||
|
list.add(new TerminalIdObj(sn, terminalId));
|
||||||
|
}
|
||||||
|
} catch(SQLException ex) {
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn, pstmt, rs);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerminalIdObj getTerminalIdBySN(String sn) throws DatabaseException {
|
||||||
|
Connection conn = null;
|
||||||
|
PreparedStatement pstmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
TerminalIdObj terminalIdObj = null;
|
||||||
|
try {
|
||||||
|
conn = DBConn.getInstance().getConnection();
|
||||||
|
pstmt = conn.prepareStatement(""
|
||||||
|
+ "select id, sn "
|
||||||
|
+ "from tms_terminal "
|
||||||
|
+ "where lower(sn)=? and delete_ts is null");
|
||||||
|
pstmt.setString(1, sn.toLowerCase());
|
||||||
|
rs = pstmt.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
String terminalId = rs.getString(1);
|
||||||
|
String _sn = rs.getString(2);
|
||||||
|
terminalIdObj = new TerminalIdObj(_sn, terminalId);
|
||||||
|
}
|
||||||
|
} catch(SQLException ex) {
|
||||||
|
throw new DatabaseException(ex);
|
||||||
|
} finally {
|
||||||
|
DBUtil.close(conn, pstmt, rs);
|
||||||
|
}
|
||||||
|
return terminalIdObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
69
src/id/iptek/utms/agent/db/DBConn.java
Normal file
69
src/id/iptek/utms/agent/db/DBConn.java
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package id.iptek.utms.agent.db;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka Ramdani
|
||||||
|
*/
|
||||||
|
public class DBConn {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(DBConn.class);
|
||||||
|
|
||||||
|
private boolean isUseDatasource;
|
||||||
|
private String datasource;
|
||||||
|
private String driver;
|
||||||
|
private String url;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private static DBConn self;
|
||||||
|
|
||||||
|
private DBConn() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(String datasource) throws Exception {
|
||||||
|
this.datasource = datasource;
|
||||||
|
logger.debug("Using Data Source: {}", this.datasource);
|
||||||
|
this.isUseDatasource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(String driver, String url, String username, String password) throws Exception {
|
||||||
|
this.driver = driver;
|
||||||
|
this.url = url;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
|
||||||
|
//load driver
|
||||||
|
logger.debug("Load JDBC driver: {}", this.driver);
|
||||||
|
Class.forName(this.driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
if(!isUseDatasource) {
|
||||||
|
return DriverManager.getConnection(url, username, password);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
InitialContext initialContext = new InitialContext();
|
||||||
|
DataSource dataSource = (DataSource) initialContext.lookup(this.datasource);
|
||||||
|
return dataSource.getConnection();
|
||||||
|
} catch(NamingException ex) {
|
||||||
|
throw new SQLException("Naming Exception when getting connection from datasource: {}", this.datasource, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DBConn getInstance() {
|
||||||
|
if (self == null) {
|
||||||
|
self = new DBConn();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
96
src/id/iptek/utms/agent/db/DBUtil.java
Normal file
96
src/id/iptek/utms/agent/db/DBUtil.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package id.iptek.utms.agent.db;
|
||||||
|
|
||||||
|
import java.sql.CallableStatement;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
public class DBUtil {
|
||||||
|
|
||||||
|
public DBUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rollback(Connection conn) {
|
||||||
|
if (conn != null) {
|
||||||
|
try {
|
||||||
|
conn.rollback();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Connection conn, Statement st) {
|
||||||
|
close(st);
|
||||||
|
close(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Connection conn, PreparedStatement pstmt) {
|
||||||
|
close(pstmt);
|
||||||
|
close(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Connection conn, Statement st, ResultSet rs) {
|
||||||
|
close(rs);
|
||||||
|
close(st);
|
||||||
|
close(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
|
||||||
|
close(rs);
|
||||||
|
close(pstmt);
|
||||||
|
close(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Connection conn, CallableStatement cstmt, ResultSet rs) {
|
||||||
|
close(rs);
|
||||||
|
close(cstmt);
|
||||||
|
close(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Connection conn) {
|
||||||
|
try {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close();
|
||||||
|
conn = null;
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(PreparedStatement pstmt) {
|
||||||
|
try {
|
||||||
|
if (pstmt != null) {
|
||||||
|
pstmt.close();
|
||||||
|
pstmt = null;
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Statement st) {
|
||||||
|
try {
|
||||||
|
if (st != null) {
|
||||||
|
st.close();
|
||||||
|
st = null;
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(ResultSet rs) {
|
||||||
|
try {
|
||||||
|
if (rs != null) {
|
||||||
|
rs.close();
|
||||||
|
rs = null;
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/id/iptek/utms/agent/db/DatabaseException.java
Normal file
16
src/id/iptek/utms/agent/db/DatabaseException.java
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package id.iptek.utms.agent.db;
|
||||||
|
|
||||||
|
public class DatabaseException extends RuntimeException {
|
||||||
|
|
||||||
|
public DatabaseException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseException(Throwable th) {
|
||||||
|
super(th);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseException(String message, Throwable th) {
|
||||||
|
super(message, th);
|
||||||
|
}
|
||||||
|
}
|
||||||
210
src/id/iptek/utms/agent/model/Application.java
Normal file
210
src/id/iptek/utms/agent/model/Application.java
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
protected String id;
|
||||||
|
protected String appName;
|
||||||
|
protected String packageName;
|
||||||
|
protected String version;
|
||||||
|
protected String companyName;
|
||||||
|
protected boolean uninstallable;
|
||||||
|
protected String description;
|
||||||
|
protected String apkId;
|
||||||
|
protected String fileId;
|
||||||
|
protected String fileExt;
|
||||||
|
protected Date fileCreateDate;
|
||||||
|
protected String checksum;
|
||||||
|
|
||||||
|
public Application() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the appName
|
||||||
|
*/
|
||||||
|
public String getAppName() {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param appName the appName to set
|
||||||
|
*/
|
||||||
|
public void setAppName(String appName) {
|
||||||
|
this.appName = appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the packageName
|
||||||
|
*/
|
||||||
|
public String getPackageName() {
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param packageName the packageName to set
|
||||||
|
*/
|
||||||
|
public void setPackageName(String packageName) {
|
||||||
|
this.packageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the version
|
||||||
|
*/
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param version the version to set
|
||||||
|
*/
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the companyName
|
||||||
|
*/
|
||||||
|
public String getCompanyName() {
|
||||||
|
return companyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param companyName the companyName to set
|
||||||
|
*/
|
||||||
|
public void setCompanyName(String companyName) {
|
||||||
|
this.companyName = companyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the uninstallable
|
||||||
|
*/
|
||||||
|
public boolean isUninstallable() {
|
||||||
|
return uninstallable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uninstallable the uninstallable to set
|
||||||
|
*/
|
||||||
|
public void setUninstallable(boolean uninstallable) {
|
||||||
|
this.uninstallable = uninstallable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the description
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param description the description to set
|
||||||
|
*/
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the apkId
|
||||||
|
*/
|
||||||
|
public String getApkId() {
|
||||||
|
return apkId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param apkId the apkId to set
|
||||||
|
*/
|
||||||
|
public void setApkId(String apkId) {
|
||||||
|
this.apkId = apkId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileId
|
||||||
|
*/
|
||||||
|
public String getFileId() {
|
||||||
|
return fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileId the fileId to set
|
||||||
|
*/
|
||||||
|
public void setFileId(String fileId) {
|
||||||
|
this.fileId = fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileExt
|
||||||
|
*/
|
||||||
|
public String getFileExt() {
|
||||||
|
return fileExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileExt the fileExt to set
|
||||||
|
*/
|
||||||
|
public void setFileExt(String fileExt) {
|
||||||
|
this.fileExt = fileExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileCreateDate
|
||||||
|
*/
|
||||||
|
public Date getFileCreateDate() {
|
||||||
|
return fileCreateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileCreateDate the fileCreateDate to set
|
||||||
|
*/
|
||||||
|
public void setFileCreateDate(Date fileCreateDate) {
|
||||||
|
this.fileCreateDate = fileCreateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the checksum
|
||||||
|
*/
|
||||||
|
public String getChecksum() {
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param checksum the checksum to set
|
||||||
|
*/
|
||||||
|
public void setChecksum(String checksum) {
|
||||||
|
this.checksum = checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Application{");
|
||||||
|
sb.append("id=").append(id);
|
||||||
|
sb.append(", appName=").append(appName);
|
||||||
|
sb.append(", packageName=").append(packageName);
|
||||||
|
sb.append(", version=").append(version);
|
||||||
|
sb.append(", companyName=").append(companyName);
|
||||||
|
sb.append(", uninstallable=").append(uninstallable);
|
||||||
|
sb.append(", description=").append(description);
|
||||||
|
sb.append(", apkId=").append(apkId);
|
||||||
|
sb.append(", fileId=").append(fileId);
|
||||||
|
sb.append(", fileExt=").append(fileExt);
|
||||||
|
sb.append(", fileCreateDate=").append(fileCreateDate);
|
||||||
|
sb.append(", checksum=").append(checksum);
|
||||||
|
sb.append('}');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
146
src/id/iptek/utms/agent/model/ApplicationExt.java
Normal file
146
src/id/iptek/utms/agent/model/ApplicationExt.java
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class ApplicationExt extends Application {
|
||||||
|
|
||||||
|
private String uniqueName;
|
||||||
|
private String downloadUrl;
|
||||||
|
private Date downloadUrlExp;
|
||||||
|
private long fileSize;
|
||||||
|
private String uniqueIconName;
|
||||||
|
private String iconUrl;
|
||||||
|
private Date iconUrlExp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the uniqueName
|
||||||
|
*/
|
||||||
|
public String getUniqueName() {
|
||||||
|
return uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uniqueName the uniqueName to set
|
||||||
|
*/
|
||||||
|
public void setUniqueName(String uniqueName) {
|
||||||
|
this.uniqueName = uniqueName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the downloadUrl
|
||||||
|
*/
|
||||||
|
public String getDownloadUrl() {
|
||||||
|
return downloadUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param downloadUrl the downloadUrl to set
|
||||||
|
*/
|
||||||
|
public void setDownloadUrl(String downloadUrl) {
|
||||||
|
this.downloadUrl = downloadUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the downloadUrlExp
|
||||||
|
*/
|
||||||
|
public Date getDownloadUrlExp() {
|
||||||
|
return downloadUrlExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param downloadUrlExp the downloadUrlExp to set
|
||||||
|
*/
|
||||||
|
public void setDownloadUrlExp(Date downloadUrlExp) {
|
||||||
|
this.downloadUrlExp = downloadUrlExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fileSize
|
||||||
|
*/
|
||||||
|
public long getFileSize() {
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileSize the fileSize to set
|
||||||
|
*/
|
||||||
|
public void setFileSize(long fileSize) {
|
||||||
|
this.fileSize = fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the uniqueIconName
|
||||||
|
*/
|
||||||
|
public String getUniqueIconName() {
|
||||||
|
return uniqueIconName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uniqueIconName the uniqueIconName to set
|
||||||
|
*/
|
||||||
|
public void setUniqueIconName(String uniqueIconName) {
|
||||||
|
this.uniqueIconName = uniqueIconName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the iconUrl
|
||||||
|
*/
|
||||||
|
public String getIconUrl() {
|
||||||
|
return iconUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param iconUrl the iconUrl to set
|
||||||
|
*/
|
||||||
|
public void setIconUrl(String iconUrl) {
|
||||||
|
this.iconUrl = iconUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the iconUrlExp
|
||||||
|
*/
|
||||||
|
public Date getIconUrlExp() {
|
||||||
|
return iconUrlExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param iconUrlExp the iconUrlExp to set
|
||||||
|
*/
|
||||||
|
public void setIconUrlExp(Date iconUrlExp) {
|
||||||
|
this.iconUrlExp = iconUrlExp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("ApplicationExt{");
|
||||||
|
sb.append("id=").append(id);
|
||||||
|
sb.append(", appName=").append(appName);
|
||||||
|
sb.append(", packageName=").append(packageName);
|
||||||
|
sb.append(", version=").append(version);
|
||||||
|
sb.append(", companyName=").append(companyName);
|
||||||
|
sb.append(", uninstallable=").append(uninstallable);
|
||||||
|
sb.append(", description=").append(description);
|
||||||
|
sb.append(", apkId=").append(apkId);
|
||||||
|
sb.append(", fileId=").append(fileId);
|
||||||
|
sb.append(", fileExt=").append(fileExt);
|
||||||
|
sb.append(", fileCreateDate=").append(fileCreateDate);
|
||||||
|
sb.append(", checksum=").append(checksum);
|
||||||
|
sb.append(", uniqueName=").append(uniqueName);
|
||||||
|
sb.append(", downloadUrl=").append(downloadUrl);
|
||||||
|
sb.append(", downloadUrlExp=").append(downloadUrlExp);
|
||||||
|
sb.append(", fileSize=").append(fileSize);
|
||||||
|
sb.append(", uniqueIconName=").append(uniqueIconName);
|
||||||
|
sb.append(", iconUrl=").append(iconUrl);
|
||||||
|
sb.append(", iconUrlExp=").append(iconUrlExp);
|
||||||
|
sb.append('}');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
53
src/id/iptek/utms/agent/model/ApplicationSimple.java
Normal file
53
src/id/iptek/utms/agent/model/ApplicationSimple.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class ApplicationSimple {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
@SerializedName("app_name")
|
||||||
|
@Expose
|
||||||
|
private String appName;
|
||||||
|
@SerializedName("package_name")
|
||||||
|
@Expose
|
||||||
|
private String packageName;
|
||||||
|
@SerializedName("version")
|
||||||
|
@Expose
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppName() {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppName(String appName) {
|
||||||
|
this.appName = appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPackageName() {
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPackageName(String packageName) {
|
||||||
|
this.packageName = packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
55
src/id/iptek/utms/agent/model/CellInfo.java
Normal file
55
src/id/iptek/utms/agent/model/CellInfo.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class CellInfo {
|
||||||
|
|
||||||
|
@SerializedName("name")
|
||||||
|
@Expose
|
||||||
|
private String name;
|
||||||
|
@SerializedName("cid")
|
||||||
|
@Expose
|
||||||
|
private String cid;
|
||||||
|
@SerializedName("type")
|
||||||
|
@Expose
|
||||||
|
private String type;
|
||||||
|
@SerializedName("strength")
|
||||||
|
@Expose
|
||||||
|
private Integer strength;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCid() {
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCid(String cid) {
|
||||||
|
this.cid = cid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getStrength() {
|
||||||
|
return strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStrength(Integer strength) {
|
||||||
|
this.strength = strength;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
140
src/id/iptek/utms/agent/model/Diagnostic.java
Normal file
140
src/id/iptek/utms/agent/model/Diagnostic.java
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class Diagnostic {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
@SerializedName("req_id")
|
||||||
|
@Expose
|
||||||
|
private String reqId;
|
||||||
|
@SerializedName("req_type")
|
||||||
|
@Expose
|
||||||
|
private String reqType;
|
||||||
|
@SerializedName("req_time")
|
||||||
|
@Expose
|
||||||
|
private String reqTime;
|
||||||
|
@SerializedName("device_sn")
|
||||||
|
@Expose
|
||||||
|
private String deviceSn;
|
||||||
|
@SerializedName("diagnostic_info")
|
||||||
|
@Expose
|
||||||
|
private DiagnosticInfo diagnosticInfo;
|
||||||
|
@SerializedName("location_info")
|
||||||
|
@Expose
|
||||||
|
private LocationInfo locationInfo;
|
||||||
|
@SerializedName("cell_info")
|
||||||
|
@Expose
|
||||||
|
private List<CellInfo> cellInfo;
|
||||||
|
@SerializedName("installed_apps")
|
||||||
|
@Expose
|
||||||
|
private List<ApplicationSimple> installedApps = null;
|
||||||
|
private Date createTime;
|
||||||
|
private String terminalId;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReqId() {
|
||||||
|
return reqId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReqId(String reqId) {
|
||||||
|
this.reqId = reqId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReqType() {
|
||||||
|
return reqType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReqType(String reqType) {
|
||||||
|
this.reqType = reqType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReqTime() {
|
||||||
|
return reqTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReqTime(String reqTime) {
|
||||||
|
this.reqTime = reqTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceSn() {
|
||||||
|
return deviceSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceSn(String deviceSn) {
|
||||||
|
this.deviceSn = deviceSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiagnosticInfo getDiagnosticInfo() {
|
||||||
|
return diagnosticInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiagnosticInfo(DiagnosticInfo diagnosticInfo) {
|
||||||
|
this.diagnosticInfo = diagnosticInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationInfo getLocationInfo() {
|
||||||
|
return locationInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocationInfo(LocationInfo locationInfo) {
|
||||||
|
this.locationInfo = locationInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CellInfo> getCellInfo() {
|
||||||
|
return cellInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellInfo(List<CellInfo> cellInfo) {
|
||||||
|
this.cellInfo = cellInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApplicationSimple> getInstalledApps() {
|
||||||
|
return installedApps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstalledApps(List<ApplicationSimple> installedApps) {
|
||||||
|
this.installedApps = installedApps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the createTime
|
||||||
|
*/
|
||||||
|
public Date getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param createTime the createTime to set
|
||||||
|
*/
|
||||||
|
public void setCreateTime(Date createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalId
|
||||||
|
*/
|
||||||
|
public String getTerminalId() {
|
||||||
|
return terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalId the terminalId to set
|
||||||
|
*/
|
||||||
|
public void setTerminalId(String terminalId) {
|
||||||
|
this.terminalId = terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
246
src/id/iptek/utms/agent/model/DiagnosticInfo.java
Normal file
246
src/id/iptek/utms/agent/model/DiagnosticInfo.java
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class DiagnosticInfo {
|
||||||
|
|
||||||
|
@SerializedName("imei")
|
||||||
|
@Expose
|
||||||
|
private String imei;
|
||||||
|
@SerializedName("meid")
|
||||||
|
@Expose
|
||||||
|
private String meid;
|
||||||
|
@SerializedName("battery_temp")
|
||||||
|
@Expose
|
||||||
|
private double batteryTemp;
|
||||||
|
@SerializedName("battery_percentage")
|
||||||
|
@Expose
|
||||||
|
private double batteryPercentage;
|
||||||
|
@SerializedName("total_memory")
|
||||||
|
@Expose
|
||||||
|
private String totalMemory;
|
||||||
|
@SerializedName("available_memory")
|
||||||
|
@Expose
|
||||||
|
private String availableMemory;
|
||||||
|
@SerializedName("total_flash_memory")
|
||||||
|
@Expose
|
||||||
|
private String totalFlashMemory;
|
||||||
|
@SerializedName("available_flash_memory")
|
||||||
|
@Expose
|
||||||
|
private String availableFlashMemory;
|
||||||
|
@SerializedName("total_mobile_data")
|
||||||
|
@Expose
|
||||||
|
private String totalMobileData;
|
||||||
|
@SerializedName("switching_times")
|
||||||
|
@Expose
|
||||||
|
private int switchingTimes;
|
||||||
|
@SerializedName("current_boot_time")
|
||||||
|
@Expose
|
||||||
|
private int currentBootTime;
|
||||||
|
@SerializedName("total_boot_time")
|
||||||
|
@Expose
|
||||||
|
private int totalBootTime;
|
||||||
|
@SerializedName("total_length_printed")
|
||||||
|
@Expose
|
||||||
|
private double totalLengthPrinted;
|
||||||
|
@SerializedName("swiping_card_times")
|
||||||
|
@Expose
|
||||||
|
private int swipingCardTimes;
|
||||||
|
@SerializedName("dip_inserting_times")
|
||||||
|
@Expose
|
||||||
|
private int dipInsertingTimes;
|
||||||
|
@SerializedName("nfc_card_reading_times")
|
||||||
|
@Expose
|
||||||
|
private int nfcCardReadingTimes;
|
||||||
|
@SerializedName("front_camera_open_times")
|
||||||
|
@Expose
|
||||||
|
private int frontCameraOpenTimes;
|
||||||
|
@SerializedName("rear_camera_open_times")
|
||||||
|
@Expose
|
||||||
|
private int rearCameraOpenTimes;
|
||||||
|
@SerializedName("charge_times")
|
||||||
|
@Expose
|
||||||
|
private int chargeTimes;
|
||||||
|
@SerializedName("new_diagnostic")
|
||||||
|
@Expose
|
||||||
|
private Boolean newDiagnostic;
|
||||||
|
private String installedAppString;
|
||||||
|
|
||||||
|
public String getImei() {
|
||||||
|
return imei;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImei(String imei) {
|
||||||
|
this.imei = imei;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMeid() {
|
||||||
|
return meid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMeid(String meid) {
|
||||||
|
this.meid = meid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBatteryTemp() {
|
||||||
|
return batteryTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatteryTemp(double batteryTemp) {
|
||||||
|
this.batteryTemp = batteryTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBatteryPercentage() {
|
||||||
|
return batteryPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatteryPercentage(double batteryPercentage) {
|
||||||
|
this.batteryPercentage = batteryPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotalMemory() {
|
||||||
|
return totalMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalMemory(String totalMemory) {
|
||||||
|
this.totalMemory = totalMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvailableMemory() {
|
||||||
|
return availableMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailableMemory(String availableMemory) {
|
||||||
|
this.availableMemory = availableMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotalFlashMemory() {
|
||||||
|
return totalFlashMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalFlashMemory(String totalFlashMemory) {
|
||||||
|
this.totalFlashMemory = totalFlashMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvailableFlashMemory() {
|
||||||
|
return availableFlashMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailableFlashMemory(String availableFlashMemory) {
|
||||||
|
this.availableFlashMemory = availableFlashMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotalMobileData() {
|
||||||
|
return totalMobileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalMobileData(String totalMobileData) {
|
||||||
|
this.totalMobileData = totalMobileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSwitchingTimes() {
|
||||||
|
return switchingTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSwitchingTimes(int switchingTimes) {
|
||||||
|
this.switchingTimes = switchingTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentBootTime() {
|
||||||
|
return currentBootTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentBootTime(int currentBootTime) {
|
||||||
|
this.currentBootTime = currentBootTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalBootTime() {
|
||||||
|
return totalBootTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalBootTime(int totalBootTime) {
|
||||||
|
this.totalBootTime = totalBootTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTotalLengthPrinted() {
|
||||||
|
return totalLengthPrinted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalLengthPrinted(double totalLengthPrinted) {
|
||||||
|
this.totalLengthPrinted = totalLengthPrinted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSwipingCardTimes() {
|
||||||
|
return swipingCardTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSwipingCardTimes(int swipingCardTimes) {
|
||||||
|
this.swipingCardTimes = swipingCardTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDipInsertingTimes() {
|
||||||
|
return dipInsertingTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDipInsertingTimes(int dipInsertingTimes) {
|
||||||
|
this.dipInsertingTimes = dipInsertingTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNfcCardReadingTimes() {
|
||||||
|
return nfcCardReadingTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNfcCardReadingTimes(int nfcCardReadingTimes) {
|
||||||
|
this.nfcCardReadingTimes = nfcCardReadingTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFrontCameraOpenTimes() {
|
||||||
|
return frontCameraOpenTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFrontCameraOpenTimes(int frontCameraOpenTimes) {
|
||||||
|
this.frontCameraOpenTimes = frontCameraOpenTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRearCameraOpenTimes() {
|
||||||
|
return rearCameraOpenTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRearCameraOpenTimes(int rearCameraOpenTimes) {
|
||||||
|
this.rearCameraOpenTimes = rearCameraOpenTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChargeTimes() {
|
||||||
|
return chargeTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChargeTimes(int chargeTimes) {
|
||||||
|
this.chargeTimes = chargeTimes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getNewDiagnostic() {
|
||||||
|
return newDiagnostic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewDiagnostic(Boolean newDiagnostic) {
|
||||||
|
this.newDiagnostic = newDiagnostic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the installedAppString
|
||||||
|
*/
|
||||||
|
public String getInstalledAppString() {
|
||||||
|
return installedAppString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param installedAppString the installedAppString to set
|
||||||
|
*/
|
||||||
|
public void setInstalledAppString(String installedAppString) {
|
||||||
|
this.installedAppString = installedAppString;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
176
src/id/iptek/utms/agent/model/DownloadTask.java
Normal file
176
src/id/iptek/utms/agent/model/DownloadTask.java
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.model.enumeration.DownloadTimeType;
|
||||||
|
import id.iptek.utms.agent.model.enumeration.InstallationNotificationType;
|
||||||
|
import id.iptek.utms.agent.model.enumeration.InstallationTimeType;
|
||||||
|
import id.iptek.utms.agent.model.enumeration.PublishTimeType;
|
||||||
|
import id.iptek.utms.agent.model.enumeration.TaskStatus;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class DownloadTask implements Serializable {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private PublishTimeType publishTimeType;
|
||||||
|
private Date publishTime;
|
||||||
|
private DownloadTimeType downloadTimeType;
|
||||||
|
private Date downloadTime;
|
||||||
|
private InstallationTimeType installationTimeType;
|
||||||
|
private Date installationTime;
|
||||||
|
private InstallationNotificationType installationNotification;
|
||||||
|
private TaskStatus status;
|
||||||
|
|
||||||
|
public DownloadTask() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the publishTimeType
|
||||||
|
*/
|
||||||
|
public PublishTimeType getPublishTimeType() {
|
||||||
|
return publishTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param publishTimeType the publishTimeType to set
|
||||||
|
*/
|
||||||
|
public void setPublishTimeType(int publishTimeType) {
|
||||||
|
this.publishTimeType = PublishTimeType.fromValue(publishTimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the publishTime
|
||||||
|
*/
|
||||||
|
public Date getPublishTime() {
|
||||||
|
return publishTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param publishTime the publishTime to set
|
||||||
|
*/
|
||||||
|
public void setPublishTime(Date publishTime) {
|
||||||
|
this.publishTime = publishTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the downloadTimeType
|
||||||
|
*/
|
||||||
|
public DownloadTimeType getDownloadTimeType() {
|
||||||
|
return downloadTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param downloadTimeType the downloadTimeType to set
|
||||||
|
*/
|
||||||
|
public void setDownloadTimeType(int downloadTimeType) {
|
||||||
|
this.downloadTimeType = DownloadTimeType.fromValue(downloadTimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the downloadTime
|
||||||
|
*/
|
||||||
|
public Date getDownloadTime() {
|
||||||
|
return downloadTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param downloadTime the downloadTime to set
|
||||||
|
*/
|
||||||
|
public void setDownloadTime(Date downloadTime) {
|
||||||
|
this.downloadTime = downloadTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the installationTimeType
|
||||||
|
*/
|
||||||
|
public InstallationTimeType getInstallationTimeType() {
|
||||||
|
return installationTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param installationTimeType the installationTimeType to set
|
||||||
|
*/
|
||||||
|
public void setInstallationTimeType(int installationTimeType) {
|
||||||
|
this.installationTimeType = InstallationTimeType.fromValue(installationTimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the installationTime
|
||||||
|
*/
|
||||||
|
public Date getInstallationTime() {
|
||||||
|
return installationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param installationTime the installationTime to set
|
||||||
|
*/
|
||||||
|
public void setInstallationTime(Date installationTime) {
|
||||||
|
this.installationTime = installationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the installationNotification
|
||||||
|
*/
|
||||||
|
public InstallationNotificationType getInstallationNotification() {
|
||||||
|
return installationNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param installationNotification the installationNotification to set
|
||||||
|
*/
|
||||||
|
public void setInstallationNotification(int installationNotification) {
|
||||||
|
this.installationNotification = InstallationNotificationType.fromValue(installationNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the status
|
||||||
|
*/
|
||||||
|
public TaskStatus getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param status the status to set
|
||||||
|
*/
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = TaskStatus.fromValue(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DownloadTask{" + "id=" + id + ", name=" + name + ", publishTimeType=" + publishTimeType + ", publishTime=" + publishTime + ", downloadTimeType=" + downloadTimeType + ", downloadTime=" + downloadTime + ", installationTimeType=" + installationTimeType + ", installationTime=" + installationTime + ", installationNotification=" + installationNotification + ", status=" + status + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
75
src/id/iptek/utms/agent/model/FileReaderCacheObj.java
Normal file
75
src/id/iptek/utms/agent/model/FileReaderCacheObj.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class FileReaderCacheObj implements Serializable {
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private BufferedReader reader;
|
||||||
|
private final AtomicInteger currentReadRowNum = new AtomicInteger(0);
|
||||||
|
|
||||||
|
public FileReaderCacheObj() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the file
|
||||||
|
*/
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param file the file to set
|
||||||
|
*/
|
||||||
|
public void setFile(File file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reader
|
||||||
|
*/
|
||||||
|
public BufferedReader getReader() {
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the currentReadRowNum
|
||||||
|
*/
|
||||||
|
public AtomicInteger getCurrentReadRowNum() {
|
||||||
|
return currentReadRowNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pointToFile(File file) throws IOException {
|
||||||
|
if(file == null) {
|
||||||
|
throw new IllegalArgumentException("File cannot be null!");
|
||||||
|
}
|
||||||
|
if(!file.exists()) {
|
||||||
|
throw new IOException("File not exists!");
|
||||||
|
}
|
||||||
|
if(!file.canRead()) {
|
||||||
|
throw new IOException("File not readable!");
|
||||||
|
}
|
||||||
|
this.file = file;
|
||||||
|
this.reader = new BufferedReader(new FileReader(this.file));
|
||||||
|
this.currentReadRowNum.set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeReader() throws IOException {
|
||||||
|
if(this.reader != null) {
|
||||||
|
this.reader.close();
|
||||||
|
this.file = null;
|
||||||
|
this.currentReadRowNum.set(0);
|
||||||
|
} else {
|
||||||
|
// ignore null reader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
118
src/id/iptek/utms/agent/model/FileWriterCacheObj.java
Normal file
118
src/id/iptek/utms/agent/model/FileWriterCacheObj.java
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class FileWriterCacheObj implements Serializable {
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private BufferedWriter writer;
|
||||||
|
private final AtomicInteger currentWriteRowNum = new AtomicInteger(0);
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
public FileWriterCacheObj() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the file
|
||||||
|
*/
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param file the file to set
|
||||||
|
*/
|
||||||
|
public void setFile(File file) {
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reader
|
||||||
|
*/
|
||||||
|
public BufferedWriter getWriter() {
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the currentReadRowNum
|
||||||
|
*/
|
||||||
|
public AtomicInteger getCurrentWriteRowNum() {
|
||||||
|
return currentWriteRowNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pointToFile(File file) throws IOException {
|
||||||
|
if(file == null) {
|
||||||
|
throw new IllegalArgumentException("File cannot be null!");
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if(file.exists()) {
|
||||||
|
throw new IOException("File exists!");
|
||||||
|
}
|
||||||
|
if(!file.canWrite()) {
|
||||||
|
throw new IOException("File not writable!");
|
||||||
|
}*/
|
||||||
|
// close old writer
|
||||||
|
synchronized (lock) {
|
||||||
|
if(this.writer != null) {
|
||||||
|
this.writer.flush();
|
||||||
|
try {
|
||||||
|
this.writer.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
this.writer = null;
|
||||||
|
}
|
||||||
|
this.file = file;
|
||||||
|
this.writer = new BufferedWriter(new FileWriter(this.file));
|
||||||
|
this.currentWriteRowNum.set(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeWriter() throws IOException {
|
||||||
|
if(this.writer != null) {
|
||||||
|
synchronized (lock) {
|
||||||
|
this.writer.close();
|
||||||
|
this.file = null;
|
||||||
|
this.currentWriteRowNum.set(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ignore null reader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedWriter writeLine(String line) throws IOException {
|
||||||
|
if(this.writer == null) {
|
||||||
|
throw new IOException("Writer cannot be null!");
|
||||||
|
}
|
||||||
|
synchronized (lock) {
|
||||||
|
this.writer.write(line);
|
||||||
|
this.writer.newLine();
|
||||||
|
this.writer.flush();
|
||||||
|
}
|
||||||
|
this.currentWriteRowNum.incrementAndGet();
|
||||||
|
return this.writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean writeLineWithMaxLineNo(int maxLineNo, String line) throws IOException {
|
||||||
|
if(this.writer == null) {
|
||||||
|
throw new IOException("Writer cannot be null!");
|
||||||
|
}
|
||||||
|
if(this.currentWriteRowNum.get() < maxLineNo) {
|
||||||
|
synchronized (lock) {
|
||||||
|
this.writer.write(line);
|
||||||
|
this.writer.newLine();
|
||||||
|
this.writer.flush();
|
||||||
|
}
|
||||||
|
this.currentWriteRowNum.incrementAndGet();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
200
src/id/iptek/utms/agent/model/HeartBeat.java
Normal file
200
src/id/iptek/utms/agent/model/HeartBeat.java
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class HeartBeat {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
@SerializedName("req_id")
|
||||||
|
@Expose
|
||||||
|
private String reqId;
|
||||||
|
@SerializedName("req_type")
|
||||||
|
@Expose
|
||||||
|
private String reqType;
|
||||||
|
@SerializedName("req_time")
|
||||||
|
@Expose
|
||||||
|
private String reqTime;
|
||||||
|
@SerializedName("device_sn")
|
||||||
|
@Expose
|
||||||
|
private String deviceSn;
|
||||||
|
@SerializedName("diagnostic_info")
|
||||||
|
@Expose
|
||||||
|
private DiagnosticInfo diagnosticInfo;
|
||||||
|
@SerializedName("location_info")
|
||||||
|
@Expose
|
||||||
|
private LocationInfo locationInfo;
|
||||||
|
@SerializedName("cell_info")
|
||||||
|
@Expose
|
||||||
|
private List<CellInfo> cellInfo;
|
||||||
|
private File fileLocation;
|
||||||
|
private Date createTime;
|
||||||
|
private String terminalId;
|
||||||
|
private String cellInfoString;
|
||||||
|
@Expose
|
||||||
|
@SerializedName("cell_type")
|
||||||
|
private String cellType;
|
||||||
|
@Expose
|
||||||
|
@SerializedName("cell_name")
|
||||||
|
private String cellName;
|
||||||
|
@Expose
|
||||||
|
@SerializedName("cell_strength")
|
||||||
|
private Integer cellStrength;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReqId() {
|
||||||
|
return reqId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReqId(String reqId) {
|
||||||
|
this.reqId = reqId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReqType() {
|
||||||
|
return reqType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReqType(String reqType) {
|
||||||
|
this.reqType = reqType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReqTime() {
|
||||||
|
return reqTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReqTime(String reqTime) {
|
||||||
|
this.reqTime = reqTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeviceSn() {
|
||||||
|
return deviceSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeviceSn(String deviceSn) {
|
||||||
|
this.deviceSn = deviceSn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiagnosticInfo getDiagnosticInfo() {
|
||||||
|
return diagnosticInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiagnosticInfo(DiagnosticInfo diagnosticInfo) {
|
||||||
|
this.diagnosticInfo = diagnosticInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationInfo getLocationInfo() {
|
||||||
|
return locationInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocationInfo(LocationInfo locationInfo) {
|
||||||
|
this.locationInfo = locationInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CellInfo> getCellInfo() {
|
||||||
|
return cellInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellInfo(List<CellInfo> cellInfo) {
|
||||||
|
this.cellInfo = cellInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFileLocation() {
|
||||||
|
return fileLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileLocation(File fileLocation) {
|
||||||
|
this.fileLocation = fileLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Date createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalId
|
||||||
|
*/
|
||||||
|
public String getTerminalId() {
|
||||||
|
return terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalId the terminalId to set
|
||||||
|
*/
|
||||||
|
public void setTerminalId(String terminalId) {
|
||||||
|
this.terminalId = terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cellInfoString
|
||||||
|
*/
|
||||||
|
public String getCellInfoString() {
|
||||||
|
return cellInfoString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cellInfoString the cellInfoString to set
|
||||||
|
*/
|
||||||
|
public void setCellInfoString(String cellInfoString) {
|
||||||
|
this.cellInfoString = cellInfoString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cellType
|
||||||
|
*/
|
||||||
|
public String getCellType() {
|
||||||
|
return cellType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cellType the cellType to set
|
||||||
|
*/
|
||||||
|
public void setCellType(String cellType) {
|
||||||
|
this.cellType = cellType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cellName
|
||||||
|
*/
|
||||||
|
public String getCellName() {
|
||||||
|
return cellName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cellName the cellName to set
|
||||||
|
*/
|
||||||
|
public void setCellName(String cellName) {
|
||||||
|
this.cellName = cellName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cellStrength
|
||||||
|
*/
|
||||||
|
public Integer getCellStrength() {
|
||||||
|
return cellStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param cellStrength the cellStrength to set
|
||||||
|
*/
|
||||||
|
public void setCellStrength(Integer cellStrength) {
|
||||||
|
this.cellStrength = cellStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
34
src/id/iptek/utms/agent/model/LocationInfo.java
Normal file
34
src/id/iptek/utms/agent/model/LocationInfo.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
@Generated("jsonschema2pojo")
|
||||||
|
public class LocationInfo {
|
||||||
|
|
||||||
|
@SerializedName("lat")
|
||||||
|
@Expose
|
||||||
|
private Double lat;
|
||||||
|
@SerializedName("lng")
|
||||||
|
@Expose
|
||||||
|
private Double lng;
|
||||||
|
|
||||||
|
public Double getLat() {
|
||||||
|
return lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLat(Double lat) {
|
||||||
|
this.lat = lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getLng() {
|
||||||
|
return lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLng(Double lng) {
|
||||||
|
this.lng = lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
130
src/id/iptek/utms/agent/model/PendingDeleteTask.java
Normal file
130
src/id/iptek/utms/agent/model/PendingDeleteTask.java
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class PendingDeleteTask implements Serializable {
|
||||||
|
|
||||||
|
private String terminalSN;
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private Date deleteTime;
|
||||||
|
private Date lastBroadcastTs;
|
||||||
|
private ApplicationSimple app;
|
||||||
|
private int activity;
|
||||||
|
private String logId;
|
||||||
|
|
||||||
|
public PendingDeleteTask() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalSN
|
||||||
|
*/
|
||||||
|
public String getTerminalSN() {
|
||||||
|
return terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalSN the terminalSN to set
|
||||||
|
*/
|
||||||
|
public void setTerminalSN(String terminalSN) {
|
||||||
|
this.terminalSN = terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the deleteTime
|
||||||
|
*/
|
||||||
|
public Date getDeleteTime() {
|
||||||
|
return deleteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param deleteTime the deleteTime to set
|
||||||
|
*/
|
||||||
|
public void setDeleteTime(Date deleteTime) {
|
||||||
|
this.deleteTime = deleteTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastBroadcastTs
|
||||||
|
*/
|
||||||
|
public Date getLastBroadcastTs() {
|
||||||
|
return lastBroadcastTs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastBroadcastTs the lastBroadcastTs to set
|
||||||
|
*/
|
||||||
|
public void setLastBroadcastTs(Date lastBroadcastTs) {
|
||||||
|
this.lastBroadcastTs = lastBroadcastTs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the app
|
||||||
|
*/
|
||||||
|
public ApplicationSimple getApp() {
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param app the app to set
|
||||||
|
*/
|
||||||
|
public void setApp(ApplicationSimple app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the activity
|
||||||
|
*/
|
||||||
|
public int getActivity() {
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param activity the activity to set
|
||||||
|
*/
|
||||||
|
public void setActivity(int activity) {
|
||||||
|
this.activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogId() {
|
||||||
|
return logId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogId(String logId) {
|
||||||
|
this.logId = logId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
234
src/id/iptek/utms/agent/model/PendingDownloadTask.java
Normal file
234
src/id/iptek/utms/agent/model/PendingDownloadTask.java
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class PendingDownloadTask implements Serializable {
|
||||||
|
|
||||||
|
private String terminalSN;
|
||||||
|
private String terminalGroupId;
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private int downloadTimeType;
|
||||||
|
private Date downloadTime;
|
||||||
|
private int installationTimeType;
|
||||||
|
private Date installationTime;
|
||||||
|
private int installationNotification;
|
||||||
|
private Date lastBroadcastTs;
|
||||||
|
private int activity;
|
||||||
|
private String logId;
|
||||||
|
private Application app;
|
||||||
|
|
||||||
|
public PendingDownloadTask() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalSN
|
||||||
|
*/
|
||||||
|
public String getTerminalSN() {
|
||||||
|
return terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalSN the terminalSN to set
|
||||||
|
*/
|
||||||
|
public void setTerminalSN(String terminalSN) {
|
||||||
|
this.terminalSN = terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalGroupId
|
||||||
|
*/
|
||||||
|
public String getTerminalGroupId() {
|
||||||
|
return terminalGroupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalGroupId the terminalGroupId to set
|
||||||
|
*/
|
||||||
|
public void setTerminalGroupId(String terminalGroupId) {
|
||||||
|
this.terminalGroupId = terminalGroupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the downloadTimeType
|
||||||
|
*/
|
||||||
|
public int getDownloadTimeType() {
|
||||||
|
return downloadTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param downloadTimeType the downloadTimeType to set
|
||||||
|
*/
|
||||||
|
public void setDownloadTimeType(int downloadTimeType) {
|
||||||
|
this.downloadTimeType = downloadTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the downloadTime
|
||||||
|
*/
|
||||||
|
public Date getDownloadTime() {
|
||||||
|
return downloadTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param downloadTime the downloadTime to set
|
||||||
|
*/
|
||||||
|
public void setDownloadTime(Date downloadTime) {
|
||||||
|
this.downloadTime = downloadTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the installationTimeType
|
||||||
|
*/
|
||||||
|
public int getInstallationTimeType() {
|
||||||
|
return installationTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param installationTimeType the installationTimeType to set
|
||||||
|
*/
|
||||||
|
public void setInstallationTimeType(int installationTimeType) {
|
||||||
|
this.installationTimeType = installationTimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the installationTime
|
||||||
|
*/
|
||||||
|
public Date getInstallationTime() {
|
||||||
|
return installationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param installationTime the installationTime to set
|
||||||
|
*/
|
||||||
|
public void setInstallationTime(Date installationTime) {
|
||||||
|
this.installationTime = installationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the installationNotification
|
||||||
|
*/
|
||||||
|
public int getInstallationNotification() {
|
||||||
|
return installationNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param installationNotification the installationNotification to set
|
||||||
|
*/
|
||||||
|
public void setInstallationNotification(int installationNotification) {
|
||||||
|
this.installationNotification = installationNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the lastBroadcastTs
|
||||||
|
*/
|
||||||
|
public Date getLastBroadcastTs() {
|
||||||
|
return lastBroadcastTs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param lastBroadcastTs the lastBroadcastTs to set
|
||||||
|
*/
|
||||||
|
public void setLastBroadcastTs(Date lastBroadcastTs) {
|
||||||
|
this.lastBroadcastTs = lastBroadcastTs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the activity
|
||||||
|
*/
|
||||||
|
public int getActivity() {
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param activity the activity to set
|
||||||
|
*/
|
||||||
|
public void setActivity(int activity) {
|
||||||
|
this.activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the logId
|
||||||
|
*/
|
||||||
|
public String getLogId() {
|
||||||
|
return logId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param logId the logId to set
|
||||||
|
*/
|
||||||
|
public void setLogId(String logId) {
|
||||||
|
this.logId = logId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the app
|
||||||
|
*/
|
||||||
|
public Application getApp() {
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param app the app to set
|
||||||
|
*/
|
||||||
|
public void setApp(Application app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("PendingDownloadTask{");
|
||||||
|
sb.append("terminalSN=").append(terminalSN);
|
||||||
|
sb.append(", terminalGroupId=").append(terminalGroupId);
|
||||||
|
sb.append(", id=").append(id);
|
||||||
|
sb.append(", name=").append(name);
|
||||||
|
sb.append(", downloadTimeType=").append(downloadTimeType);
|
||||||
|
sb.append(", downloadTime=").append(downloadTime);
|
||||||
|
sb.append(", installationTimeType=").append(installationTimeType);
|
||||||
|
sb.append(", installationTime=").append(installationTime);
|
||||||
|
sb.append(", installationNotification=").append(installationNotification);
|
||||||
|
sb.append(", lastBroadcastTs=").append(lastBroadcastTs);
|
||||||
|
sb.append(", activity=").append(activity);
|
||||||
|
sb.append(", logId=").append(logId);
|
||||||
|
sb.append(", app=").append(app);
|
||||||
|
sb.append('}');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
257
src/id/iptek/utms/agent/model/Profile.java
Normal file
257
src/id/iptek/utms/agent/model/Profile.java
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class Profile implements Serializable {
|
||||||
|
|
||||||
|
private String terminalSN;
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private int heartbeatInterval;
|
||||||
|
private int diagnosticInterval;
|
||||||
|
private boolean maskHomeButton;
|
||||||
|
private boolean maskStatusButton;
|
||||||
|
private boolean scheduleReboot;
|
||||||
|
private Date scheduleRebootTime;
|
||||||
|
private boolean isDefault;
|
||||||
|
private boolean relocationAlert;
|
||||||
|
private int movingThreshold;
|
||||||
|
private String adminPassword;
|
||||||
|
private String frontApp;
|
||||||
|
private List<String> groupIds;
|
||||||
|
private List<String> apps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalSN
|
||||||
|
*/
|
||||||
|
public String getTerminalSN() {
|
||||||
|
return terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalSN the terminalSN to set
|
||||||
|
*/
|
||||||
|
public void setTerminalSN(String terminalSN) {
|
||||||
|
this.terminalSN = terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the heartbeatInterval
|
||||||
|
*/
|
||||||
|
public int getHeartbeatInterval() {
|
||||||
|
return heartbeatInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param heartbeatInterval the heartbeatInterval to set
|
||||||
|
*/
|
||||||
|
public void setHeartbeatInterval(int heartbeatInterval) {
|
||||||
|
this.heartbeatInterval = heartbeatInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the diagnosticInterval
|
||||||
|
*/
|
||||||
|
public int getDiagnosticInterval() {
|
||||||
|
return diagnosticInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param diagnosticInterval the diagnosticInterval to set
|
||||||
|
*/
|
||||||
|
public void setDiagnosticInterval(int diagnosticInterval) {
|
||||||
|
this.diagnosticInterval = diagnosticInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maskHomeButton
|
||||||
|
*/
|
||||||
|
public boolean isMaskHomeButton() {
|
||||||
|
return maskHomeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maskHomeButton the maskHomeButton to set
|
||||||
|
*/
|
||||||
|
public void setMaskHomeButton(boolean maskHomeButton) {
|
||||||
|
this.maskHomeButton = maskHomeButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maskStatusButton
|
||||||
|
*/
|
||||||
|
public boolean isMaskStatusButton() {
|
||||||
|
return maskStatusButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maskStatusButton the maskStatusButton to set
|
||||||
|
*/
|
||||||
|
public void setMaskStatusButton(boolean maskStatusButton) {
|
||||||
|
this.maskStatusButton = maskStatusButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the scheduleReboot
|
||||||
|
*/
|
||||||
|
public boolean isScheduleReboot() {
|
||||||
|
return scheduleReboot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param scheduleReboot the scheduleReboot to set
|
||||||
|
*/
|
||||||
|
public void setScheduleReboot(boolean scheduleReboot) {
|
||||||
|
this.scheduleReboot = scheduleReboot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the scheduleRebootTime
|
||||||
|
*/
|
||||||
|
public Date getScheduleRebootTime() {
|
||||||
|
return scheduleRebootTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param scheduleRebootTime the scheduleRebootTime to set
|
||||||
|
*/
|
||||||
|
public void setScheduleRebootTime(Date scheduleRebootTime) {
|
||||||
|
this.scheduleRebootTime = scheduleRebootTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the isDefault
|
||||||
|
*/
|
||||||
|
public boolean isDefault() {
|
||||||
|
return isDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isDefault the isDefault to set
|
||||||
|
*/
|
||||||
|
public void setDefault(boolean isDefault) {
|
||||||
|
this.isDefault = isDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the relocationAlert
|
||||||
|
*/
|
||||||
|
public boolean isRelocationAlert() {
|
||||||
|
return relocationAlert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param relocationAlert the relocationAlert to set
|
||||||
|
*/
|
||||||
|
public void setRelocationAlert(boolean relocationAlert) {
|
||||||
|
this.relocationAlert = relocationAlert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the movingThreshold
|
||||||
|
*/
|
||||||
|
public int getMovingThreshold() {
|
||||||
|
return movingThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param movingThreshold the movingThreshold to set
|
||||||
|
*/
|
||||||
|
public void setMovingThreshold(int movingThreshold) {
|
||||||
|
this.movingThreshold = movingThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the adminPassword
|
||||||
|
*/
|
||||||
|
public String getAdminPassword() {
|
||||||
|
return adminPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param adminPassword the adminPassword to set
|
||||||
|
*/
|
||||||
|
public void setAdminPassword(String adminPassword) {
|
||||||
|
this.adminPassword = adminPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the frontApp
|
||||||
|
*/
|
||||||
|
public String getFrontApp() {
|
||||||
|
return frontApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param frontApp the frontApp to set
|
||||||
|
*/
|
||||||
|
public void setFrontApp(String frontApp) {
|
||||||
|
this.frontApp = frontApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the apps
|
||||||
|
*/
|
||||||
|
public List<String> getApps() {
|
||||||
|
if(apps == null) {
|
||||||
|
apps = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param apps the apps to set
|
||||||
|
*/
|
||||||
|
public void setApps(List<String> apps) {
|
||||||
|
this.apps = apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the groupIds
|
||||||
|
*/
|
||||||
|
public List<String> getGroupIds() {
|
||||||
|
return groupIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param groupIds the groupIds to set
|
||||||
|
*/
|
||||||
|
public void setGroupIds(List<String> groupIds) {
|
||||||
|
this.groupIds = groupIds;
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/id/iptek/utms/agent/model/SimplePendingDownloadTask.java
Normal file
61
src/id/iptek/utms/agent/model/SimplePendingDownloadTask.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class SimplePendingDownloadTask implements Serializable {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
private List<String> groupIds;
|
||||||
|
|
||||||
|
public SimplePendingDownloadTask() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name the name to set
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the groupIds
|
||||||
|
*/
|
||||||
|
public List<String> getGroupIds() {
|
||||||
|
return groupIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param groupIds the groupIds to set
|
||||||
|
*/
|
||||||
|
public void setGroupIds(List<String> groupIds) {
|
||||||
|
this.groupIds = groupIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
120
src/id/iptek/utms/agent/model/TaskAckReq.java
Normal file
120
src/id/iptek/utms/agent/model/TaskAckReq.java
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class TaskAckReq implements Serializable {
|
||||||
|
|
||||||
|
private String reqId;
|
||||||
|
private String terminalSN;
|
||||||
|
private String ackId;
|
||||||
|
private String terminalId;
|
||||||
|
private int activity;
|
||||||
|
private String message;
|
||||||
|
private String taskId;
|
||||||
|
private String terminalGroupId;
|
||||||
|
private boolean broadcasted;
|
||||||
|
|
||||||
|
public TaskAckReq() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the reqId
|
||||||
|
*/
|
||||||
|
public String getReqId() {
|
||||||
|
return reqId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param reqId the reqId to set
|
||||||
|
*/
|
||||||
|
public void setReqId(String reqId) {
|
||||||
|
this.reqId = reqId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalSN
|
||||||
|
*/
|
||||||
|
public String getTerminalSN() {
|
||||||
|
return terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalSN the terminalSN to set
|
||||||
|
*/
|
||||||
|
public void setTerminalSN(String terminalSN) {
|
||||||
|
this.terminalSN = terminalSN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ackId
|
||||||
|
*/
|
||||||
|
public String getAckId() {
|
||||||
|
return ackId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ackId the ackId to set
|
||||||
|
*/
|
||||||
|
public void setAckId(String ackId) {
|
||||||
|
this.ackId = ackId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTerminalId() {
|
||||||
|
return terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTerminalId(String terminalId) {
|
||||||
|
this.terminalId = terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTerminalGroupId() {
|
||||||
|
return terminalGroupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTerminalGroupId(String terminalGroupId) {
|
||||||
|
this.terminalGroupId = terminalGroupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getActivity() {
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivity(int activity) {
|
||||||
|
this.activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the message
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param message the message to set
|
||||||
|
*/
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskId() {
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskId(String taskId) {
|
||||||
|
this.taskId = taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBroadcasted() {
|
||||||
|
return broadcasted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBroadcasted(boolean broadcasted) {
|
||||||
|
this.broadcasted = broadcasted;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
80
src/id/iptek/utms/agent/model/TerminalIdObj.java
Normal file
80
src/id/iptek/utms/agent/model/TerminalIdObj.java
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package id.iptek.utms.agent.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class TerminalIdObj implements Serializable {
|
||||||
|
|
||||||
|
private String sn;
|
||||||
|
private String terminalId;
|
||||||
|
|
||||||
|
public TerminalIdObj() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TerminalIdObj(String sn, String terminalId) {
|
||||||
|
this.sn = sn;
|
||||||
|
this.terminalId = terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sn
|
||||||
|
*/
|
||||||
|
public String getSn() {
|
||||||
|
return sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sn the sn to set
|
||||||
|
*/
|
||||||
|
public void setSn(String sn) {
|
||||||
|
this.sn = sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the terminalId
|
||||||
|
*/
|
||||||
|
public String getTerminalId() {
|
||||||
|
return terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param terminalId the terminalId to set
|
||||||
|
*/
|
||||||
|
public void setTerminalId(String terminalId) {
|
||||||
|
this.terminalId = terminalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 3;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final TerminalIdObj other = (TerminalIdObj) obj;
|
||||||
|
if (!Objects.equals(this.sn, other.sn)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Objects.equals(this.terminalId, other.terminalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TerminalIdObj{" + "sn=" + sn + ", terminalId=" + terminalId + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package id.iptek.utms.agent.model.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public enum DownloadTimeType {
|
||||||
|
|
||||||
|
NEXT_CONTACT(1),
|
||||||
|
DATE_TIME(2);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private DownloadTimeType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DownloadTimeType fromValue(int value) {
|
||||||
|
DownloadTimeType val = null;
|
||||||
|
for(DownloadTimeType _val : DownloadTimeType.values()) {
|
||||||
|
if(_val.getValue() == value) {
|
||||||
|
val = _val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package id.iptek.utms.agent.model.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public enum InstallationNotificationType {
|
||||||
|
|
||||||
|
SILENT(1),
|
||||||
|
NEED_CONFIRMATION(2);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private InstallationNotificationType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InstallationNotificationType fromValue(int value) {
|
||||||
|
InstallationNotificationType val = null;
|
||||||
|
for(InstallationNotificationType _val : InstallationNotificationType.values()) {
|
||||||
|
if(_val.getValue() == value) {
|
||||||
|
val = _val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package id.iptek.utms.agent.model.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public enum InstallationTimeType {
|
||||||
|
|
||||||
|
IMMEDIATE_AFTER_DOWNLOAD(1),
|
||||||
|
DATE_TIME(2);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private InstallationTimeType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InstallationTimeType fromValue(int value) {
|
||||||
|
InstallationTimeType val = null;
|
||||||
|
for(InstallationTimeType _val : InstallationTimeType.values()) {
|
||||||
|
if(_val.getValue() == value) {
|
||||||
|
val = _val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package id.iptek.utms.agent.model.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public enum PublishTimeType {
|
||||||
|
|
||||||
|
IMMEDIATE(1),
|
||||||
|
DATE_TIME(2);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private PublishTimeType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PublishTimeType fromValue(int value) {
|
||||||
|
PublishTimeType val = null;
|
||||||
|
for(PublishTimeType _val : PublishTimeType.values()) {
|
||||||
|
if(_val.getValue() == value) {
|
||||||
|
val = _val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/id/iptek/utms/agent/model/enumeration/TaskActivity.java
Normal file
40
src/id/iptek/utms/agent/model/enumeration/TaskActivity.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package id.iptek.utms.agent.model.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public enum TaskActivity {
|
||||||
|
|
||||||
|
INITIAL(0),
|
||||||
|
PUBLISHED(1),
|
||||||
|
ACCEPTED(2),
|
||||||
|
DOWNLOAD_STARTED(3),
|
||||||
|
DOWNLOAD_SUCCESS(4),
|
||||||
|
DOWNLOAD_FAIL(5),
|
||||||
|
INSTALL_STARTED(6),
|
||||||
|
INSTALL_SUCCESS(7),
|
||||||
|
INSTALL_FAIL(8),
|
||||||
|
EXPIRED(99);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private TaskActivity(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TaskActivity fromValue(int value) {
|
||||||
|
TaskActivity val = null;
|
||||||
|
for(TaskActivity _val : TaskActivity.values()) {
|
||||||
|
if(_val.getValue() == value) {
|
||||||
|
val = _val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/id/iptek/utms/agent/model/enumeration/TaskStatus.java
Normal file
36
src/id/iptek/utms/agent/model/enumeration/TaskStatus.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package id.iptek.utms.agent.model.enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public enum TaskStatus {
|
||||||
|
|
||||||
|
INITIAL(0),
|
||||||
|
NOT_STARTED(1),
|
||||||
|
IN_PROGRESS(2),
|
||||||
|
CANCELLED(3),
|
||||||
|
DONE(4),
|
||||||
|
EXPIRED(99);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private TaskStatus(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TaskStatus fromValue(int value) {
|
||||||
|
TaskStatus val = null;
|
||||||
|
for(TaskStatus _val : TaskStatus.values()) {
|
||||||
|
if(_val.getValue() == value) {
|
||||||
|
val = _val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/id/iptek/utms/agent/queue/ConsumerMode.java
Normal file
11
src/id/iptek/utms/agent/queue/ConsumerMode.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package id.iptek.utms.agent.queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public enum ConsumerMode {
|
||||||
|
|
||||||
|
SINGLE, BATCH;
|
||||||
|
|
||||||
|
}
|
||||||
212
src/id/iptek/utms/agent/queue/DelayMessageQueue.java
Normal file
212
src/id/iptek/utms/agent/queue/DelayMessageQueue.java
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
package id.iptek.utms.agent.queue;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.db.DatabaseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public class DelayMessageQueue<T> {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
private ExecutorService executorservice;
|
||||||
|
private int capacity = 10;
|
||||||
|
private ConsumerMode mode = ConsumerMode.SINGLE;
|
||||||
|
private QueueMessageHandler<T> handler;
|
||||||
|
private final ConcurrentLinkedQueue<T> queue = new ConcurrentLinkedQueue<>();
|
||||||
|
private boolean running = false;
|
||||||
|
private int totalThread = 1;
|
||||||
|
private ExecutorService internalExec = null;
|
||||||
|
private Future internalWorker = null;
|
||||||
|
private long batchFlushIntervalMillis = 1000L;
|
||||||
|
|
||||||
|
public DelayMessageQueue() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelayMessageQueue(ExecutorService executorservice, QueueMessageHandler<T> handler) {
|
||||||
|
this(executorservice, handler, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelayMessageQueue(ExecutorService executorservice, QueueMessageHandler<T> handler, int capacity) {
|
||||||
|
this.executorservice = executorservice;
|
||||||
|
this.handler = handler;
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExecutorservice(ExecutorService executorservice) {
|
||||||
|
this.executorservice = executorservice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCapacity(int capacity) {
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCapacity() {
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(ConsumerMode mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHandler(QueueMessageHandler<T> handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalThread(int totalThread) {
|
||||||
|
this.totalThread = totalThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatchFlushIntervalMillis(long batchFlushIntervalMillis) {
|
||||||
|
this.batchFlushIntervalMillis = batchFlushIntervalMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
logger.info("Run queue worker ...");
|
||||||
|
this.running = true;
|
||||||
|
|
||||||
|
internalExec = Executors.newFixedThreadPool(totalThread);
|
||||||
|
internalWorker = this.executorservice.submit(new QueueRunnable());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(boolean interrupt) {
|
||||||
|
logger.info("Stopping queue worker ...");
|
||||||
|
stop(interrupt, 0L, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean stop(boolean interrupt, long timeout, TimeUnit unit) {
|
||||||
|
logger.info("Stopping queue worker ...");
|
||||||
|
this.running = false;
|
||||||
|
if(internalWorker == null) {
|
||||||
|
logger.warn("Queue worker has not been run!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if(interrupt) {
|
||||||
|
internalWorker.cancel(true);
|
||||||
|
} else if(!internalWorker.isDone()) {
|
||||||
|
if(timeout > 0L) {
|
||||||
|
internalWorker.get(timeout, unit);
|
||||||
|
} else {
|
||||||
|
internalWorker.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.warn("Queue worker did not stop gracefully: {}", ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
internalExec.shutdown();
|
||||||
|
try {
|
||||||
|
boolean terminated = timeout > 0L ? internalExec.awaitTermination(timeout, unit) : internalExec.awaitTermination(0L, TimeUnit.MILLISECONDS);
|
||||||
|
if(!terminated) {
|
||||||
|
logger.warn("Queue handler tasks did not finish within {} {}", timeout, unit);
|
||||||
|
internalExec.shutdownNow();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch(InterruptedException ex) {
|
||||||
|
logger.warn("Interrupted while waiting queue handler tasks: {}", ex.getMessage());
|
||||||
|
internalExec.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(T message) {
|
||||||
|
return queue.add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class QueueRunnable implements Runnable {
|
||||||
|
|
||||||
|
private final List<T> internalList = new ArrayList<>();
|
||||||
|
private long lastFlushTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while(running || !queue.isEmpty()) {
|
||||||
|
try {
|
||||||
|
T message = queue.poll();
|
||||||
|
if(message != null) {
|
||||||
|
if(mode == ConsumerMode.BATCH) {
|
||||||
|
// handled batches
|
||||||
|
internalList.add(message);
|
||||||
|
|
||||||
|
// check capacity
|
||||||
|
if(internalList.size() >= capacity) {
|
||||||
|
flushBatch();
|
||||||
|
}
|
||||||
|
} else if(mode == ConsumerMode.SINGLE) {
|
||||||
|
// run job using separate runnable
|
||||||
|
Runnable run = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
// handle single
|
||||||
|
boolean handled = handler.handleMessage(message);
|
||||||
|
logger.debug("Message handled? {}", handled);
|
||||||
|
} catch(DatabaseException ex) {
|
||||||
|
logger.error("Error saving heartbeats: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
internalExec.execute(run);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(mode == ConsumerMode.BATCH && !internalList.isEmpty()
|
||||||
|
&& System.currentTimeMillis() - lastFlushTime >= batchFlushIntervalMillis) {
|
||||||
|
flushBatch();
|
||||||
|
}
|
||||||
|
TimeUnit.MILLISECONDS.sleep(100L);
|
||||||
|
}
|
||||||
|
if(mode == ConsumerMode.BATCH && !internalList.isEmpty()
|
||||||
|
&& System.currentTimeMillis() - lastFlushTime >= batchFlushIntervalMillis) {
|
||||||
|
flushBatch();
|
||||||
|
}
|
||||||
|
} catch(InterruptedException ex) {
|
||||||
|
logger.debug("Queue worker interrupted: {}", ex.getMessage());
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error consuming queue : {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(mode == ConsumerMode.BATCH && !internalList.isEmpty()) {
|
||||||
|
flushBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flushBatch() {
|
||||||
|
List<T> workingList = new ArrayList<>();
|
||||||
|
workingList.addAll(internalList);
|
||||||
|
internalList.clear();
|
||||||
|
lastFlushTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// run job using separate runnable
|
||||||
|
Runnable run = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
boolean handled = handler.handleMessages(workingList);
|
||||||
|
logger.debug("Batch messages handled? {}", handled);
|
||||||
|
} catch(DatabaseException ex) {
|
||||||
|
logger.error("Error saving heartbeats: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
internalExec.execute(run);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
134
src/id/iptek/utms/agent/queue/DeviceInitQueueMessageHandler.java
Normal file
134
src/id/iptek/utms/agent/queue/DeviceInitQueueMessageHandler.java
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
package id.iptek.utms.agent.queue;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import id.iptek.utms.agent.dao.ProfileDao;
|
||||||
|
import id.iptek.utms.agent.model.Profile;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class DeviceInitQueueMessageHandler implements QueueMessageHandler<Map> {
|
||||||
|
|
||||||
|
public final static String NAME = "DEV_INIT_QUEUE_HANDLER";
|
||||||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
private ProfileDao profileDao = new ProfileDao();
|
||||||
|
private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
|
||||||
|
|
||||||
|
public DeviceInitQueueMessageHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessage(Map message) {
|
||||||
|
boolean processed = false;
|
||||||
|
try {
|
||||||
|
logger.debug("Handling init request: {}", message);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
|
MqttClient mqttClient = (MqttClient) message.get("MQTT");
|
||||||
|
String terminalSN = (String) message.get("device_sn");
|
||||||
|
Profile profile = profileDao.getProfileForTerminal(terminalSN);
|
||||||
|
if (profile != null) {
|
||||||
|
broadcastProfile(mqttClient, profile);
|
||||||
|
} else {
|
||||||
|
logger.warn("No profile for SN: {}", terminalSN);
|
||||||
|
}
|
||||||
|
processed = true;
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
logger.debug("Saved in {}ms", (end-start));
|
||||||
|
return processed;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error handling init: {}", ex.getMessage(), ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessages(List<Map> messages) {
|
||||||
|
try {
|
||||||
|
logger.debug("Handling list of init requests: {}", messages.size());
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean processed = false;
|
||||||
|
for(Map message : messages) {
|
||||||
|
MqttClient mqttClient = (MqttClient) message.get("MQTT");
|
||||||
|
String terminalSN = (String) message.get("device_sn");
|
||||||
|
Profile profile = profileDao.getProfileForTerminal(terminalSN);
|
||||||
|
if (profile != null) {
|
||||||
|
broadcastProfile(mqttClient, profile);
|
||||||
|
} else {
|
||||||
|
logger.warn("No profile for SN: {}", terminalSN);
|
||||||
|
}
|
||||||
|
processed |= true;
|
||||||
|
}
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
logger.debug("Saved in {}ms", (end-start));
|
||||||
|
return processed;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error handling list of init requests: {}", ex.getMessage(), ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send profile to device topic via mqtt
|
||||||
|
public void broadcastProfile(MqttClient mqttClient,
|
||||||
|
Profile profile) throws Exception {
|
||||||
|
logger.debug("Publish profile ...");
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
int qos = 2;
|
||||||
|
String topicName = profile.getTerminalSN().toUpperCase() + "_IN";
|
||||||
|
// generate json
|
||||||
|
Map messageMap = new HashMap<>();
|
||||||
|
messageMap.put("req_id", UUID.randomUUID().toString());
|
||||||
|
messageMap.put("req_time", dateTimeFormat.format(new Date()));
|
||||||
|
messageMap.put("req_type", "UPDATE_PARAM");
|
||||||
|
// profile map
|
||||||
|
Map profileMap = new HashMap<>();
|
||||||
|
profileMap.put("id", profile.getId());
|
||||||
|
profileMap.put("name", profile.getName());
|
||||||
|
profileMap.put("hearbeat_interval", profile.getHeartbeatInterval());
|
||||||
|
profileMap.put("diagnostic_interval", profile.getDiagnosticInterval());
|
||||||
|
profileMap.put("mask_home_button", profile.isMaskHomeButton());
|
||||||
|
profileMap.put("mask_status_button", profile.isMaskStatusButton());
|
||||||
|
profileMap.put("schedule_reboot", profile.isScheduleReboot());
|
||||||
|
if (profile.isScheduleReboot()) {
|
||||||
|
profileMap.put("schedule_reboot_time", timeFormat.format(profile.getScheduleRebootTime()));
|
||||||
|
}
|
||||||
|
profileMap.put("relocation_alert", profile.isRelocationAlert());
|
||||||
|
profileMap.put("moving_threshold", profile.getMovingThreshold());
|
||||||
|
profileMap.put("admin_password", profile.getAdminPassword());
|
||||||
|
|
||||||
|
// additional
|
||||||
|
profileMap.put("front_app", profile.getFrontApp());
|
||||||
|
profileMap.put("apps_home_list", profile.getApps());
|
||||||
|
profileMap.put("group_list", profile.getGroupIds());
|
||||||
|
|
||||||
|
messageMap.put("profile", profileMap);
|
||||||
|
|
||||||
|
String messageData = gson.toJson(messageMap);
|
||||||
|
|
||||||
|
logger.debug("Try publish message to: {}", topicName);
|
||||||
|
mqttClient.publish(topicName, messageData.getBytes(), qos, false);
|
||||||
|
logger.debug("Message published!");
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error publish to device: {}", ex.getMessage(), ex);
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
logger.debug("Publish profile DONE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package id.iptek.utms.agent.queue;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.dao.DiagnosticDao;
|
||||||
|
import id.iptek.utms.agent.model.Diagnostic;
|
||||||
|
import java.util.List;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class DiagnosticInfoQueueMessageHandler implements QueueMessageHandler<Diagnostic> {
|
||||||
|
|
||||||
|
public final static String NAME = "DIAGNOSTIC_QUEUE_HANDLER";
|
||||||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
private DiagnosticDao dao = new DiagnosticDao();
|
||||||
|
|
||||||
|
public DiagnosticInfoQueueMessageHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessage(Diagnostic message) {
|
||||||
|
try {
|
||||||
|
logger.debug("Saving diagnostic: {}", message);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean saved = dao.save(message);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
logger.debug("Saved in {}ms", (end-start));
|
||||||
|
return saved;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error handling diagnostic: {}", ex.getMessage(), ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessages(List<Diagnostic> messages) {
|
||||||
|
try {
|
||||||
|
logger.debug("Saving list of diagnostics: {}", messages.size());
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean saved = dao.saveAll(messages);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
logger.debug("Saved in {}ms", (end-start));
|
||||||
|
return saved;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error handling list of diagnostics: {}", ex.getMessage(), ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package id.iptek.utms.agent.queue;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.dao.HeartbeatDao;
|
||||||
|
import id.iptek.utms.agent.model.HeartBeat;
|
||||||
|
import java.util.List;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class HeartBeatQueueMessageHandler implements QueueMessageHandler<HeartBeat> {
|
||||||
|
|
||||||
|
public final static String NAME = "HEARTBEAT_QUEUE_HANDLER";
|
||||||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
private HeartbeatDao dao = new HeartbeatDao();
|
||||||
|
|
||||||
|
public HeartBeatQueueMessageHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessage(HeartBeat message) {
|
||||||
|
try {
|
||||||
|
logger.debug("Saving heartbeat: {}", message);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean saved = dao.save(message);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
logger.debug("Saved in {}ms", (end-start));
|
||||||
|
return saved;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error handling heartbeat: {}", ex.getMessage(), ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessages(List<HeartBeat> messages) {
|
||||||
|
try {
|
||||||
|
logger.debug("Saving list of heartbeats: {}", messages.size());
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
boolean saved = dao.saveAll(messages);
|
||||||
|
long end = System.currentTimeMillis();
|
||||||
|
logger.debug("Saved in {}ms", (end-start));
|
||||||
|
return saved;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error handling list of heartbeats: {}", ex.getMessage(), ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
src/id/iptek/utms/agent/queue/QueueMessageHandler.java
Normal file
25
src/id/iptek/utms/agent/queue/QueueMessageHandler.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package id.iptek.utms.agent.queue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public interface QueueMessageHandler<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle message
|
||||||
|
* @param message
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean handleMessage(T message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle batch of messages at same time
|
||||||
|
* @param messages
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean handleMessages(List<T> messages);
|
||||||
|
|
||||||
|
}
|
||||||
52
src/id/iptek/utms/agent/sample/MqttPublishSample.java
Normal file
52
src/id/iptek/utms/agent/sample/MqttPublishSample.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package id.iptek.utms.agent.sample;
|
||||||
|
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
|
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||||
|
|
||||||
|
public class MqttPublishSample {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
String topic = "SERVER_IN_DIAG";
|
||||||
|
String content = "{\"req_id\":\"a971d68e-1fcc-4eeb-ba96-6c4e6e867a06\",\"req_type\":\"DIAGNOSTIC\",\"req_time\":\"20250827140806\",\"device_sn\":\"V9E0191945\",\"diagnostic_info\":{\"imei\":\"863188045199949\",\"meid\":\"\",\"battery_temp\":\" 250\",\"battery_percentage\":\"100\",\"total_memory\":\"1997537280\",\"available_memory\":\"1308291072\",\"total_flash_memory\":\"16000000000B\",\"available_flash_memory\":\"11429019648\",\"total_mobile_data\":\"1248910\",\"switching_times\":\"0\",\"current_boot_time\":\"0\",\"total_boot_time\":\"104\",\"total_length_printed\":\"13097.0\",\"swiping_card_times\":\"297\",\"dip_inserting_times\":\"273\",\"nfc_card_reading_times\":\"124\",\"front_camera_open_times\":\"0\",\"rear_camera_open_times\":\"0\",\"new_diagnostic\":true,\"sam_available\":true},\"location_info\":{\"lat\":-6.357999801635742,\"lng\":106.81169891357422},\"installed_apps\":[{\"app_name\":\"CPU Info\",\"package_name\":\"com.kgurgul.cpuinfo\",\"version\":\"6.0.0\"},{\"app_name\":\"NSICCSDemo\",\"package_name\":\"com.unified.nsiccsdemo\",\"version\":\"1.0\"},{\"app_name\":\"VFSystemService\",\"package_name\":\"com.vfi.smartpos.system_service\",\"version\":\"1.14.0.1\"},{\"app_name\":\"Telnet\",\"package_name\":\"koushikdutta.telnet\",\"version\":\"1.0.1\"},{\"app_name\":\"Athena\",\"package_name\":\"dev.sebaubuntu.athena.dev\",\"version\":\"1.1.0\"},{\"app_name\":\"UTMS\",\"package_name\":\"com.unified.launcher\",\"version\":\"1.4.3.BIT\"},{\"app_name\":\"Bank Index\",\"package_name\":\"com.iptek.index\",\"version\":\"1.1.4.DEV\"},{\"app_name\":\"VFService\",\"package_name\":\"com.vfi.smartpos.deviceservice\",\"version\":\"3.11.7.1\"}],\"device_info_ex\":{\"SN\":\"V9E0191945\",\"PN\":\"M550-104-22-EUA-6\",\"IMSI\":\"510019134244830\",\"IMEI\":\"863188045199949\",\"MEID\":\"\",\"manufacture\":\"Verifone\",\"deviceModel\":\"X990\",\"androidOsVer\":\"10\",\"androidKernalVer\":\"Linux version 4.14.133 (linbx@v-dev) (gcc version 4.9.x 20150123 (prerelease) (GCC) ) #1 SMP PREEMPT Thu Aug 4 11:30:37 CST 2022\",\"romVer\":\"3A.1.385(202208041133 INTL)\",\"firmwareVer\":\"V3.1.0.20220804\",\"hardwareVer\":\"M550-10X-XX-XXX-6 Rev.C\",\"SPVer\":\"X990-V1.0.26(202209080934)\",\"VFSerivceVer\":\"3.11.7.1\",\"VRKSn\":\"\",\"SponsorID\":\"\",\"SponsorName\":\"\",\"bootVer\":\"X990-1.0.0.A10(20220707)\"}}";
|
||||||
|
//String content = "{\"req_id\":\"7484442f-1d5c-4d51-96bc-ed7cb0ec8b95\",\"req_time\":\"2023-07-30 18:39:00\",\"req_type\":\"RESET_CONNECTION\"}";
|
||||||
|
int qos = 2;
|
||||||
|
String broker = "tcp://192.168.4.112:1883";
|
||||||
|
String clientId = "JavaSample";
|
||||||
|
MemoryPersistence persistence = new MemoryPersistence();
|
||||||
|
|
||||||
|
try {
|
||||||
|
MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
|
||||||
|
MqttConnectOptions connOpts = new MqttConnectOptions();
|
||||||
|
connOpts.setCleanSession(true);
|
||||||
|
connOpts.setUserName("user1");
|
||||||
|
connOpts.setPassword("P@ssw0rd".toCharArray());
|
||||||
|
//connOpts.setUserName("wira");
|
||||||
|
//connOpts.setPassword("wira1234".toCharArray());
|
||||||
|
|
||||||
|
System.out.println("Connecting to broker: "+broker);
|
||||||
|
sampleClient.connect(connOpts);
|
||||||
|
System.out.println("Connected");
|
||||||
|
System.out.println("Publishing message: "+content);
|
||||||
|
MqttMessage message = new MqttMessage(content.getBytes());
|
||||||
|
message.setQos(qos);
|
||||||
|
//message.setRetained(true);
|
||||||
|
sampleClient.publish(topic, message);
|
||||||
|
System.out.println("Message published");
|
||||||
|
sampleClient.disconnect();
|
||||||
|
System.out.println("Disconnected");
|
||||||
|
System.exit(0);
|
||||||
|
} catch(MqttException me) {
|
||||||
|
System.out.println("reason "+me.getReasonCode());
|
||||||
|
System.out.println("msg "+me.getMessage());
|
||||||
|
System.out.println("loc "+me.getLocalizedMessage());
|
||||||
|
System.out.println("cause "+me.getCause());
|
||||||
|
System.out.println("excep "+me);
|
||||||
|
me.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
87
src/id/iptek/utms/agent/sample/MqttSubscribeSample.java
Normal file
87
src/id/iptek/utms/agent/sample/MqttSubscribeSample.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package id.iptek.utms.agent.sample;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
|
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||||
|
|
||||||
|
public class MqttSubscribeSample {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
final String topic = "5354b64f-c52c-45e0-8b26-49b5d5352e44";
|
||||||
|
final String topic2 = "V1E0352316_IN";
|
||||||
|
//V1E0352316_IN
|
||||||
|
int qos = 2;
|
||||||
|
//String broker = "tcp://verifone.id:1883";
|
||||||
|
String broker = "tcp://bit.unifiedtms.id:1883";
|
||||||
|
String clientId = "SN02";
|
||||||
|
MemoryPersistence persistence = new MemoryPersistence();
|
||||||
|
|
||||||
|
try {
|
||||||
|
final MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
|
||||||
|
MqttConnectOptions connOpts = new MqttConnectOptions();
|
||||||
|
connOpts.setCleanSession(true);
|
||||||
|
//connOpts.setUserName("wira");
|
||||||
|
//connOpts.setPassword("wira1234".toCharArray());
|
||||||
|
connOpts.setUserName("user1");
|
||||||
|
connOpts.setPassword("P@ssw0rd".toCharArray());
|
||||||
|
connOpts.setAutomaticReconnect(true);
|
||||||
|
connOpts.setKeepAliveInterval(10000);
|
||||||
|
System.out.println("Connecting to broker: " + broker);
|
||||||
|
sampleClient.setCallback(new MqttCallbackExtended() {
|
||||||
|
@Override
|
||||||
|
public void connectComplete(boolean bln, String string) {
|
||||||
|
System.out.println("Connect complete? " + bln + " : " + string);
|
||||||
|
try {
|
||||||
|
sampleClient.subscribe(topic);
|
||||||
|
sampleClient.subscribe(topic2);
|
||||||
|
} catch(MqttException ex) {
|
||||||
|
System.err.println("Error subscribe topic: " + topic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionLost(Throwable thrwbl) {
|
||||||
|
System.err.println("Connection Lost: " + thrwbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageArrived(String topic, MqttMessage mm) throws Exception {
|
||||||
|
System.out.println("<< [" + topic + "] " + new String(mm.getPayload()) + " (" + mm.getId() + " - " + mm.getQos() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deliveryComplete(IMqttDeliveryToken imdt) {
|
||||||
|
System.err.println("Delivery Complete: " + imdt.getMessageId());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
sampleClient.connect(connOpts);
|
||||||
|
System.out.println("Connected");
|
||||||
|
//sampleClient.subscribe(topic);
|
||||||
|
|
||||||
|
try {
|
||||||
|
TimeUnit.SECONDS.sleep(100);
|
||||||
|
} catch(InterruptedException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleClient.disconnect();
|
||||||
|
System.out.println("Disconnected");
|
||||||
|
System.exit(0);
|
||||||
|
} catch (MqttException me) {
|
||||||
|
System.out.println("reason " + me.getReasonCode());
|
||||||
|
System.out.println("msg " + me.getMessage());
|
||||||
|
System.out.println("loc " + me.getLocalizedMessage());
|
||||||
|
System.out.println("cause " + me.getCause());
|
||||||
|
System.out.println("excep " + me);
|
||||||
|
me.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,299 @@
|
|||||||
|
package id.iptek.utms.agent.scheduler.job;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import id.iptek.utms.agent.AppConfig;
|
||||||
|
import id.iptek.utms.agent.dao.ApplicationDao;
|
||||||
|
import id.iptek.utms.agent.dao.DownloadTaskDao;
|
||||||
|
import id.iptek.utms.agent.model.ApplicationExt;
|
||||||
|
import id.iptek.utms.agent.model.DownloadTask;
|
||||||
|
import id.iptek.utms.agent.model.PendingDownloadTask;
|
||||||
|
import id.iptek.utms.agent.model.enumeration.TaskStatus;
|
||||||
|
import id.iptek.utms.agent.util.Singleton;
|
||||||
|
import io.minio.GetPresignedObjectUrlArgs;
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import io.minio.http.Method;
|
||||||
|
import java.io.File;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import static java.util.concurrent.TimeUnit.HOURS;
|
||||||
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||||
|
import org.quartz.Job;
|
||||||
|
import org.quartz.JobDataMap;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class DownloadTaskPublisherJob implements Job {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
private ApplicationDao appDao = new ApplicationDao();
|
||||||
|
private DownloadTaskDao dao = new DownloadTaskDao();
|
||||||
|
private static final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
private static final SimpleDateFormat sdfYEAR = new SimpleDateFormat("yyyy");
|
||||||
|
private static final SimpleDateFormat sdfMONTH = new SimpleDateFormat("MM");
|
||||||
|
private static final SimpleDateFormat sdfDATE = new SimpleDateFormat("dd");
|
||||||
|
|
||||||
|
public DownloadTaskPublisherJob() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(JobExecutionContext jec) throws JobExecutionException {
|
||||||
|
try {
|
||||||
|
logger.info("Execute publish task job ..");
|
||||||
|
JobDataMap dataMap = jec.getMergedJobDataMap();
|
||||||
|
// get task
|
||||||
|
DownloadTask task = (DownloadTask) dataMap.get("task");
|
||||||
|
logger.info(">> {}", task);
|
||||||
|
if(task.getStatus() == TaskStatus.INITIAL) {
|
||||||
|
boolean populated = dao.populateAndBuildDownloadTaskLogs(task);
|
||||||
|
logger.info("Populated? {}", populated);
|
||||||
|
}
|
||||||
|
List<PendingDownloadTask> groupPendingDownloadTasks = dao.getUnpublishedPendingTaskByTerminalGroup(task);
|
||||||
|
List<PendingDownloadTask> pendingDownloadTasks = dao.getUnpublishedPendingTaskByTerminal(task);
|
||||||
|
|
||||||
|
MqttClient mqttClient = (MqttClient) Singleton.getInstance("MQTT_CLIENT").getObject();
|
||||||
|
logger.info("Total Group Pending Download Tasks: {}", groupPendingDownloadTasks.size());
|
||||||
|
for(PendingDownloadTask downloadTask : groupPendingDownloadTasks) {
|
||||||
|
logger.info(">> [1] task={}, group={}, app={}", downloadTask.getId(), downloadTask.getTerminalGroupId(), downloadTask.getApp().getId());
|
||||||
|
broadcastDownloadTasksToDevice(mqttClient, downloadTask);
|
||||||
|
}
|
||||||
|
logger.info("Total Pending Download Tasks: {}", pendingDownloadTasks.size());
|
||||||
|
for(PendingDownloadTask downloadTask : pendingDownloadTasks) {
|
||||||
|
logger.info(">> [2] task={}, terminal={}, app={}", downloadTask.getId(), downloadTask.getTerminalSN(), downloadTask.getApp().getId());
|
||||||
|
broadcastDownloadTasksToDevice(mqttClient, downloadTask);
|
||||||
|
}
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error publish task: {}", ex.getMessage(), ex);
|
||||||
|
} finally {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send download task to device topic via mqtt
|
||||||
|
protected void broadcastDownloadTasksToDevice(MqttClient mqttClient,
|
||||||
|
PendingDownloadTask task) throws Exception {
|
||||||
|
logger.debug("Broadcast tasks ...");
|
||||||
|
try {
|
||||||
|
int qos = 2;
|
||||||
|
String topicName;
|
||||||
|
// broadcast to group or specific SN
|
||||||
|
boolean broadcastToGroup = false;
|
||||||
|
if(task.getTerminalGroupId() != null) {
|
||||||
|
topicName = task.getTerminalGroupId();
|
||||||
|
broadcastToGroup = true;
|
||||||
|
} else {
|
||||||
|
topicName = task.getTerminalSN().toUpperCase() + "_IN";
|
||||||
|
}
|
||||||
|
|
||||||
|
AppConfig appConfig = AppConfig.getInstance();
|
||||||
|
Date now = Calendar.getInstance().getTime();
|
||||||
|
ApplicationExt app = (ApplicationExt) task.getApp();
|
||||||
|
String bucketName = appConfig.get("fileserver.bucket");
|
||||||
|
// check icon url expiry
|
||||||
|
Date iconUrlExp = app.getIconUrlExp();
|
||||||
|
if(iconUrlExp == null || now.after(iconUrlExp)) {
|
||||||
|
logger.debug("Icon url expired: {}", iconUrlExp);
|
||||||
|
String iconUniqueName = app.getUniqueIconName();
|
||||||
|
|
||||||
|
String path = appConfig.get("fileserver.icon.path");
|
||||||
|
int expiry = appConfig.getAsInt("fileserver.icon.expiry", 7);
|
||||||
|
TimeUnit timeUnit = getTimeUnit(appConfig, "fileserver.icon.timeunit", "server.icon.timeunit", "DAYS");
|
||||||
|
Date iconExpiryDate = getExpiryDate(now, expiry, timeUnit);
|
||||||
|
|
||||||
|
logger.info("Generate icon url for app '{}', old expiry: {}", app.getId(), iconUrlExp);
|
||||||
|
String iconDownloadUrl = generateDownloadUrl(bucketName, path, iconUniqueName,
|
||||||
|
expiry, timeUnit);
|
||||||
|
app.setIconUrl(iconDownloadUrl);
|
||||||
|
app.setIconUrlExp(iconExpiryDate);
|
||||||
|
logger.info("Icon url generated for app '{}', new expiry: {}", app.getId(), iconExpiryDate);
|
||||||
|
|
||||||
|
boolean iconUrlUpdated = appDao.updateIconUrl(app);
|
||||||
|
logger.info("Icon url updated? {}", iconUrlUpdated);
|
||||||
|
}
|
||||||
|
// check download url expiry
|
||||||
|
Date downloadUrlExp = app.getDownloadUrlExp();
|
||||||
|
if(downloadUrlExp == null || now.after(downloadUrlExp)) {
|
||||||
|
logger.info("Download app url expired for task '{}', app '{}', old expiry: {}", task.getId(), app.getId(), downloadUrlExp);
|
||||||
|
String uniqueName = app.getUniqueName();
|
||||||
|
|
||||||
|
String path = appConfig.get("fileserver.app.path");
|
||||||
|
int expiry = appConfig.getAsInt("fileserver.app.expiry", 7);
|
||||||
|
TimeUnit timeUnit = getTimeUnit(appConfig, "fileserver.app.timeunit", "server.app.timeunit", "DAYS");
|
||||||
|
Date appExpiryDate = getExpiryDate(now, expiry, timeUnit);
|
||||||
|
|
||||||
|
logger.info("Generate app url for task '{}', app '{}'", task.getId(), app.getId());
|
||||||
|
String appDownloadUrl = generateDownloadUrl(bucketName, path, uniqueName,
|
||||||
|
expiry, timeUnit);
|
||||||
|
app.setDownloadUrl(appDownloadUrl);
|
||||||
|
app.setDownloadUrlExp(appExpiryDate);
|
||||||
|
logger.info("App url generated for task '{}', app '{}', new expiry: {}", task.getId(), app.getId(), appExpiryDate);
|
||||||
|
|
||||||
|
boolean appUrlUpdated = appDao.updateAppUrl(task, app);
|
||||||
|
logger.info("App url updated? {}", appUrlUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate json
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map messageMap = new HashMap<>();
|
||||||
|
messageMap.put("req_id", UUID.randomUUID().toString());
|
||||||
|
messageMap.put("req_time", dateTimeFormat.format(new Date()));
|
||||||
|
// we'll use log's id as ack_id
|
||||||
|
if(broadcastToGroup) {
|
||||||
|
String ackId = "BROADCAST_" + task.getId();
|
||||||
|
messageMap.put("ack_id", ackId);
|
||||||
|
} else {
|
||||||
|
messageMap.put("ack_id", task.getLogId());
|
||||||
|
}
|
||||||
|
messageMap.put("req_type", "DOWNLOAD_APP_TASK");
|
||||||
|
// task map
|
||||||
|
Map taskMap = new HashMap<>();
|
||||||
|
taskMap.put("id", task.getId());
|
||||||
|
taskMap.put("name", task.getName());
|
||||||
|
taskMap.put("download_time_type", getDownloadTimeTypeName(task.getDownloadTimeType()));
|
||||||
|
if (task.getDownloadTimeType() == 2) {
|
||||||
|
taskMap.put("download_time", dateTimeFormat.format(task.getDownloadTime()));
|
||||||
|
}
|
||||||
|
taskMap.put("installation_time_type", getInstallationTimeTypeName(task.getInstallationTimeType()));
|
||||||
|
if (task.getInstallationTimeType() == 2) {
|
||||||
|
taskMap.put("installation_time", dateTimeFormat.format(task.getInstallationTime()));
|
||||||
|
}
|
||||||
|
taskMap.put("installation_notification", getInstallationNotificationName(task.getInstallationNotification()));
|
||||||
|
messageMap.put("task", taskMap);
|
||||||
|
// app map
|
||||||
|
Map appMap = new HashMap<>();
|
||||||
|
appMap.put("id", app.getId());
|
||||||
|
appMap.put("name", app.getAppName());
|
||||||
|
appMap.put("package_name", app.getPackageName());
|
||||||
|
appMap.put("version", app.getVersion());
|
||||||
|
appMap.put("company", app.getCompanyName());
|
||||||
|
appMap.put("uninstallable", app.isUninstallable());
|
||||||
|
appMap.put("description", app.getDescription());
|
||||||
|
appMap.put("download_url", app.getDownloadUrl());
|
||||||
|
appMap.put("md5_checksum", app.getChecksum());
|
||||||
|
messageMap.put("app", appMap);
|
||||||
|
|
||||||
|
String messageData = gson.toJson(messageMap);
|
||||||
|
logger.debug("Try publish message to: {}", topicName);
|
||||||
|
logger.debug(">> {}", messageData);
|
||||||
|
mqttClient.publish(topicName, messageData.getBytes(), qos, false);
|
||||||
|
logger.debug("Message published!");
|
||||||
|
|
||||||
|
// change log's last broadcast time
|
||||||
|
if(broadcastToGroup) {
|
||||||
|
boolean updated = dao.updateGroupLastBroadcastTs(task);
|
||||||
|
logger.debug("Download task group last broadcast time updated? {}", updated);
|
||||||
|
} else {
|
||||||
|
boolean updated = dao.updateTerminalLastBroadcastTs(task);
|
||||||
|
logger.debug("Download task terminal last broadcast time updated? {}", updated);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
logger.debug("Start broadcast download tasks DONE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String getDownloadTimeTypeName(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return "NEXT_CONTACT";
|
||||||
|
case 2:
|
||||||
|
return "DATETIME";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getInstallationTimeTypeName(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return "IMMEDIATE_AFTER_DOWNLOAD";
|
||||||
|
case 2:
|
||||||
|
return "DATETIME";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getInstallationNotificationName(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return "SILENT";
|
||||||
|
case 2:
|
||||||
|
return "NEED_CONFIRMATION";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFilePath(String fileId, String fileExt, Date fileCreateDate) {
|
||||||
|
String filePath = AppConfig.getInstance().get("file.dir") + File.separator
|
||||||
|
+ sdfYEAR.format(fileCreateDate) + File.separator
|
||||||
|
+ sdfMONTH.format(fileCreateDate) + File.separator
|
||||||
|
+ sdfDATE.format(fileCreateDate) + File.separator
|
||||||
|
+ fileId + "." + fileExt;
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String md5Checksum(byte[] bytes) throws Exception {
|
||||||
|
try {
|
||||||
|
String checksum = DigestUtils.md5Hex(bytes);
|
||||||
|
return checksum;
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateDownloadUrl(String bucketName, String path, String uniqueName, int expiry, TimeUnit expiryTimeUnit) throws Exception {
|
||||||
|
MinioClient minioClient = (MinioClient) Singleton.getInstance("MINIO_CLIENT").getObject();
|
||||||
|
String url
|
||||||
|
= minioClient.getPresignedObjectUrl(
|
||||||
|
GetPresignedObjectUrlArgs.builder()
|
||||||
|
.method(Method.GET)
|
||||||
|
.bucket(bucketName)
|
||||||
|
.object(path + "/" + uniqueName)
|
||||||
|
.expiry(expiry, expiryTimeUnit)
|
||||||
|
.build());
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date getExpiryDate(Date now, int expiry, TimeUnit timeUnit) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.setTime(now);
|
||||||
|
switch (timeUnit) {
|
||||||
|
case MILLISECONDS:
|
||||||
|
cal.add(Calendar.MILLISECOND, expiry);
|
||||||
|
break;
|
||||||
|
case SECONDS:
|
||||||
|
cal.add(Calendar.SECOND, expiry);
|
||||||
|
break;
|
||||||
|
case MINUTES:
|
||||||
|
cal.add(Calendar.MINUTE, expiry);
|
||||||
|
break;
|
||||||
|
case HOURS:
|
||||||
|
cal.add(Calendar.HOUR_OF_DAY, expiry);
|
||||||
|
break;
|
||||||
|
case DAYS:
|
||||||
|
cal.add(Calendar.DAY_OF_MONTH, expiry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return cal.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeUnit getTimeUnit(AppConfig appConfig, String name, String legacyName, String defaultValue) {
|
||||||
|
String value = appConfig.get(name);
|
||||||
|
if(value == null) {
|
||||||
|
value = appConfig.get(legacyName, defaultValue);
|
||||||
|
}
|
||||||
|
return TimeUnit.valueOf(value.trim().toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
package id.iptek.utms.agent.scheduler.job;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.dao.DownloadTaskDao;
|
||||||
|
import id.iptek.utms.agent.model.DownloadTask;
|
||||||
|
import id.iptek.utms.agent.model.enumeration.PublishTimeType;
|
||||||
|
import id.iptek.utms.agent.util.Singleton;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import org.quartz.Job;
|
||||||
|
import static org.quartz.JobBuilder.newJob;
|
||||||
|
import org.quartz.JobDataMap;
|
||||||
|
import org.quartz.JobDetail;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
import org.quartz.JobExecutionException;
|
||||||
|
import org.quartz.JobKey;
|
||||||
|
import org.quartz.Scheduler;
|
||||||
|
import org.quartz.SchedulerException;
|
||||||
|
import org.quartz.Trigger;
|
||||||
|
import org.quartz.TriggerBuilder;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class DownloadTaskSchedulerJob implements Job {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
private DownloadTaskDao dao = new DownloadTaskDao();
|
||||||
|
|
||||||
|
public DownloadTaskSchedulerJob() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(JobExecutionContext jec) throws JobExecutionException {
|
||||||
|
try {
|
||||||
|
logger.info("Execute job ..");
|
||||||
|
List<DownloadTask> tasks = dao.getUnscheduledTasks();
|
||||||
|
logger.info("Done query");
|
||||||
|
logger.info("Got {} tasks", tasks.size());
|
||||||
|
/*List<String> scheduledJobIds = (List<String>) Singleton.getInstance("SCHEDULER_JOBS").getObject();
|
||||||
|
if(scheduledJobIds == null) {
|
||||||
|
scheduledJobIds = new ArrayList<>();
|
||||||
|
Singleton.getInstance("SCHEDULER_JOBS").setObject(scheduledJobIds);
|
||||||
|
}*/
|
||||||
|
for(DownloadTask task : tasks) {
|
||||||
|
/*if(scheduledJobIds.contains(task.getId())) {
|
||||||
|
logger.info("Download Task with id '{}' is already scheduled.", task.getId());
|
||||||
|
} else {
|
||||||
|
logger.info("Will schedule download task with id: {}", task.getId());
|
||||||
|
scheduleTask(task);
|
||||||
|
scheduledJobIds.add(task.getId());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
logger.info("Will schedule download task with id: {}", task.getId());
|
||||||
|
scheduleTask(task);
|
||||||
|
}
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error get tasks: {}", ex.getMessage(), ex);
|
||||||
|
} finally {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scheduleTask(DownloadTask task) throws SchedulerException {
|
||||||
|
// get quartz scheduler
|
||||||
|
Scheduler sched = (Scheduler) Singleton.getInstance("SCHEDULER").getObject();
|
||||||
|
JobKey jobkey = new JobKey("download-task-" + task.getId(), "publish-task");
|
||||||
|
if(sched.checkExists(jobkey)) return;
|
||||||
|
|
||||||
|
if(task.getPublishTimeType() == PublishTimeType.IMMEDIATE) {
|
||||||
|
// publish job in next 1 minutes
|
||||||
|
JobDataMap map = new JobDataMap();
|
||||||
|
map.put("task", task);
|
||||||
|
JobDetail job = newJob(DownloadTaskPublisherJob.class)
|
||||||
|
.withIdentity(jobkey)
|
||||||
|
.usingJobData(map)
|
||||||
|
.build();
|
||||||
|
Calendar time = Calendar.getInstance();
|
||||||
|
time.add(Calendar.MINUTE, 1);
|
||||||
|
Trigger trigger = TriggerBuilder.newTrigger()
|
||||||
|
.withIdentity("download-task-trigger-" + task.getId(), "publish-task")
|
||||||
|
.startAt(time.getTime())
|
||||||
|
.build();
|
||||||
|
sched.scheduleJob(job, trigger);
|
||||||
|
|
||||||
|
logger.info("Task id-{} scheduled @{}", task.getId(), trigger.getFinalFireTime());
|
||||||
|
} else if(task.getPublishTimeType() == PublishTimeType.DATE_TIME) {
|
||||||
|
Calendar time = Calendar.getInstance();
|
||||||
|
// compare publish time with current time
|
||||||
|
Date publishTime = task.getPublishTime();
|
||||||
|
JobDataMap map = new JobDataMap();
|
||||||
|
map.put("task", task);
|
||||||
|
JobDetail job = newJob(DownloadTaskPublisherJob.class)
|
||||||
|
.withIdentity(jobkey)
|
||||||
|
.usingJobData(map)
|
||||||
|
.build();
|
||||||
|
if(time.getTime().equals(publishTime) || time.getTime().after(publishTime)) {
|
||||||
|
// publish it next 5 minutes
|
||||||
|
time.add(Calendar.MINUTE, 1);
|
||||||
|
Trigger trigger = TriggerBuilder.newTrigger()
|
||||||
|
.withIdentity("download-task-trigger-" + task.getId(), "publish-task")
|
||||||
|
.startAt(time.getTime())
|
||||||
|
.build();
|
||||||
|
sched.scheduleJob(job, trigger);
|
||||||
|
|
||||||
|
logger.info("Task id-{} scheduled @{}", task.getId(), trigger.getFinalFireTime());
|
||||||
|
} else {
|
||||||
|
Trigger trigger = TriggerBuilder.newTrigger()
|
||||||
|
.withIdentity("download-task-trigger-" + task.getId(), "publish-task")
|
||||||
|
.startAt(publishTime)
|
||||||
|
.build();
|
||||||
|
sched.scheduleJob(job, trigger);
|
||||||
|
|
||||||
|
logger.info("Task id-{} scheduled @{}", task.getId(), trigger.getFinalFireTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/id/iptek/utms/agent/test/TestMinio.java
Normal file
51
src/id/iptek/utms/agent/test/TestMinio.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||||
|
*/
|
||||||
|
package id.iptek.utms.agent.test;
|
||||||
|
|
||||||
|
import io.minio.GetPresignedObjectUrlArgs;
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import io.minio.http.Method;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class TestMinio {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
MinioClient minioClient
|
||||||
|
= MinioClient.builder()
|
||||||
|
.endpoint("https://download.unifiedtms.id:9000")
|
||||||
|
.credentials("i9ZB0sNhHaiQe7oEP0sL", "4bxVnKwKgkXpZJ9Dou4oprZ1E8oe3s1HuvKLRn0N")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String uniqueName = "1693968324774app_ico.png";
|
||||||
|
String uniqueApkName = "1693223977836Facebook Lite_368.0.0.5.95_Apkpure.apk";
|
||||||
|
|
||||||
|
String url
|
||||||
|
= minioClient.getPresignedObjectUrl(
|
||||||
|
GetPresignedObjectUrlArgs.builder()
|
||||||
|
.method(Method.GET)
|
||||||
|
.bucket("application-bucket")
|
||||||
|
.object("icons/" + uniqueName)
|
||||||
|
.expiry(1, TimeUnit.MINUTES)
|
||||||
|
.build());
|
||||||
|
System.out.println("URL: " + url);
|
||||||
|
|
||||||
|
String apkUrl
|
||||||
|
= minioClient.getPresignedObjectUrl(
|
||||||
|
GetPresignedObjectUrlArgs.builder()
|
||||||
|
.method(Method.GET)
|
||||||
|
.bucket("application-bucket")
|
||||||
|
.object("apps/" + uniqueApkName)
|
||||||
|
.expiry(1, TimeUnit.MINUTES)
|
||||||
|
.build());
|
||||||
|
System.out.println("APK URL: " + apkUrl);
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
18
src/id/iptek/utms/agent/test/TestSubstring.java
Normal file
18
src/id/iptek/utms/agent/test/TestSubstring.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
||||||
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
||||||
|
*/
|
||||||
|
package id.iptek.utms.agent.test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jakar
|
||||||
|
*/
|
||||||
|
public class TestSubstring {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String ackId = "BROADCAST-1234";
|
||||||
|
System.out.println(">> " + ackId.substring(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
135
src/id/iptek/utms/agent/util/FileUtil.java
Normal file
135
src/id/iptek/utms/agent/util/FileUtil.java
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package id.iptek.utms.agent.util;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka Ramdani
|
||||||
|
*/
|
||||||
|
public class FileUtil {
|
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(FileUtil.class);
|
||||||
|
|
||||||
|
private FileUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copy(String srcPath, String dstPath) throws IOException, Exception {
|
||||||
|
copy(srcPath, dstPath, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copy(String srcPath, String dstPath, boolean overwrite) throws IOException, Exception {
|
||||||
|
log.debug("\"{}\" -> \"{}\"", srcPath, dstPath);
|
||||||
|
File srcFile = new File(srcPath);
|
||||||
|
File dstFile = new File(dstPath);
|
||||||
|
|
||||||
|
if (srcFile.exists() && !srcFile.isDirectory()) {
|
||||||
|
if (dstFile.exists() && dstFile.isDirectory()) {
|
||||||
|
String[] _filenames = srcPath.split("[\\/\\\\]");
|
||||||
|
dstFile = new File(dstFile, _filenames[_filenames.length - 1]);
|
||||||
|
} else if (dstFile.exists() && !overwrite) {
|
||||||
|
throw new IOException("Destination file \"" + dstPath + "\" is exists, not overwriting file.");
|
||||||
|
} else if (dstFile.exists()) {
|
||||||
|
//remove existing file
|
||||||
|
if (!dstFile.delete()) {
|
||||||
|
throw new IOException("Can not remove old destination file \"" + dstPath + "\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//create new file
|
||||||
|
byte[] srcBytes = StreamUtil.read(new FileInputStream(srcFile));
|
||||||
|
StreamUtil.write(new FileOutputStream(dstFile), srcBytes, true);
|
||||||
|
} else {
|
||||||
|
throw new IOException("Source file \"" + srcFile + "\" is not exists or is a directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void move(String srcPath, String dstPath) throws IOException, Exception {
|
||||||
|
move(srcPath, dstPath, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void move(String srcPath, String dstPath, boolean overwrite) throws IOException, Exception {
|
||||||
|
copy(srcPath, dstPath, overwrite);
|
||||||
|
delete(srcPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean delete(String path) throws IOException, Exception {
|
||||||
|
File srcFile = new File(path);
|
||||||
|
if (srcFile.exists() && !srcFile.isDirectory()) {
|
||||||
|
boolean deleted = new File(path).delete();
|
||||||
|
if (deleted) {
|
||||||
|
log.debug("\"{}\" removed", path);
|
||||||
|
} else {
|
||||||
|
log.debug("\"{}\" NOT removed", path);
|
||||||
|
}
|
||||||
|
return deleted;
|
||||||
|
} else {
|
||||||
|
throw new IOException("Source file \"" + srcFile + "\" is not exists or is a directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] list(String path) throws IOException, Exception {
|
||||||
|
log.debug("list: \"{}\"", path);
|
||||||
|
return new File(path).list();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] list(String path, FilenameFilter fileNameFilter) throws IOException, Exception {
|
||||||
|
log.debug("list: \"{}\"", path);
|
||||||
|
return new File(path).list(fileNameFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File[] listFiles(File parent, FilenameFilter fileNameFilter) throws IOException, Exception {
|
||||||
|
return listFiles(parent, fileNameFilter, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File[] listFiles(File parent, FilenameFilter fileNameFilter, boolean nameOrdered) throws IOException, Exception {
|
||||||
|
return listFiles(parent.getAbsolutePath(), fileNameFilter, nameOrdered);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File[] listFiles(String path, FilenameFilter fileNameFilter) throws IOException, Exception {
|
||||||
|
return listFiles(path, fileNameFilter, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File[] listFiles(String path, FilenameFilter fileNameFilter, boolean nameOrdered) throws IOException, Exception {
|
||||||
|
log.debug("list: \"{}\"", path);
|
||||||
|
File[] files = new File(path).listFiles(fileNameFilter);
|
||||||
|
if (nameOrdered) {
|
||||||
|
Arrays.sort(files, new Comparator<File>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(File f1, File f2) {
|
||||||
|
return f2.getName().compareTo(f1.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean mkdirs(String path) throws IOException, Exception {
|
||||||
|
return mkdirs(path, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean mkdirs(String path, boolean silentOnExists) throws IOException, Exception {
|
||||||
|
File file = new File(path);
|
||||||
|
if (file.exists()) {
|
||||||
|
if (silentOnExists) {
|
||||||
|
log.debug("\"{}\" is already exists. keep silence ..", path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw new IOException("\"" + path + "\" is already exists.");
|
||||||
|
}
|
||||||
|
boolean created = file.mkdirs();
|
||||||
|
if (created) {
|
||||||
|
log.debug("\"{}\" created", path);
|
||||||
|
} else {
|
||||||
|
log.debug("\"{}\" NOT created", path);
|
||||||
|
}
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
}
|
||||||
71
src/id/iptek/utms/agent/util/IOUtil.java
Normal file
71
src/id/iptek/utms/agent/util/IOUtil.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package id.iptek.utms.agent.util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.Reader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka Ramdani
|
||||||
|
*/
|
||||||
|
public final class IOUtil {
|
||||||
|
|
||||||
|
private IOUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] read(InputStream in) throws IOException {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
int i = -1;
|
||||||
|
byte[] buffer = new byte[1024*4];
|
||||||
|
while( (i = in.read(buffer)) != -1 ) {
|
||||||
|
baos.write(buffer, 0, i);
|
||||||
|
}
|
||||||
|
baos.flush();
|
||||||
|
} finally {
|
||||||
|
close(in);
|
||||||
|
}
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void close(InputStream in) {
|
||||||
|
if(in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
in = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(OutputStream out) {
|
||||||
|
if(out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
out = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Reader reader) {
|
||||||
|
if(reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
reader = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(byte[] bytes, OutputStream out) throws IOException {
|
||||||
|
out.write(bytes);
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(String text, OutputStream out) throws IOException {
|
||||||
|
out.write(text.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/id/iptek/utms/agent/util/Singleton.java
Normal file
29
src/id/iptek/utms/agent/util/Singleton.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package id.iptek.utms.agent.util;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public final class Singleton {
|
||||||
|
|
||||||
|
private final static Map<String, Singleton> INSTANCES = new HashMap<>();
|
||||||
|
private Object object;
|
||||||
|
|
||||||
|
private Singleton() {}
|
||||||
|
|
||||||
|
public void setObject(Object object) {
|
||||||
|
this.object = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getObject() {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Singleton getInstance(String name) {
|
||||||
|
Singleton instance = INSTANCES.get(name);
|
||||||
|
if(instance == null) {
|
||||||
|
instance = new Singleton();
|
||||||
|
INSTANCES.put(name, instance);
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
96
src/id/iptek/utms/agent/util/StreamUtil.java
Normal file
96
src/id/iptek/utms/agent/util/StreamUtil.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package id.iptek.utms.agent.util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka Ramdani
|
||||||
|
*/
|
||||||
|
public final class StreamUtil {
|
||||||
|
|
||||||
|
private StreamUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readAsBase64(InputStream is) throws IOException {
|
||||||
|
byte[] bytes = read(is);
|
||||||
|
return Base64.encodeBase64String(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] read(InputStream is) throws IOException {
|
||||||
|
return read(is, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] read(InputStream is, boolean close) throws IOException {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
byte[] buffer = new byte[10*1024];
|
||||||
|
int i = -1;
|
||||||
|
while( (i = is.read(buffer)) > 0 ) {
|
||||||
|
baos.write(buffer, 0, i);
|
||||||
|
}
|
||||||
|
baos.flush();
|
||||||
|
} finally {
|
||||||
|
if(is != null && close) {
|
||||||
|
try {
|
||||||
|
is.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
is = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(OutputStream os, byte[] bytes, boolean close) throws IOException {
|
||||||
|
try {
|
||||||
|
int maxPerWrite = 10*1024;
|
||||||
|
int len = bytes.length;
|
||||||
|
int written = 0;
|
||||||
|
while(written < len) {
|
||||||
|
int write = (len - written) >= maxPerWrite ? maxPerWrite : (len - written);
|
||||||
|
os.write(bytes, written, write);
|
||||||
|
written += write;
|
||||||
|
}
|
||||||
|
os.flush();
|
||||||
|
} finally {
|
||||||
|
if(os != null && close) {
|
||||||
|
try {
|
||||||
|
os.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
os = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(InputStream in) {
|
||||||
|
if(in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
in = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(OutputStream out) {
|
||||||
|
if(out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch(IOException ignore) {}
|
||||||
|
out = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
String file = "G:\\Pictures\\Avatar-Me.jpg";
|
||||||
|
String imageBase64 = readAsBase64(new FileInputStream(file));
|
||||||
|
System.out.println("ImageBase64:\n" + imageBase64);
|
||||||
|
} catch(Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
134
src/id/iptek/utms/agent/util/StringUtil.java
Normal file
134
src/id/iptek/utms/agent/util/StringUtil.java
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
package id.iptek.utms.agent.util;
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.apache.commons.id.random.SessionIdGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka Ramdani
|
||||||
|
*/
|
||||||
|
public final class StringUtil {
|
||||||
|
|
||||||
|
private StringUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decodeHtml(String strValue) {
|
||||||
|
String strResult = "";
|
||||||
|
if (strValue != null) {
|
||||||
|
String strInfo = strValue;
|
||||||
|
StringBuffer sbResult = null;
|
||||||
|
try {
|
||||||
|
sbResult = new StringBuffer(strInfo);
|
||||||
|
|
||||||
|
int intStart = 0;
|
||||||
|
int intEnd = 0;
|
||||||
|
while (true) {
|
||||||
|
if (strInfo.indexOf("<") != -1) {
|
||||||
|
intStart = strInfo.indexOf("<");
|
||||||
|
intEnd = intStart + "<".length();
|
||||||
|
|
||||||
|
sbResult.replace(intStart, intEnd, "<");
|
||||||
|
strInfo = sbResult.toString();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strInfo.indexOf(">") != -1) {
|
||||||
|
intStart = strInfo.indexOf(">");
|
||||||
|
intEnd = intStart + ">".length();
|
||||||
|
|
||||||
|
sbResult.replace(intStart, intEnd, ">");
|
||||||
|
strInfo = sbResult.toString();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strInfo.indexOf("&") != -1) {
|
||||||
|
intStart = strInfo.indexOf("&");
|
||||||
|
intEnd = intStart + "&".length();
|
||||||
|
|
||||||
|
sbResult.replace(intStart, intEnd, "&");
|
||||||
|
strInfo = sbResult.toString();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strInfo.indexOf(""") != -1) {
|
||||||
|
intStart = strInfo.indexOf(""");
|
||||||
|
intEnd = intStart + """.length();
|
||||||
|
|
||||||
|
sbResult.replace(intStart, intEnd, "\"");
|
||||||
|
strInfo = sbResult.toString();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strInfo.indexOf(" ") == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
intStart = strInfo.indexOf(" ");
|
||||||
|
intEnd = intStart + " ".length();
|
||||||
|
|
||||||
|
sbResult.replace(intStart, intEnd, " ");
|
||||||
|
strInfo = sbResult.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
strResult = sbResult.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
strResult = "";
|
||||||
|
} finally {
|
||||||
|
sbResult = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuilder collect(String msg) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("<HTML>\n");
|
||||||
|
sb.append("<HEAD>\n");
|
||||||
|
sb.append("<TITLE>\n");
|
||||||
|
sb.append("</TITLE>\n");
|
||||||
|
sb.append("</HEAD>\n");
|
||||||
|
sb.append("<BODY background=#ffffff>\n");
|
||||||
|
for (int i = 0; i < msg.length(); i++) {
|
||||||
|
char currentChar = msg.charAt(i);
|
||||||
|
if ((currentChar == '\n') || (currentChar == '\n')) {
|
||||||
|
sb.append("<BR>");
|
||||||
|
} else if (currentChar == ' ') {
|
||||||
|
sb.append(" ");
|
||||||
|
} else {
|
||||||
|
sb.append(currentChar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("</BODY>\n");
|
||||||
|
sb.append("</HTML>\n");
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getMD5Hash(String string) {
|
||||||
|
try {
|
||||||
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
|
md5.update(string.getBytes());
|
||||||
|
byte[] digest = md5.digest();
|
||||||
|
string = Base64.encodeBase64String(digest);
|
||||||
|
} catch (NoSuchAlgorithmException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String byteArrToHexString(byte[] bArr) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < bArr.length; i++) {
|
||||||
|
int unsigned = bArr[i] & 0xff;
|
||||||
|
if (unsigned < 0x10) {
|
||||||
|
sb.append("0");
|
||||||
|
}
|
||||||
|
sb.append(Integer.toHexString((unsigned)));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SessionIdGenerator gidGenerator = new SessionIdGenerator();
|
||||||
|
String gid = DigestUtils.md5Hex(gidGenerator.nextStringIdentifier());
|
||||||
|
System.err.println(">> gid: " + gid);
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/id/iptek/utms/agent/worker/DeviceInitWorker.java
Normal file
58
src/id/iptek/utms/agent/worker/DeviceInitWorker.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package id.iptek.utms.agent.worker;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import id.iptek.utms.agent.AppConfig;
|
||||||
|
import id.iptek.utms.agent.queue.ConsumerMode;
|
||||||
|
import id.iptek.utms.agent.queue.DelayMessageQueue;
|
||||||
|
import id.iptek.utms.agent.queue.DeviceInitQueueMessageHandler;
|
||||||
|
import id.iptek.utms.agent.util.Singleton;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class DeviceInitWorker extends Worker {
|
||||||
|
|
||||||
|
public DeviceInitWorker() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void init(String consumerName, AppConfig appConfig) throws Exception {
|
||||||
|
super.init(consumerName, appConfig);
|
||||||
|
|
||||||
|
DelayMessageQueue<Map> queue = (DelayMessageQueue<Map>) Singleton.getInstance(DeviceInitQueueMessageHandler.NAME).getObject();
|
||||||
|
ConsumerMode mode = ConsumerMode.valueOf(appConfig.get("mqtt.consumer."+consumerName+".consumermode", "SINGLE"));
|
||||||
|
int batchCapacity = appConfig.getAsInt("mqtt.consumer."+consumerName+".batch.capacity", 10);
|
||||||
|
queue.setCapacity(batchCapacity);
|
||||||
|
queue.setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageArrived(String string, MqttMessage mm) throws Exception {
|
||||||
|
try {
|
||||||
|
String json = new String(mm.getPayload());
|
||||||
|
logger.debug("<< " + json + " (" + mm.getId() + " - " + mm.getQos() + ")");
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map map = gson.fromJson(json, Map.class);
|
||||||
|
|
||||||
|
String terminalSN = (String) map.get("device_sn");
|
||||||
|
if(terminalSN == null) {
|
||||||
|
logger.debug("SN Information null!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// put mqttclient to the map
|
||||||
|
map.put("MQTT", mqttClient);
|
||||||
|
|
||||||
|
DelayMessageQueue<Map> queue = (DelayMessageQueue<Map>) Singleton.getInstance(DeviceInitQueueMessageHandler.NAME).getObject();
|
||||||
|
boolean queued = queue.add(map);
|
||||||
|
if(!queued) {
|
||||||
|
logger.error("Init request NOT queued: {}", queued);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Init: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
184
src/id/iptek/utms/agent/worker/DiagnosticWorker.java
Normal file
184
src/id/iptek/utms/agent/worker/DiagnosticWorker.java
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
package id.iptek.utms.agent.worker;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import id.iptek.utms.agent.AppConfig;
|
||||||
|
import id.iptek.utms.agent.model.ApplicationSimple;
|
||||||
|
import id.iptek.utms.agent.model.Diagnostic;
|
||||||
|
import id.iptek.utms.agent.model.DiagnosticInfo;
|
||||||
|
import id.iptek.utms.agent.model.LocationInfo;
|
||||||
|
import id.iptek.utms.agent.queue.ConsumerMode;
|
||||||
|
import id.iptek.utms.agent.queue.DelayMessageQueue;
|
||||||
|
import id.iptek.utms.agent.queue.DiagnosticInfoQueueMessageHandler;
|
||||||
|
import id.iptek.utms.agent.util.Singleton;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
|
|
||||||
|
public class DiagnosticWorker extends Worker {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void init(String consumerName, AppConfig appConfig) throws Exception {
|
||||||
|
super.init(consumerName, appConfig);
|
||||||
|
|
||||||
|
DelayMessageQueue<Diagnostic> queue = (DelayMessageQueue<Diagnostic>) Singleton.getInstance(DiagnosticInfoQueueMessageHandler.NAME).getObject();
|
||||||
|
ConsumerMode mode = ConsumerMode.valueOf(appConfig.get("mqtt.consumer."+consumerName+".consumermode", "SINGLE"));
|
||||||
|
int batchCapacity = appConfig.getAsInt("mqtt.consumer."+consumerName+".batch.capacity", 10);
|
||||||
|
queue.setCapacity(batchCapacity);
|
||||||
|
queue.setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageArrived(String string, MqttMessage mm) throws Exception {
|
||||||
|
try {
|
||||||
|
String json = new String(mm.getPayload());
|
||||||
|
this.logger.debug("<< " + json + " (" + mm.getId() + " - " + mm.getQos() + ")");
|
||||||
|
Gson gson = new Gson();
|
||||||
|
|
||||||
|
Map diagnosticReqMap = (Map) gson.fromJson(json, Map.class);
|
||||||
|
if(!"DIAGNOSTIC".equals((String) diagnosticReqMap.get("req_type"))) {
|
||||||
|
// skip message
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Diagnostic diagnosticReq = mapDiagnosticData(diagnosticReqMap);
|
||||||
|
// set id
|
||||||
|
diagnosticReq.setId(UUID.randomUUID().toString());
|
||||||
|
diagnosticReq.setCreateTime(new Date());
|
||||||
|
|
||||||
|
DelayMessageQueue<Diagnostic> queue = (DelayMessageQueue<Diagnostic>) Singleton.getInstance(DiagnosticInfoQueueMessageHandler.NAME).getObject();
|
||||||
|
boolean queued = queue.add(diagnosticReq);
|
||||||
|
if(!queued) {
|
||||||
|
logger.error("Diagnostic NOT queued: {}", queued);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
this.logger.error("Error saving diagnostic: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Diagnostic mapDiagnosticData(Map map) {
|
||||||
|
String reqId = (String) map.get("req_id");
|
||||||
|
String terminalSN = (String) map.get("device_sn");
|
||||||
|
Diagnostic diagnostic = new Diagnostic();
|
||||||
|
diagnostic.setId(UUID.randomUUID().toString());
|
||||||
|
diagnostic.setReqId(reqId);
|
||||||
|
diagnostic.setDeviceSn(terminalSN);
|
||||||
|
Map diagnosticInfoMap = (Map) map.get("diagnostic_info");
|
||||||
|
boolean isNewDiagnostic = getBoolean(diagnosticInfoMap, "new_diagnostic");
|
||||||
|
DiagnosticInfo diagnosticInfo = new DiagnosticInfo();
|
||||||
|
diagnostic.setDiagnosticInfo(diagnosticInfo);
|
||||||
|
diagnosticInfo.setBatteryPercentage(getInt(diagnosticInfoMap, "battery_percentage"));
|
||||||
|
double temp = getDouble(diagnosticInfoMap, "battery_temp");
|
||||||
|
if (isNewDiagnostic) {
|
||||||
|
temp /= 10.0D;
|
||||||
|
}
|
||||||
|
diagnosticInfo.setBatteryTemp(temp);
|
||||||
|
diagnosticInfo.setMeid((String) diagnosticInfoMap.get("meid"));
|
||||||
|
diagnosticInfo.setTotalMemory((String) diagnosticInfoMap.get("total_memory"));
|
||||||
|
diagnosticInfo.setAvailableMemory((String) diagnosticInfoMap.get("available_memory"));
|
||||||
|
diagnosticInfo.setTotalFlashMemory((String) diagnosticInfoMap.get("total_flash_memory"));
|
||||||
|
diagnosticInfo.setAvailableFlashMemory((String) diagnosticInfoMap.get("available_flash_memory"));
|
||||||
|
diagnosticInfo.setTotalMobileData((String) diagnosticInfoMap.get("total_mobile_data"));
|
||||||
|
diagnosticInfo.setCurrentBootTime(getInt(diagnosticInfoMap, "current_boot_time"));
|
||||||
|
diagnosticInfo.setTotalBootTime(getInt(diagnosticInfoMap, "total_boot_time"));
|
||||||
|
diagnosticInfo.setTotalLengthPrinted(getDouble(diagnosticInfoMap, "total_length_printed"));
|
||||||
|
diagnosticInfo.setSwitchingTimes(getInt(diagnosticInfoMap, "switching_times"));
|
||||||
|
diagnosticInfo.setSwipingCardTimes(getInt(diagnosticInfoMap, "swiping_card_times"));
|
||||||
|
diagnosticInfo.setDipInsertingTimes(getInt(diagnosticInfoMap, "dip_inserting_times"));
|
||||||
|
diagnosticInfo.setNfcCardReadingTimes(getInt(diagnosticInfoMap, "nfc_card_reading_times"));
|
||||||
|
diagnosticInfo.setFrontCameraOpenTimes(getInt(diagnosticInfoMap, "front_camera_open_times"));
|
||||||
|
diagnosticInfo.setRearCameraOpenTimes(getInt(diagnosticInfoMap, "rear_camera_open_times"));
|
||||||
|
diagnosticInfo.setChargeTimes(getInt(diagnosticInfoMap, "charge_times"));
|
||||||
|
List<Map<String, Object>> installedApps = (List<Map<String, Object>>) map.get("installed_apps");
|
||||||
|
if (installedApps != null) {
|
||||||
|
List<ApplicationSimple> applications = new ArrayList<>();
|
||||||
|
installedApps.forEach(appMap -> {
|
||||||
|
String appName = getString(appMap, "app_name");
|
||||||
|
String packageName = getString(appMap, "package_name");
|
||||||
|
String version = getString(appMap, "version");
|
||||||
|
ApplicationSimple appSimple = new ApplicationSimple();
|
||||||
|
appSimple.setId(UUID.randomUUID().toString());
|
||||||
|
appSimple.setAppName(appName);
|
||||||
|
appSimple.setPackageName(packageName);
|
||||||
|
appSimple.setVersion(version);
|
||||||
|
applications.add(appSimple);
|
||||||
|
});
|
||||||
|
diagnostic.setInstalledApps(applications);
|
||||||
|
Gson gson = new Gson();
|
||||||
|
String installedAppString = gson.toJson(applications);
|
||||||
|
diagnosticInfo.setInstalledAppString(installedAppString);
|
||||||
|
}
|
||||||
|
Map locationInfoMap = (Map) map.get("location_info");
|
||||||
|
LocationInfo locationInfo = new LocationInfo();
|
||||||
|
diagnostic.setLocationInfo(locationInfo);
|
||||||
|
locationInfo.setLat((Double) locationInfoMap.get("lat"));
|
||||||
|
locationInfo.setLng((Double) locationInfoMap.get("lng"));
|
||||||
|
return diagnostic;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getBoolean(Map map, String key) {
|
||||||
|
Object val = map.get(key);
|
||||||
|
if (val instanceof String) {
|
||||||
|
String sVal = (String) val;
|
||||||
|
return Boolean.parseBoolean(sVal.trim());
|
||||||
|
}
|
||||||
|
if (val instanceof Boolean) {
|
||||||
|
return ((Boolean) val).booleanValue();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getDouble(Map map, String key) {
|
||||||
|
Object val = map.get(key);
|
||||||
|
if (val instanceof String) {
|
||||||
|
String sVal = (String) val;
|
||||||
|
return Double.parseDouble(sVal.trim());
|
||||||
|
}
|
||||||
|
if (val instanceof Double) {
|
||||||
|
return ((Double) val).doubleValue();
|
||||||
|
}
|
||||||
|
if (val instanceof Integer) {
|
||||||
|
return ((Double) val).doubleValue();
|
||||||
|
}
|
||||||
|
return 0.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getInt(Map map, String key) {
|
||||||
|
Object val = map.get(key);
|
||||||
|
if (val instanceof String) {
|
||||||
|
String sVal = (String) val;
|
||||||
|
return Integer.parseInt(sVal.trim());
|
||||||
|
}
|
||||||
|
if (val instanceof Integer) {
|
||||||
|
return ((Integer) val).intValue();
|
||||||
|
}
|
||||||
|
if (val instanceof Double) {
|
||||||
|
return ((Double) val).intValue();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getLong(Map map, String key) {
|
||||||
|
Object val = map.get(key);
|
||||||
|
if (val instanceof String) {
|
||||||
|
String sVal = (String) val;
|
||||||
|
if (sVal.contains("B")) {
|
||||||
|
sVal = sVal.replace("B", "");
|
||||||
|
}
|
||||||
|
return Long.parseLong(sVal.trim());
|
||||||
|
}
|
||||||
|
if (val instanceof Long) {
|
||||||
|
return ((Long) val).longValue();
|
||||||
|
}
|
||||||
|
if (val instanceof Double) {
|
||||||
|
return ((Double) val).longValue();
|
||||||
|
}
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getString(Map map, String key) {
|
||||||
|
return (String) map.get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
165
src/id/iptek/utms/agent/worker/DownloadTaskAckWorker.java
Normal file
165
src/id/iptek/utms/agent/worker/DownloadTaskAckWorker.java
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
package id.iptek.utms.agent.worker;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import id.iptek.utms.agent.GenericCache;
|
||||||
|
import id.iptek.utms.agent.dao.DownloadTaskDao;
|
||||||
|
import id.iptek.utms.agent.dao.TerminalDao;
|
||||||
|
import id.iptek.utms.agent.model.TaskAckReq;
|
||||||
|
import id.iptek.utms.agent.model.TerminalIdObj;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class DownloadTaskAckWorker extends Worker {
|
||||||
|
|
||||||
|
private DownloadTaskDao dao = new DownloadTaskDao();
|
||||||
|
private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
private TerminalDao terminalDao = new TerminalDao();
|
||||||
|
|
||||||
|
public DownloadTaskAckWorker() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageArrived(String string, MqttMessage mm) throws Exception {
|
||||||
|
try {
|
||||||
|
String json = new String(mm.getPayload());
|
||||||
|
logger.debug("<< " + json + " (" + mm.getId() + " - " + mm.getQos() + ")");
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map map = gson.fromJson(json, Map.class);
|
||||||
|
|
||||||
|
String reqId = UUID.randomUUID().toString();
|
||||||
|
String requestType = (String) map.get("req_type");
|
||||||
|
if(!"DOWNLOAD_ACK".equals(requestType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String terminalSN = (String) map.get("device_sn");
|
||||||
|
String ackId = (String) map.get("ack_id");
|
||||||
|
String status = (String) map.get("status");
|
||||||
|
if("ACCEPTED".equals(status)) {
|
||||||
|
status = "NOT_STARTED";
|
||||||
|
}
|
||||||
|
int activity = translateActivityFromStatus(status);
|
||||||
|
|
||||||
|
TaskAckReq req = new TaskAckReq();
|
||||||
|
req.setReqId(reqId);
|
||||||
|
req.setAckId(ackId);
|
||||||
|
req.setTerminalSN(terminalSN);
|
||||||
|
req.setActivity(activity);
|
||||||
|
if(ackId.startsWith("BROADCAST_")) {
|
||||||
|
String taskId = ackId.substring(10);
|
||||||
|
req.setBroadcasted(true);
|
||||||
|
req.setTaskId(taskId);
|
||||||
|
}
|
||||||
|
// get terminal id from cache
|
||||||
|
String terminalId = getTerminalIdBySN(terminalSN);
|
||||||
|
if(terminalId != null) {
|
||||||
|
req.setTerminalId(terminalId);
|
||||||
|
boolean saved = dao.save(req);
|
||||||
|
logger.debug("Download task ACK request saved? {}", saved);
|
||||||
|
if(saved) {
|
||||||
|
if("INSTALL_SUCCESS".equals(status) ||
|
||||||
|
"INSTALL_FAIL".equals(status)) {
|
||||||
|
// send ack DOWNLOAD_TASK_CONFIRM_ACK
|
||||||
|
broadcastDownloadTasksConfirmACK(mqttClient, terminalSN, ackId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn("Invalid SN: {}", terminalSN);
|
||||||
|
}
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Download task ACK: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int translateActivityFromStatus(String status) {
|
||||||
|
int activity = 0; // initial
|
||||||
|
switch(status) {
|
||||||
|
case "INITIAL":
|
||||||
|
activity = 0;
|
||||||
|
break;
|
||||||
|
case "NOT_STARTED":
|
||||||
|
activity = 1;
|
||||||
|
break;
|
||||||
|
case "DOWNLOAD_STARTED":
|
||||||
|
activity = 2;
|
||||||
|
break;
|
||||||
|
case "DOWNLOAD_SUCCESS":
|
||||||
|
activity = 3;
|
||||||
|
break;
|
||||||
|
case "DOWNLOAD_FAIL":
|
||||||
|
activity = 4;
|
||||||
|
break;
|
||||||
|
case "INSTALL_STARTED":
|
||||||
|
activity = 5;
|
||||||
|
break;
|
||||||
|
case "INSTALL_SUCCESS":
|
||||||
|
activity = 6;
|
||||||
|
break;
|
||||||
|
case "INSTALL_FAIL":
|
||||||
|
activity = 7;
|
||||||
|
break;
|
||||||
|
case "ACCEPTED":
|
||||||
|
activity = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send download task to device topic via mqtt
|
||||||
|
public void broadcastDownloadTasksConfirmACK(MqttClient mqttClient,
|
||||||
|
String terminalSN,
|
||||||
|
String ackId) throws Exception {
|
||||||
|
logger.debug("Broadcast tasks ...");
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
int qos = 2;
|
||||||
|
String topicName = terminalSN.toUpperCase() + "_IN";
|
||||||
|
// generate json
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map messageMap = new HashMap<>();
|
||||||
|
messageMap.put("req_id", UUID.randomUUID().toString());
|
||||||
|
messageMap.put("req_time", dateTimeFormat.format(new Date()));
|
||||||
|
// we'll use log's id as ack_id
|
||||||
|
messageMap.put("ack_id", ackId);
|
||||||
|
messageMap.put("req_type", "DOWNLOAD_TASK_CONFIRM_ACK");
|
||||||
|
|
||||||
|
String messageData = gson.toJson(messageMap);
|
||||||
|
|
||||||
|
logger.debug("Try publish message to: {}", topicName);
|
||||||
|
mqttClient.publish(topicName, messageData.getBytes(), qos, false);
|
||||||
|
logger.debug("Message published!");
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error publish to device: {}", ex.getMessage(), ex);
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
logger.debug("Start broadcast download tasks DONE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTerminalIdBySN(String sn) throws Exception {
|
||||||
|
try {
|
||||||
|
GenericCache cache = GenericCache.getCache("terminalId");
|
||||||
|
String terminalId = (String) cache.get(sn.toLowerCase());
|
||||||
|
if(terminalId == null) {
|
||||||
|
// load from db first
|
||||||
|
TerminalIdObj terminalObj = terminalDao.getTerminalIdBySN(sn);
|
||||||
|
if(terminalObj != null) {
|
||||||
|
terminalId = terminalObj.getTerminalId();
|
||||||
|
cache.put(sn.toLowerCase(), terminalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return terminalId;
|
||||||
|
} finally {}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/id/iptek/utms/agent/worker/HeartbeatWorker.java
Normal file
64
src/id/iptek/utms/agent/worker/HeartbeatWorker.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package id.iptek.utms.agent.worker;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import id.iptek.utms.agent.AppConfig;
|
||||||
|
import id.iptek.utms.agent.model.HeartBeat;
|
||||||
|
import id.iptek.utms.agent.queue.ConsumerMode;
|
||||||
|
import id.iptek.utms.agent.queue.DelayMessageQueue;
|
||||||
|
import id.iptek.utms.agent.queue.HeartBeatQueueMessageHandler;
|
||||||
|
import id.iptek.utms.agent.util.Singleton;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public class HeartbeatWorker extends Worker {
|
||||||
|
|
||||||
|
public HeartbeatWorker() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void init(String consumerName, AppConfig appConfig) throws Exception {
|
||||||
|
super.init(consumerName, appConfig);
|
||||||
|
|
||||||
|
DelayMessageQueue<HeartBeat> queue = (DelayMessageQueue<HeartBeat>) Singleton.getInstance(HeartBeatQueueMessageHandler.NAME).getObject();
|
||||||
|
ConsumerMode mode = ConsumerMode.valueOf(appConfig.get("mqtt.consumer."+consumerName+".consumermode", "SINGLE"));
|
||||||
|
int batchCapacity = appConfig.getAsInt("mqtt.consumer."+consumerName+".batch.capacity", 10);
|
||||||
|
queue.setCapacity(batchCapacity);
|
||||||
|
queue.setMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doSomething() throws Exception {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void messageArrived(String string, MqttMessage mm) throws Exception {
|
||||||
|
try {
|
||||||
|
String json = new String(mm.getPayload());
|
||||||
|
logger.debug("<< " + json + " (" + mm.getId() + " - " + mm.getQos() + ")");
|
||||||
|
Gson gson = new Gson();
|
||||||
|
HeartBeat heartbeatReq = gson.fromJson(json, HeartBeat.class);
|
||||||
|
if(!"HEARTBEAT".equals(heartbeatReq.getReqType())) {
|
||||||
|
// skip message
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set id
|
||||||
|
heartbeatReq.setId(UUID.randomUUID().toString());
|
||||||
|
heartbeatReq.setCreateTime(new Date());
|
||||||
|
|
||||||
|
DelayMessageQueue<HeartBeat> queue = (DelayMessageQueue<HeartBeat>) Singleton.getInstance(HeartBeatQueueMessageHandler.NAME).getObject();
|
||||||
|
boolean queued = queue.add(heartbeatReq);
|
||||||
|
if(!queued) {
|
||||||
|
logger.error("Heartbeat NOT queued: {}", queued);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error processing heartbeat: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
623
src/id/iptek/utms/agent/worker/Worker.java
Normal file
623
src/id/iptek/utms/agent/worker/Worker.java
Normal file
@ -0,0 +1,623 @@
|
|||||||
|
package id.iptek.utms.agent.worker;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import id.iptek.utms.agent.AppConfig;
|
||||||
|
import id.iptek.utms.agent.GenericCache;
|
||||||
|
import id.iptek.utms.agent.dao.DeleteTaskDao;
|
||||||
|
import id.iptek.utms.agent.dao.DownloadTaskDao;
|
||||||
|
import id.iptek.utms.agent.model.Application;
|
||||||
|
import id.iptek.utms.agent.model.ApplicationSimple;
|
||||||
|
import id.iptek.utms.agent.model.PendingDeleteTask;
|
||||||
|
import id.iptek.utms.agent.model.PendingDownloadTask;
|
||||||
|
import id.iptek.utms.agent.model.SimplePendingDownloadTask;
|
||||||
|
import id.iptek.utms.agent.util.IOUtil;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
|
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttClient;
|
||||||
|
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||||
|
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public abstract class Worker implements MqttCallbackExtended, Runnable {
|
||||||
|
|
||||||
|
protected Logger logger;
|
||||||
|
private String brokerUrl;
|
||||||
|
private String loggingId;
|
||||||
|
private String topic;
|
||||||
|
private String clientIdPrefix;
|
||||||
|
private String user;
|
||||||
|
private String password;
|
||||||
|
private long sleep;
|
||||||
|
private long keepAlive;
|
||||||
|
private boolean cleanSession;
|
||||||
|
private int maxInflight;
|
||||||
|
private boolean autoReconnect;
|
||||||
|
private long reconnectDelayMillis;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mqtt *
|
||||||
|
*/
|
||||||
|
private MemoryPersistence persistence = new MemoryPersistence();
|
||||||
|
protected MqttClient mqttClient;
|
||||||
|
private volatile boolean running = false;
|
||||||
|
|
||||||
|
private DeleteTaskDao deleteTaskDao = new DeleteTaskDao();
|
||||||
|
private DownloadTaskDao downloadTaskDao = new DownloadTaskDao();
|
||||||
|
private static final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
private static final SimpleDateFormat sdfYEAR = new SimpleDateFormat("yyyy");
|
||||||
|
private static final SimpleDateFormat sdfMONTH = new SimpleDateFormat("MM");
|
||||||
|
private static final SimpleDateFormat sdfDATE = new SimpleDateFormat("dd");
|
||||||
|
|
||||||
|
protected ExecutorService executorService = null;
|
||||||
|
|
||||||
|
public Worker() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExecutorService(ExecutorService executorService) {
|
||||||
|
this.executorService = executorService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the brokerUrl
|
||||||
|
*/
|
||||||
|
public String getBrokerUrl() {
|
||||||
|
return brokerUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the loggingId
|
||||||
|
*/
|
||||||
|
public String getLoggingId() {
|
||||||
|
return loggingId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the topic
|
||||||
|
*/
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the clientIdPrefix
|
||||||
|
*/
|
||||||
|
public String getClientIdPrefix() {
|
||||||
|
return clientIdPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the user
|
||||||
|
*/
|
||||||
|
public String getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the password
|
||||||
|
*/
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sleep
|
||||||
|
*/
|
||||||
|
public long getSleep() {
|
||||||
|
return sleep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the keepAlive
|
||||||
|
*/
|
||||||
|
public long getKeepAlive() {
|
||||||
|
return keepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cleanSession
|
||||||
|
*/
|
||||||
|
public boolean isCleanSession() {
|
||||||
|
return cleanSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maxInflight
|
||||||
|
*/
|
||||||
|
public int getMaxInflight() {
|
||||||
|
return maxInflight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the autoReconnect
|
||||||
|
*/
|
||||||
|
public boolean isAutoReconnect() {
|
||||||
|
return autoReconnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(String consumerName, AppConfig appConfig) throws Exception {
|
||||||
|
String _brokerUrl = appConfig.get("mqtt.broker.url");
|
||||||
|
String _loggingId = appConfig.get("mqtt.consumer." + consumerName + ".loggingid");
|
||||||
|
String _topic = appConfig.get("mqtt.consumer." + consumerName + ".topic");
|
||||||
|
String _clientIdPrefix = appConfig.get("mqtt.consumer." + consumerName + ".clientid_prefix");
|
||||||
|
String _user = appConfig.get("mqtt.consumer." + consumerName + ".user");
|
||||||
|
String _password = appConfig.get("mqtt.consumer." + consumerName + ".password");
|
||||||
|
long _sleep = appConfig.getAsLong("mqtt.consumer." + consumerName + ".sleep");
|
||||||
|
long _keepAlive = appConfig.getAsLong("mqtt.consumer." + consumerName + ".keepalive", 10L);
|
||||||
|
int _maxInflight = appConfig.getAsInt("mqtt.consumer." + consumerName + ".maxinflight", 32);
|
||||||
|
boolean _cleanSession = appConfig.getAsBoolean("mqtt.consumer." + consumerName + ".cleansession", true);
|
||||||
|
boolean _autoReconnect = appConfig.getAsBoolean("mqtt.consumer." + consumerName + ".autoreconnect", true);
|
||||||
|
long _reconnectDelayMillis = appConfig.getAsLong("mqtt.consumer." + consumerName + ".reconnect.delay.millis", 5000L);
|
||||||
|
|
||||||
|
this.brokerUrl = _brokerUrl;
|
||||||
|
this.loggingId = _loggingId;
|
||||||
|
this.topic = _topic;
|
||||||
|
this.clientIdPrefix = _clientIdPrefix;
|
||||||
|
this.user = _user;
|
||||||
|
this.password = _password;
|
||||||
|
this.sleep = _sleep;
|
||||||
|
this.keepAlive = _keepAlive;
|
||||||
|
this.maxInflight = _maxInflight;
|
||||||
|
this.cleanSession = _cleanSession;
|
||||||
|
this.autoReconnect = _autoReconnect;
|
||||||
|
this.reconnectDelayMillis = _reconnectDelayMillis;
|
||||||
|
|
||||||
|
// init logger
|
||||||
|
//logger = LoggerFactory.getLogger(getClass() + "." + _loggingId);
|
||||||
|
logger = LoggerFactory.getLogger(getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws Exception {
|
||||||
|
try {
|
||||||
|
this.running = true;
|
||||||
|
|
||||||
|
logger.info("Starting ...");
|
||||||
|
String clientId = getClientIdPrefix() + RandomStringUtils.randomAlphanumeric(10);
|
||||||
|
mqttClient = new MqttClient(brokerUrl, clientId, persistence);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() throws Exception {
|
||||||
|
try {
|
||||||
|
this.running = false;
|
||||||
|
if (mqttClient != null) {
|
||||||
|
mqttClient.disconnectForcibly(0L, 250L, false);
|
||||||
|
mqttClient.close(true);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectionLost(Throwable thrwbl) {
|
||||||
|
logger.warn("Connection Lost: " + thrwbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deliveryComplete(IMqttDeliveryToken imdt) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectComplete(boolean bln, String string) {
|
||||||
|
if (getTopic() != null) {
|
||||||
|
try {
|
||||||
|
logger.info("Connected, subscribe to '{}'", getTopic());
|
||||||
|
mqttClient.subscribe(getTopic());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error subscribe topic: " + topic);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.debug("No topic subscribed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
if (mqttClient != null && !mqttClient.isConnected()) {
|
||||||
|
MqttConnectOptions connOpts = new MqttConnectOptions();
|
||||||
|
connOpts.setCleanSession(isCleanSession());
|
||||||
|
connOpts.setUserName(getUser());
|
||||||
|
if (getPassword() != null) {
|
||||||
|
connOpts.setPassword(getPassword().toCharArray());
|
||||||
|
}
|
||||||
|
connOpts.setAutomaticReconnect(isAutoReconnect());
|
||||||
|
connOpts.setKeepAliveInterval((int) getKeepAlive());
|
||||||
|
connOpts.setMaxInflight(getMaxInflight());
|
||||||
|
mqttClient.setCallback(this);
|
||||||
|
logger.info("Started ...");
|
||||||
|
|
||||||
|
logger.info("Try to connect ...");
|
||||||
|
try {
|
||||||
|
mqttClient.connect(connOpts);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error connect MQTT broker: {}", ex.getMessage(), ex);
|
||||||
|
sleepBeforeReconnect();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do something
|
||||||
|
try {
|
||||||
|
doSomething();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error doing something: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getSleep() != 0L) {
|
||||||
|
try {
|
||||||
|
logger.info("Sleep for {} ms", getSleep());
|
||||||
|
TimeUnit.MILLISECONDS.sleep(getSleep());
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
logger.error("Sleep got interrupted: {}", ex.getMessage(), ex);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error run: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
} while (running);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sleepBeforeReconnect() {
|
||||||
|
try {
|
||||||
|
logger.info("Wait {} ms before reconnecting MQTT broker", reconnectDelayMillis);
|
||||||
|
TimeUnit.MILLISECONDS.sleep(reconnectDelayMillis);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
logger.error("Reconnect wait interrupted: {}", ex.getMessage(), ex);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doSomething() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
protected void publishPendingTasks(String terminalSN) {
|
||||||
|
boolean dummy = true;
|
||||||
|
if (dummy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pending delete task
|
||||||
|
List<PendingDeleteTask> pendingDeleteTaskList = deleteTaskDao.getPendingTaskForTerminal(terminalSN);
|
||||||
|
pendingDeleteTaskList.forEach((t) -> {
|
||||||
|
try {
|
||||||
|
broadcastDeleteTasksToDevice(mqttClient, t);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error push delete task: [{}, {}, {}]", t.getTerminalSN(), t.getId(), t.getLogId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// pending download task
|
||||||
|
List<PendingDownloadTask> pendingDownloadTaskList = downloadTaskDao.getPendingTaskForTerminal(terminalSN);
|
||||||
|
pendingDownloadTaskList.forEach((t) -> {
|
||||||
|
try {
|
||||||
|
broadcastDownloadTasksToDevice(mqttClient, t);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error push download task: [{}, {}, {}]", t.getTerminalSN(), t.getId(), t.getLogId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void publishPendingTasksForAll(int limit, int periodeMinutes, boolean checkOnline) {
|
||||||
|
// pending delete task
|
||||||
|
Date currentTime = downloadTaskDao.getCurrentTime();
|
||||||
|
logger.debug("Current server time: {}", currentTime);
|
||||||
|
logger.debug("Get all pending delete tasks ..");
|
||||||
|
List<PendingDeleteTask> pendingDeleteTaskList = null;
|
||||||
|
|
||||||
|
if(checkOnline) {
|
||||||
|
pendingDeleteTaskList = deleteTaskDao.getPendingTaskForOnlineTerminals(periodeMinutes, limit);
|
||||||
|
} else {
|
||||||
|
pendingDeleteTaskList = deleteTaskDao.getPendingTaskForTerminals(periodeMinutes, limit);
|
||||||
|
}
|
||||||
|
logger.debug("... got {} task item.", pendingDeleteTaskList.size());
|
||||||
|
pendingDeleteTaskList.forEach((t) -> {
|
||||||
|
try {
|
||||||
|
broadcastDeleteTasksToDevice(mqttClient, t);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error push delete task: [{}, {}, {}]", t.getTerminalSN(), t.getId(), t.getLogId(), ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.debug("Get all pending download tasks ..");
|
||||||
|
List<PendingDownloadTask> pendingDownloadTaskList = null;
|
||||||
|
if(checkOnline) {
|
||||||
|
pendingDownloadTaskList = downloadTaskDao.getPendingTaskForOnlineTerminals(periodeMinutes, limit);
|
||||||
|
} else {
|
||||||
|
pendingDownloadTaskList = downloadTaskDao.getPendingTaskForTerminals(periodeMinutes, limit);
|
||||||
|
}
|
||||||
|
logger.debug("... got {} task item.", pendingDownloadTaskList.size());
|
||||||
|
pendingDownloadTaskList.forEach((t) -> {
|
||||||
|
try {
|
||||||
|
broadcastDownloadTasksToDevice(mqttClient, t);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
logger.error("Error push download task: [{}, {}, {}]", t.getTerminalSN(), t.getId(), t.getLogId(), ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void publishBroadcastPendingTasksForAll() {
|
||||||
|
// pending delete task
|
||||||
|
Date currentTime = downloadTaskDao.getCurrentTime();
|
||||||
|
logger.debug("Current server time: {}", currentTime);
|
||||||
|
logger.debug("Get all pending download tasks ..");
|
||||||
|
// pending download task
|
||||||
|
logger.debug("Get next BROADCAST pending download tasks ..");
|
||||||
|
PendingDownloadTask nextBroadcastDownloadTask = downloadTaskDao.getNextPendingTaskForBroadcast();
|
||||||
|
if(nextBroadcastDownloadTask != null) {
|
||||||
|
logger.debug("Pending BROADCAST download task: \"{}\"", nextBroadcastDownloadTask.getName());
|
||||||
|
try {
|
||||||
|
// cache last broadcasted task
|
||||||
|
GenericCache taskCache = GenericCache.getCache("LAST_BROADCAST_DOWNLOAD_TASK");
|
||||||
|
taskCache.put("task_id", nextBroadcastDownloadTask.getId());
|
||||||
|
|
||||||
|
broadcastDownloadTasksToDevice(mqttClient, nextBroadcastDownloadTask);
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error BROADCAST download task: [{}]", nextBroadcastDownloadTask.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send delete task to device topic via mqtt
|
||||||
|
private void broadcastDeleteTasksToDevice(MqttClient mqttClient,
|
||||||
|
PendingDeleteTask task) throws Exception {
|
||||||
|
logger.debug("Broadcast tasks ...");
|
||||||
|
try {
|
||||||
|
int qos = 2;
|
||||||
|
String topicName = task.getTerminalSN().toUpperCase() + "_IN";
|
||||||
|
// generate json
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map messageMap = new HashMap<>();
|
||||||
|
messageMap.put("req_id", UUID.randomUUID().toString());
|
||||||
|
messageMap.put("req_time", dateTimeFormat.format(new Date()));
|
||||||
|
// we'll use log's id as ack_id
|
||||||
|
messageMap.put("ack_id", task.getLogId());
|
||||||
|
messageMap.put("req_type", "DELETE_APP_TASK");
|
||||||
|
// task map
|
||||||
|
Map taskMap = new HashMap<>();
|
||||||
|
taskMap.put("id", task.getId());
|
||||||
|
taskMap.put("name", task.getName());
|
||||||
|
taskMap.put("delete_time", task.getDeleteTime() != null ? dateTimeFormat.format(task.getDeleteTime()) : null);
|
||||||
|
messageMap.put("task", taskMap);
|
||||||
|
// app map
|
||||||
|
ApplicationSimple app = task.getApp();
|
||||||
|
Map appMap = new HashMap<>();
|
||||||
|
appMap.put("id", app.getId());
|
||||||
|
appMap.put("name", app.getAppName());
|
||||||
|
appMap.put("package_name", app.getPackageName());
|
||||||
|
messageMap.put("app", appMap);
|
||||||
|
|
||||||
|
String messageData = gson.toJson(messageMap);
|
||||||
|
|
||||||
|
logger.debug("Try publish message to: {}", topicName);
|
||||||
|
mqttClient.publish(topicName, messageData.getBytes(), qos, false);
|
||||||
|
logger.debug("Message published!");
|
||||||
|
|
||||||
|
// change log's last broadcast time
|
||||||
|
boolean updated = deleteTaskDao.saveLastBroadcastTs(task);
|
||||||
|
logger.debug("Delete task log last broadcast time updated? {}", updated);
|
||||||
|
} finally {
|
||||||
|
logger.debug("Start broadcast delete tasks DONE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send download task to device topic via mqtt
|
||||||
|
protected void broadcastDownloadTasksToDevice(MqttClient mqttClient,
|
||||||
|
PendingDownloadTask task) throws Exception {
|
||||||
|
logger.debug("Broadcast tasks ...");
|
||||||
|
try {
|
||||||
|
int qos = 2;
|
||||||
|
String topicName;
|
||||||
|
if(!"SN".equals(task.getTerminalSN().toUpperCase())) {
|
||||||
|
topicName = task.getTerminalSN().toUpperCase() + "_IN";
|
||||||
|
} else {
|
||||||
|
topicName = "SERVER_OUT";
|
||||||
|
}
|
||||||
|
// generate json
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map messageMap = new HashMap<>();
|
||||||
|
messageMap.put("req_id", UUID.randomUUID().toString());
|
||||||
|
messageMap.put("req_time", dateTimeFormat.format(new Date()));
|
||||||
|
// we'll use log's id as ack_id
|
||||||
|
messageMap.put("ack_id", task.getLogId());
|
||||||
|
messageMap.put("req_type", "DOWNLOAD_APP_TASK");
|
||||||
|
// task map
|
||||||
|
Map taskMap = new HashMap<>();
|
||||||
|
taskMap.put("id", task.getId());
|
||||||
|
taskMap.put("name", task.getName());
|
||||||
|
taskMap.put("download_time_type", getDownloadTimeTypeName(task.getDownloadTimeType()));
|
||||||
|
if (task.getDownloadTimeType() == 2) {
|
||||||
|
taskMap.put("download_time", dateTimeFormat.format(task.getDownloadTime()));
|
||||||
|
}
|
||||||
|
taskMap.put("installation_time_type", getInstallationTimeTypeName(task.getInstallationTimeType()));
|
||||||
|
if (task.getInstallationTimeType() == 2) {
|
||||||
|
taskMap.put("installation_time", dateTimeFormat.format(task.getInstallationTime()));
|
||||||
|
}
|
||||||
|
taskMap.put("installation_notification", getInstallationNotificationName(task.getInstallationNotification()));
|
||||||
|
messageMap.put("task", taskMap);
|
||||||
|
// app map
|
||||||
|
Application app = task.getApp();
|
||||||
|
Map appMap = new HashMap<>();
|
||||||
|
appMap.put("id", app.getId());
|
||||||
|
appMap.put("name", app.getAppName());
|
||||||
|
appMap.put("package_name", app.getPackageName());
|
||||||
|
appMap.put("version", app.getVersion());
|
||||||
|
appMap.put("company", app.getCompanyName());
|
||||||
|
appMap.put("uninstallable", app.isUninstallable());
|
||||||
|
appMap.put("description", app.getDescription());
|
||||||
|
if (app.getDownloadUrl() != null) {
|
||||||
|
appMap.put("download_url", app.getDownloadUrl());
|
||||||
|
appMap.put("md5_checksum", app.getChecksum());
|
||||||
|
} else {
|
||||||
|
String downloadURL = AppConfig.getInstance().get("file.download.url");
|
||||||
|
if (downloadURL != null) {
|
||||||
|
downloadURL = downloadURL.replace("{$id}", app.getApkId());
|
||||||
|
}
|
||||||
|
appMap.put("download_url", downloadURL);
|
||||||
|
String filePath = getFilePath(app.getFileId(), app.getFileExt(), app.getFileCreateDate());
|
||||||
|
appMap.put("md5_checksum", md5Checksum(IOUtil.read(new FileInputStream(filePath))));
|
||||||
|
}
|
||||||
|
messageMap.put("app", appMap);
|
||||||
|
|
||||||
|
String messageData = gson.toJson(messageMap);
|
||||||
|
|
||||||
|
logger.debug("Try publish message to: {}", topicName);
|
||||||
|
mqttClient.publish(topicName, messageData.getBytes(), qos, false);
|
||||||
|
logger.debug("Message published!");
|
||||||
|
|
||||||
|
// change log's last broadcast time
|
||||||
|
if(!"BROADCAST".equals(task.getLogId())) {
|
||||||
|
boolean updated = downloadTaskDao.saveLastBroadcastTs(task);
|
||||||
|
logger.debug("Download task log last broadcast time updated? {}", updated);
|
||||||
|
} else {
|
||||||
|
logger.debug("Do not update last broadcast time because this is broadcasted task!");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
logger.debug("Start broadcast download tasks DONE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send NONE ack for invalid download task-SN to device topic via mqtt
|
||||||
|
protected void broadcastNoneDownloadTasksToDevice(MqttClient mqttClient,
|
||||||
|
String sn, String taskId) throws Exception {
|
||||||
|
logger.debug("Broadcast NONE tasks ...");
|
||||||
|
try {
|
||||||
|
int qos = 2;
|
||||||
|
String topicName = sn.toUpperCase() + "_IN";
|
||||||
|
// generate json
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map messageMap = new HashMap<>();
|
||||||
|
messageMap.put("req_id", UUID.randomUUID().toString());
|
||||||
|
messageMap.put("req_type", "NONE");
|
||||||
|
messageMap.put("req_time", dateTimeFormat.format(new Date()));
|
||||||
|
messageMap.put("task_id", taskId);
|
||||||
|
|
||||||
|
String messageData = gson.toJson(messageMap);
|
||||||
|
|
||||||
|
logger.debug("Try publish message to: {}", topicName);
|
||||||
|
mqttClient.publish(topicName, messageData.getBytes(), qos, false);
|
||||||
|
logger.debug("Message published!");
|
||||||
|
} finally {
|
||||||
|
logger.debug("Start broadcast NONE download tasks DONE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void publishBroadcastCheckPendingTasksForAll() {
|
||||||
|
// pending check task
|
||||||
|
Date currentTime = downloadTaskDao.getCurrentTime();
|
||||||
|
logger.debug("Current server time: {}", currentTime);
|
||||||
|
logger.debug("Get all pending check tasks ..");
|
||||||
|
List<SimplePendingDownloadTask> tasks = downloadTaskDao.getPendingTasksForBroadcast();
|
||||||
|
if(!tasks.isEmpty()) {
|
||||||
|
tasks.forEach((task) -> {
|
||||||
|
try {
|
||||||
|
logger.debug("Pending BROADCAST check task: \"{} - {}\"", task.getId(), task.getName());
|
||||||
|
broadcastCheckTaskToDevice(mqttClient, task);
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.error("Error BROADCAST check task: [{} - {}]", task.getId(), task.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// broadcast check task to all device topic via mqtt
|
||||||
|
private void broadcastCheckTaskToDevice(MqttClient mqttClient,
|
||||||
|
SimplePendingDownloadTask task) throws Exception {
|
||||||
|
logger.debug("Broadcast tasks ...");
|
||||||
|
try {
|
||||||
|
int qos = 2;
|
||||||
|
String topicName = "SERVER_OUT";
|
||||||
|
// generate json
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Map messageMap = new HashMap<>();
|
||||||
|
messageMap.put("req_id", UUID.randomUUID().toString());
|
||||||
|
messageMap.put("req_time", dateTimeFormat.format(new Date()));
|
||||||
|
// we'll put task id here as key so same task will be ignored by device if received
|
||||||
|
// more than 1 time
|
||||||
|
messageMap.put("task_id", task.getId());
|
||||||
|
messageMap.put("req_type", "CHECK_TASK");
|
||||||
|
messageMap.put("group_list", task.getGroupIds());
|
||||||
|
|
||||||
|
String messageData = gson.toJson(messageMap);
|
||||||
|
|
||||||
|
logger.debug("Try publish message to: {}", topicName);
|
||||||
|
mqttClient.publish(topicName, messageData.getBytes(), qos, false);
|
||||||
|
logger.debug("Message published!");
|
||||||
|
} finally {
|
||||||
|
logger.debug("Start broadcast check tasks DONE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDownloadTimeTypeName(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return "NEXT_CONTACT";
|
||||||
|
case 2:
|
||||||
|
return "DATETIME";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getInstallationTimeTypeName(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return "IMMEDIATE_AFTER_DOWNLOAD";
|
||||||
|
case 2:
|
||||||
|
return "DATETIME";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getInstallationNotificationName(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
return "SILENT";
|
||||||
|
case 2:
|
||||||
|
return "NEED_CONFIRMATION";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFilePath(String fileId, String fileExt, Date fileCreateDate) {
|
||||||
|
String filePath = AppConfig.getInstance().get("file.dir") + File.separator
|
||||||
|
+ sdfYEAR.format(fileCreateDate) + File.separator
|
||||||
|
+ sdfMONTH.format(fileCreateDate) + File.separator
|
||||||
|
+ sdfDATE.format(fileCreateDate) + File.separator
|
||||||
|
+ fileId + "." + fileExt;
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String md5Checksum(byte[] bytes) throws Exception {
|
||||||
|
try {
|
||||||
|
String checksum = DigestUtils.md5Hex(bytes);
|
||||||
|
return checksum;
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
51
src/id/iptek/utms/agent/worker/WorkerFactory.java
Normal file
51
src/id/iptek/utms/agent/worker/WorkerFactory.java
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package id.iptek.utms.agent.worker;
|
||||||
|
|
||||||
|
import id.iptek.utms.agent.AppConfig;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jaka
|
||||||
|
*/
|
||||||
|
public final class WorkerFactory {
|
||||||
|
|
||||||
|
private static WorkerFactory self;
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(WorkerFactory.class);
|
||||||
|
|
||||||
|
private WorkerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Worker> buildWorkers(AppConfig config) throws Exception {
|
||||||
|
List<Worker> workers = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
String[] consumerNames = config.getAll("mqtt.consumers");
|
||||||
|
|
||||||
|
logger.info("Build workers ...");
|
||||||
|
for(String consumerName : consumerNames) {
|
||||||
|
logger.debug("Build worker: '{}'", consumerName);
|
||||||
|
String workerClass = config.get("mqtt.consumer." + consumerName + ".workerclass");
|
||||||
|
Class clazz = Class.forName(workerClass);
|
||||||
|
int _threads = config.getAsInt("mqtt.consumer." + consumerName + ".threads", 1);
|
||||||
|
|
||||||
|
for(int a = 0; a < _threads; a++) {
|
||||||
|
Worker worker = (Worker) clazz.newInstance();
|
||||||
|
worker.init(consumerName, config);
|
||||||
|
workers.add(worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("... done build workers.");
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
return workers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WorkerFactory getInstance() {
|
||||||
|
if(self == null) {
|
||||||
|
self = new WorkerFactory();
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
utms-agent.service
Normal file
15
utms-agent.service
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=UTMS Agent
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=tomcat
|
||||||
|
Group=tomcat
|
||||||
|
WorkingDirectory=/opt/utms-agent
|
||||||
|
ExecStart=/usr/bin/java -jar /opt/utms-agent/utms-agent.jar /opt/utms-agent/conf/mqtt-agents.cfg
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Reference in New Issue
Block a user