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