From 265e33241a806d3c3462f1c0701a8617190be01b Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 10 Mar 2023 14:45:49 +0100 Subject: [PATCH 01/61] version set to 3.6.0-SNAPSHOT --- application/pom.xml | 2 +- common/actor/pom.xml | 2 +- common/cache/pom.xml | 2 +- common/cluster-api/pom.xml | 2 +- common/coap-server/pom.xml | 2 +- common/dao-api/pom.xml | 2 +- common/data/pom.xml | 2 +- common/edge-api/pom.xml | 2 +- common/message/pom.xml | 2 +- common/pom.xml | 2 +- common/queue/pom.xml | 2 +- common/script/pom.xml | 2 +- common/script/remote-js-client/pom.xml | 2 +- common/script/script-api/pom.xml | 2 +- common/stats/pom.xml | 2 +- common/transport/coap/pom.xml | 2 +- common/transport/http/pom.xml | 2 +- common/transport/lwm2m/pom.xml | 2 +- common/transport/mqtt/pom.xml | 2 +- common/transport/pom.xml | 2 +- common/transport/snmp/pom.xml | 2 +- common/transport/transport-api/pom.xml | 2 +- common/util/pom.xml | 2 +- common/version-control/pom.xml | 2 +- dao/pom.xml | 2 +- msa/black-box-tests/pom.xml | 2 +- msa/js-executor/package.json | 2 +- msa/js-executor/pom.xml | 2 +- msa/pom.xml | 2 +- msa/tb-node/pom.xml | 2 +- msa/tb/pom.xml | 2 +- msa/transport/coap/pom.xml | 2 +- msa/transport/http/pom.xml | 2 +- msa/transport/lwm2m/pom.xml | 2 +- msa/transport/mqtt/pom.xml | 2 +- msa/transport/pom.xml | 2 +- msa/transport/snmp/pom.xml | 2 +- msa/vc-executor-docker/pom.xml | 2 +- msa/vc-executor/pom.xml | 2 +- msa/web-ui/package.json | 2 +- msa/web-ui/pom.xml | 2 +- netty-mqtt/pom.xml | 4 ++-- pom.xml | 2 +- rest-client/pom.xml | 2 +- rule-engine/pom.xml | 2 +- rule-engine/rule-engine-api/pom.xml | 2 +- rule-engine/rule-engine-components/pom.xml | 2 +- tools/pom.xml | 2 +- transport/coap/pom.xml | 2 +- transport/http/pom.xml | 2 +- transport/lwm2m/pom.xml | 2 +- transport/mqtt/pom.xml | 2 +- transport/pom.xml | 2 +- transport/snmp/pom.xml | 2 +- ui-ngx/package.json | 2 +- ui-ngx/pom.xml | 2 +- 56 files changed, 57 insertions(+), 57 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index b653465050..d2fc75b1cb 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard application diff --git a/common/actor/pom.xml b/common/actor/pom.xml index 2bc3335ded..2de85be932 100644 --- a/common/actor/pom.xml +++ b/common/actor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/cache/pom.xml b/common/cache/pom.xml index 9c887cd7cd..440860fda6 100644 --- a/common/cache/pom.xml +++ b/common/cache/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/cluster-api/pom.xml b/common/cluster-api/pom.xml index bd45c1c7ca..c9fa6d0894 100644 --- a/common/cluster-api/pom.xml +++ b/common/cluster-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/coap-server/pom.xml b/common/coap-server/pom.xml index a48a0c31bc..420fc4dae6 100644 --- a/common/coap-server/pom.xml +++ b/common/coap-server/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index 71f872b353..029c660500 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/data/pom.xml b/common/data/pom.xml index e50ccd9dd2..f6fd744a02 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/edge-api/pom.xml b/common/edge-api/pom.xml index cf03facf55..60562efbf2 100644 --- a/common/edge-api/pom.xml +++ b/common/edge-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index ac7814bc49..e64d4676ce 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index 812a05abaf..0edd153a3c 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard common diff --git a/common/queue/pom.xml b/common/queue/pom.xml index 200867d022..edd4574bdd 100644 --- a/common/queue/pom.xml +++ b/common/queue/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/script/pom.xml b/common/script/pom.xml index 42593f033c..26f60bd358 100644 --- a/common/script/pom.xml +++ b/common/script/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/script/remote-js-client/pom.xml b/common/script/remote-js-client/pom.xml index 8fbef37bdb..8fa852d977 100644 --- a/common/script/remote-js-client/pom.xml +++ b/common/script/remote-js-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT script org.thingsboard.common.script diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index 24cf7d832d..c4e069f695 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT script org.thingsboard.common.script diff --git a/common/stats/pom.xml b/common/stats/pom.xml index 19243d9b28..0869243e7a 100644 --- a/common/stats/pom.xml +++ b/common/stats/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/coap/pom.xml b/common/transport/coap/pom.xml index 14c105c3b7..2ac15d3e42 100644 --- a/common/transport/coap/pom.xml +++ b/common/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/http/pom.xml b/common/transport/http/pom.xml index b02491768e..8cf3e0efe8 100644 --- a/common/transport/http/pom.xml +++ b/common/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/lwm2m/pom.xml b/common/transport/lwm2m/pom.xml index ddd8f227cf..4433eae2b9 100644 --- a/common/transport/lwm2m/pom.xml +++ b/common/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/mqtt/pom.xml b/common/transport/mqtt/pom.xml index ae0b35e44d..bb4767640c 100644 --- a/common/transport/mqtt/pom.xml +++ b/common/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/pom.xml b/common/transport/pom.xml index 4f319abfad..6879a4924d 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/snmp/pom.xml b/common/transport/snmp/pom.xml index 30d14a4b28..1865f498fa 100644 --- a/common/transport/snmp/pom.xml +++ b/common/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml index 26dde924f7..2e2174e0a9 100644 --- a/common/transport/transport-api/pom.xml +++ b/common/transport/transport-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/util/pom.xml b/common/util/pom.xml index a222724acd..83036d536f 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/common/version-control/pom.xml b/common/version-control/pom.xml index 381f4ed292..a8acdf2be9 100644 --- a/common/version-control/pom.xml +++ b/common/version-control/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index 4fc8a3c08d..4d4dd2a30b 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard dao diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml index ae0b12ead7..12d36272c0 100644 --- a/msa/black-box-tests/pom.xml +++ b/msa/black-box-tests/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/js-executor/package.json b/msa/js-executor/package.json index add59eb610..dc72a2bb22 100644 --- a/msa/js-executor/package.json +++ b/msa/js-executor/package.json @@ -1,7 +1,7 @@ { "name": "thingsboard-js-executor", "private": true, - "version": "3.5.0", + "version": "3.6.0", "description": "ThingsBoard JavaScript Executor Microservice", "main": "server.ts", "bin": "server.js", diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index 05775ef137..0bd7bf4d60 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/pom.xml b/msa/pom.xml index ad40e574ec..e80dc54269 100644 --- a/msa/pom.xml +++ b/msa/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard msa diff --git a/msa/tb-node/pom.xml b/msa/tb-node/pom.xml index 8779dd6dd1..8437cc35c3 100644 --- a/msa/tb-node/pom.xml +++ b/msa/tb-node/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index 4b8439e0e9..7c4af55497 100644 --- a/msa/tb/pom.xml +++ b/msa/tb/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/coap/pom.xml b/msa/transport/coap/pom.xml index 6a4ce4dd69..386b91ea76 100644 --- a/msa/transport/coap/pom.xml +++ b/msa/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/http/pom.xml b/msa/transport/http/pom.xml index 37fe6efc91..344219a660 100644 --- a/msa/transport/http/pom.xml +++ b/msa/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/lwm2m/pom.xml b/msa/transport/lwm2m/pom.xml index 77f5a1e2fd..8dfef617cd 100644 --- a/msa/transport/lwm2m/pom.xml +++ b/msa/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/mqtt/pom.xml b/msa/transport/mqtt/pom.xml index 962025a917..e1d740c877 100644 --- a/msa/transport/mqtt/pom.xml +++ b/msa/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/pom.xml b/msa/transport/pom.xml index 8f6acf590e..e0bd5a9457 100644 --- a/msa/transport/pom.xml +++ b/msa/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/snmp/pom.xml b/msa/transport/snmp/pom.xml index 6353419382..b6a4e15b04 100644 --- a/msa/transport/snmp/pom.xml +++ b/msa/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.msa transport - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT org.thingsboard.msa.transport diff --git a/msa/vc-executor-docker/pom.xml b/msa/vc-executor-docker/pom.xml index b076cf14cb..9b6fc493cd 100644 --- a/msa/vc-executor-docker/pom.xml +++ b/msa/vc-executor-docker/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/vc-executor/pom.xml b/msa/vc-executor/pom.xml index 37ba0da564..9bd2befa90 100644 --- a/msa/vc-executor/pom.xml +++ b/msa/vc-executor/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/web-ui/package.json b/msa/web-ui/package.json index 18cc80481f..3338d2ae76 100644 --- a/msa/web-ui/package.json +++ b/msa/web-ui/package.json @@ -1,7 +1,7 @@ { "name": "thingsboard-web-ui", "private": true, - "version": "3.5.0", + "version": "3.6.0", "description": "ThingsBoard Web UI Microservice", "main": "server.ts", "bin": "server.js", diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index fd73ce686c..e9500cf5e0 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT msa org.thingsboard.msa diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index b15e8235b4..0ae03f3980 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -19,11 +19,11 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard netty-mqtt - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT jar Netty MQTT Client diff --git a/pom.xml b/pom.xml index 49f30df835..b70be187ed 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT pom Thingsboard diff --git a/rest-client/pom.xml b/rest-client/pom.xml index cb85c2134e..10a8cd311b 100644 --- a/rest-client/pom.xml +++ b/rest-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard rest-client diff --git a/rule-engine/pom.xml b/rule-engine/pom.xml index e005b5a543..fe8cb3fab5 100644 --- a/rule-engine/pom.xml +++ b/rule-engine/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard rule-engine diff --git a/rule-engine/rule-engine-api/pom.xml b/rule-engine/rule-engine-api/pom.xml index 5a200fc14a..47d13e5658 100644 --- a/rule-engine/rule-engine-api/pom.xml +++ b/rule-engine/rule-engine-api/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index e85f0094b5..34c6e315f7 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/tools/pom.xml b/tools/pom.xml index ae6eb95a15..c0b74bb0a9 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard tools diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 5cc87640d7..3b1e0a9e62 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index d685b8d1ab..3d4b806d03 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/lwm2m/pom.xml b/transport/lwm2m/pom.xml index dcdfaac0c8..efe76111f3 100644 --- a/transport/lwm2m/pom.xml +++ b/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index 11a73d7e51..75daa483a1 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/pom.xml b/transport/pom.xml index 3e14199411..203ea6cbbb 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard transport diff --git a/transport/snmp/pom.xml b/transport/snmp/pom.xml index 8ba98a9924..c04e7d1f1f 100644 --- a/transport/snmp/pom.xml +++ b/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT transport diff --git a/ui-ngx/package.json b/ui-ngx/package.json index a8abb6fbeb..a1564630f3 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -1,6 +1,6 @@ { "name": "thingsboard", - "version": "3.5.0", + "version": "3.6.0", "scripts": { "ng": "ng", "start": "node --max_old_space_size=8048 ./node_modules/@angular/cli/bin/ng serve --configuration development --host 0.0.0.0 --open", diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index 01d0ece37d..d6dc28490f 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard org.thingsboard From 98ea8298c3a4a73f238e783e7b2abf1e9c42aa0c Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 21 Apr 2023 20:03:25 +0200 Subject: [PATCH 02/61] set 3.6 version for monitoring --- monitoring/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monitoring/pom.xml b/monitoring/pom.xml index e044635e98..399e34092d 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -21,7 +21,7 @@ 4.0.0 org.thingsboard - 3.5.0-SNAPSHOT + 3.6.0-SNAPSHOT thingsboard From 40d6e6713141ee6273bf2f91bfce2c824b57f18a Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 2 May 2023 00:46:34 +0200 Subject: [PATCH 03/61] migrate to java 17 --- .../sync/vc/VersionControlTaskRedisCache.java | 4 +- .../AutoCommitSettingsRedisCache.java | 4 +- .../RepositorySettingsRedisCache.java | 4 +- .../server/controller/AbstractWebTest.java | 14 ++++- ...alizer.java => TbJavaRedisSerializer.java} | 8 +-- .../server/cache/device/DeviceRedisCache.java | 4 +- .../UsersSessionInvalidationRedisCache.java | 4 +- common/data/pom.xml | 4 -- .../server/common/data/FSTUtils.java | 35 ------------ .../server/common/data/JavaSerDesUtil.java | 57 +++++++++++++++++++ .../bootstrap/LwM2MServerSecurityConfig.java | 4 +- .../NoSecLwM2MBootstrapServerCredential.java | 3 + .../msg/TbMsgProcessingStackItemTest.java | 6 +- ...a => JavaDataDecodingEncodingService.java} | 20 ++----- common/script/script-api/pom.xml | 4 ++ .../store/TbLwM2MDtlsSessionRedisStore.java | 8 +-- .../store/TbLwM2mRedisSecurityStore.java | 21 +++---- .../dao/asset/AssetProfileRedisCache.java | 4 +- .../server/dao/asset/AssetRedisCache.java | 4 +- .../dashboard/DashboardTitlesRedisCache.java | 4 +- .../device/DeviceCredentialsRedisCache.java | 4 +- .../dao/device/DeviceProfileRedisCache.java | 4 +- .../server/dao/edge/EdgeRedisCache.java | 4 +- .../entity/count/EntityCountRedisCache.java | 4 +- .../dao/entityview/EntityViewRedisCache.java | 4 +- .../server/dao/ota/OtaPackageRedisCache.java | 4 +- .../dao/relation/RelationRedisCache.java | 4 +- .../dao/tenant/TenantExistsRedisCache.java | 4 +- .../dao/tenant/TenantProfileRedisCache.java | 4 +- .../server/dao/tenant/TenantRedisCache.java | 4 +- .../dao/user/UserSettingsRedisCache.java | 5 +- pom.xml | 17 +++--- 32 files changed, 148 insertions(+), 130 deletions(-) rename common/cache/src/main/java/org/thingsboard/server/cache/{TbFSTRedisSerializer.java => TbJavaRedisSerializer.java} (80%) delete mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/FSTUtils.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/JavaSerDesUtil.java rename common/queue/src/main/java/org/thingsboard/server/queue/util/{ProtoWithFSTService.java => JavaDataDecodingEncodingService.java} (61%) diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlTaskRedisCache.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlTaskRedisCache.java index 5fccbb3cbb..a849577d0c 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlTaskRedisCache.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/VersionControlTaskRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import java.util.UUID; @@ -31,6 +31,6 @@ import java.util.UUID; public class VersionControlTaskRedisCache extends RedisTbTransactionalCache { public VersionControlTaskRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.VERSION_CONTROL_TASK_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.VERSION_CONTROL_TASK_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/autocommit/AutoCommitSettingsRedisCache.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/autocommit/AutoCommitSettingsRedisCache.java index b3c47cf2a7..be9bbfa443 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/autocommit/AutoCommitSettingsRedisCache.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/autocommit/AutoCommitSettingsRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.sync.vc.AutoCommitSettings; @@ -31,6 +31,6 @@ import org.thingsboard.server.common.data.sync.vc.AutoCommitSettings; public class AutoCommitSettingsRedisCache extends RedisTbTransactionalCache { public AutoCommitSettingsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.AUTO_COMMIT_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.AUTO_COMMIT_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/RepositorySettingsRedisCache.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/RepositorySettingsRedisCache.java index 27fba3459c..1e71a51d00 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/RepositorySettingsRedisCache.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/repository/RepositorySettingsRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; @@ -31,6 +31,6 @@ import org.thingsboard.server.common.data.sync.vc.RepositorySettings; public class RepositorySettingsRedisCache extends RedisTbTransactionalCache { public RepositorySettingsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.REPOSITORY_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.REPOSITORY_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index c7580867e0..d128c8ed91 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -116,6 +116,8 @@ import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRequest; import org.thingsboard.server.service.security.auth.rest.LoginRequest; import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.sql.SQLException; @@ -927,9 +929,15 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected static void setStaticFinalFieldValue(Class targetCls, String fieldName, Object value) throws Exception { Field field = targetCls.getDeclaredField(fieldName); field.setAccessible(true); - Field modifiers = Field.class.getDeclaredField("modifiers"); - modifiers.setAccessible(true); - modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); + // Get the VarHandle for the 'modifiers' field in the Field class + MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup()); + VarHandle modifiersHandle = lookup.findVarHandle(Field.class, "modifiers", int.class); + + // Remove the final modifier from the field + int currentModifiers = field.getModifiers(); + modifiersHandle.set(field, currentModifiers & ~Modifier.FINAL); + + // Set the new value field.set(null, value); } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/TbFSTRedisSerializer.java b/common/cache/src/main/java/org/thingsboard/server/cache/TbJavaRedisSerializer.java similarity index 80% rename from common/cache/src/main/java/org/thingsboard/server/cache/TbFSTRedisSerializer.java rename to common/cache/src/main/java/org/thingsboard/server/cache/TbJavaRedisSerializer.java index 3d8bf66542..9a5e2fa078 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/TbFSTRedisSerializer.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/TbJavaRedisSerializer.java @@ -16,17 +16,17 @@ package org.thingsboard.server.cache; import org.springframework.data.redis.serializer.SerializationException; -import org.thingsboard.server.common.data.FSTUtils; +import org.thingsboard.server.common.data.JavaSerDesUtil; -public class TbFSTRedisSerializer implements TbRedisSerializer { +public class TbJavaRedisSerializer implements TbRedisSerializer { @Override public byte[] serialize(V value) throws SerializationException { - return FSTUtils.encode(value); + return JavaSerDesUtil.encode(value); } @Override public V deserialize(K key, byte[] bytes) throws SerializationException { - return FSTUtils.decode(bytes); + return JavaSerDesUtil.decode(bytes); } } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceRedisCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceRedisCache.java index 591555a3a1..a7b7a047fb 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceRedisCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/device/DeviceRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.Device; @@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.Device; public class DeviceRedisCache extends RedisTbTransactionalCache { public DeviceRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.DEVICE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.DEVICE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersSessionInvalidationRedisCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersSessionInvalidationRedisCache.java index 83360fb8af..38a9104679 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersSessionInvalidationRedisCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/usersUpdateTime/UsersSessionInvalidationRedisCache.java @@ -22,7 +22,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @@ -31,6 +31,6 @@ public class UsersSessionInvalidationRedisCache extends RedisTbTransactionalCach @Autowired public UsersSessionInvalidationRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.USERS_SESSION_INVALIDATION_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.USERS_SESSION_INVALIDATION_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/common/data/pom.xml b/common/data/pom.xml index d81203cd4d..c1fa964caa 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -108,10 +108,6 @@ io.swagger swagger-annotations - - de.ruedigermoeller - fst - com.google.protobuf protobuf-java-util diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/FSTUtils.java b/common/data/src/main/java/org/thingsboard/server/common/data/FSTUtils.java deleted file mode 100644 index 83447d7a6b..0000000000 --- a/common/data/src/main/java/org/thingsboard/server/common/data/FSTUtils.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.common.data; - -import lombok.extern.slf4j.Slf4j; -import org.nustaq.serialization.FSTConfiguration; - -@Slf4j -public class FSTUtils { - - public static final FSTConfiguration CONFIG = FSTConfiguration.createDefaultConfiguration(); - - @SuppressWarnings("unchecked") - public static T decode(byte[] byteArray) { - return byteArray != null && byteArray.length > 0 ? (T) CONFIG.asObject(byteArray) : null; - } - - public static byte[] encode(T msq) { - return CONFIG.asByteArray(msq); - } - -} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/JavaSerDesUtil.java b/common/data/src/main/java/org/thingsboard/server/common/data/JavaSerDesUtil.java new file mode 100644 index 0000000000..636fda5fc5 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/JavaSerDesUtil.java @@ -0,0 +1,57 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data; + +import lombok.extern.slf4j.Slf4j; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +@Slf4j +public class JavaSerDesUtil { + + @SuppressWarnings("unchecked") + public static T decode(byte[] byteArray) { + if (byteArray == null || byteArray.length == 0) { + return null; + } + InputStream is = new ByteArrayInputStream(byteArray); + try (ObjectInputStream ois = new ObjectInputStream(is)) { + return (T) ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + log.error("Error during deserialization message, [{}]", e.getMessage()); + return null; + } + } + + public static byte[] encode(T msq) { + if (msq == null) { + return null; + } + ByteArrayOutputStream boas = new ByteArrayOutputStream(); + try (ObjectOutputStream ois = new ObjectOutputStream(boas)) { + ois.writeObject(msq); + return boas.toByteArray(); + } catch (IOException e) { + log.error("Error during serialization message, [{}]", e.getMessage()); + throw new RuntimeException(e); + } + } +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java index eb052da126..4405115905 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java @@ -19,9 +19,11 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.io.Serializable; + @ApiModel @Data -public class LwM2MServerSecurityConfig { +public class LwM2MServerSecurityConfig implements Serializable { @ApiModelProperty(position = 1, value = "Server short Id. Used as link to associate server Object Instance. This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client. " + "This Resource MUST be set when the Bootstrap-Server Resource has a value of 'false'. " + diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/NoSecLwM2MBootstrapServerCredential.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/NoSecLwM2MBootstrapServerCredential.java index 6bd7b7c427..43b9a0763e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/NoSecLwM2MBootstrapServerCredential.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/NoSecLwM2MBootstrapServerCredential.java @@ -17,8 +17,11 @@ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; +import java.io.Serial; + public class NoSecLwM2MBootstrapServerCredential extends AbstractLwM2MBootstrapServerCredential { + @Serial private static final long serialVersionUID = 5540417758424747066L; @Override diff --git a/common/message/src/test/java/org/thingsboard/server/common/msg/TbMsgProcessingStackItemTest.java b/common/message/src/test/java/org/thingsboard/server/common/msg/TbMsgProcessingStackItemTest.java index 1f3fa2050a..86d061b57c 100644 --- a/common/message/src/test/java/org/thingsboard/server/common/msg/TbMsgProcessingStackItemTest.java +++ b/common/message/src/test/java/org/thingsboard/server/common/msg/TbMsgProcessingStackItemTest.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.msg; import org.junit.jupiter.api.Test; -import org.thingsboard.server.common.data.FSTUtils; +import org.thingsboard.server.common.data.JavaSerDesUtil; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; @@ -29,8 +29,8 @@ class TbMsgProcessingStackItemTest { @Test void testSerialization() { TbMsgProcessingStackItem item = new TbMsgProcessingStackItem(new RuleChainId(UUID.randomUUID()), new RuleNodeId(UUID.randomUUID())); - byte[] bytes = FSTUtils.encode(item); - TbMsgProcessingStackItem itemDecoded = FSTUtils.decode(bytes); + byte[] bytes = JavaSerDesUtil.encode(item); + TbMsgProcessingStackItem itemDecoded = JavaSerDesUtil.decode(bytes); assertThat(item).isEqualTo(itemDecoded); } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/util/ProtoWithFSTService.java b/common/queue/src/main/java/org/thingsboard/server/queue/util/JavaDataDecodingEncodingService.java similarity index 61% rename from common/queue/src/main/java/org/thingsboard/server/queue/util/ProtoWithFSTService.java rename to common/queue/src/main/java/org/thingsboard/server/queue/util/JavaDataDecodingEncodingService.java index b0d0b182e9..493d6f31f2 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/util/ProtoWithFSTService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/util/JavaDataDecodingEncodingService.java @@ -16,33 +16,21 @@ package org.thingsboard.server.queue.util; import lombok.extern.slf4j.Slf4j; -import org.nustaq.serialization.FSTConfiguration; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.FSTUtils; +import org.thingsboard.server.common.data.JavaSerDesUtil; import java.util.Optional; @Slf4j @Service -public class ProtoWithFSTService implements DataDecodingEncodingService { - - public static final FSTConfiguration CONFIG = FSTConfiguration.createDefaultConfiguration(); - +public class JavaDataDecodingEncodingService implements DataDecodingEncodingService { @Override public Optional decode(byte[] byteArray) { - try { - return Optional.ofNullable(FSTUtils.decode(byteArray)); - } catch (IllegalArgumentException e) { - log.error("Error during deserialization message, [{}]", e.getMessage()); - return Optional.empty(); - } + return Optional.ofNullable(JavaSerDesUtil.decode(byteArray)); } - @Override public byte[] encode(T msq) { - return FSTUtils.encode(msq); + return JavaSerDesUtil.encode(msq); } - - } diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index 24cf7d832d..b5d652f0d9 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -52,6 +52,10 @@ org.javadelight delight-nashorn-sandbox + + org.openjdk.nashorn + nashorn-core + com.google.code.gson gson diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java index a1ffad9946..737ce96c41 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MDtlsSessionRedisStore.java @@ -15,25 +15,23 @@ */ package org.thingsboard.server.transport.lwm2m.server.store; -import org.nustaq.serialization.FSTConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.thingsboard.server.common.data.JavaSerDesUtil; import org.thingsboard.server.transport.lwm2m.secure.TbX509DtlsSessionInfo; public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { private static final String SESSION_EP = "SESSION#EP#"; private final RedisConnectionFactory connectionFactory; - private final FSTConfiguration serializer; public TbLwM2MDtlsSessionRedisStore(RedisConnectionFactory redisConnectionFactory) { this.connectionFactory = redisConnectionFactory; - this.serializer = FSTConfiguration.createDefaultConfiguration(); } @Override public void put(String endpoint, TbX509DtlsSessionInfo msg) { try (var c = connectionFactory.getConnection()) { - var serializedMsg = serializer.asByteArray(msg); + var serializedMsg = JavaSerDesUtil.encode(msg); if (serializedMsg != null) { c.set(getKey(endpoint), serializedMsg); } else { @@ -47,7 +45,7 @@ public class TbLwM2MDtlsSessionRedisStore implements TbLwM2MDtlsSessionStore { try (var c = connectionFactory.getConnection()) { var data = c.get(getKey(endpoint)); if (data != null) { - return (TbX509DtlsSessionInfo) serializer.asObject(data); + return JavaSerDesUtil.decode(data); } else { return null; } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java index f6539556e5..87e92c8cca 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java @@ -18,9 +18,9 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.eclipse.leshan.core.SecurityMode; import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; import org.eclipse.leshan.server.security.SecurityInfo; -import org.nustaq.serialization.FSTConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.integration.redis.util.RedisLockRegistry; +import org.thingsboard.server.common.data.JavaSerDesUtil; import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import java.util.concurrent.locks.Lock; @@ -31,13 +31,11 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { private static final String PSKID_SEC = "PSKID#SEC"; private final RedisConnectionFactory connectionFactory; - private final FSTConfiguration serializer; private final RedisLockRegistry redisLock; public TbLwM2mRedisSecurityStore(RedisConnectionFactory connectionFactory) { this.connectionFactory = connectionFactory; redisLock = new RedisLockRegistry(connectionFactory, "Security"); - serializer = FSTConfiguration.createDefaultConfiguration(); } @Override @@ -50,12 +48,11 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { if (data == null || data.length == 0) { return null; } else { - if (SecurityMode.NO_SEC.equals(((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityMode())) { + if (SecurityMode.NO_SEC.equals(((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(data)).getSecurityMode())) { return SecurityInfo.newPreSharedKeyInfo(SecurityMode.NO_SEC.toString(), SecurityMode.NO_SEC.toString(), SecurityMode.NO_SEC.toString().getBytes()); - } - else { - return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo(); + } else { + return ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(data)).getSecurityInfo(); } } } finally { @@ -79,7 +76,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { if (data == null || data.length == 0) { return null; } else { - return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo(); + return ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(data)).getSecurityInfo(); } } } finally { @@ -92,7 +89,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { @Override public void put(TbLwM2MSecurityInfo tbSecurityInfo) throws NonUniqueSecurityInfoException { SecurityInfo info = tbSecurityInfo.getSecurityInfo(); - byte[] tbSecurityInfoSerialized = serializer.asByteArray(tbSecurityInfo); + byte[] tbSecurityInfoSerialized = JavaSerDesUtil.encode(tbSecurityInfo); Lock lock = null; try (var connection = connectionFactory.getConnection()) { lock = redisLock.obtain(tbSecurityInfo.getEndpoint()); @@ -110,7 +107,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { byte[] previousData = connection.getSet((SEC_EP + tbSecurityInfo.getEndpoint()).getBytes(), tbSecurityInfoSerialized); if (previousData != null && info != null) { - String previousIdentity = ((TbLwM2MSecurityInfo) serializer.asObject(previousData)).getSecurityInfo().getIdentity(); + String previousIdentity = ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(previousData)).getSecurityInfo().getIdentity(); if (previousIdentity != null && !previousIdentity.equals(info.getIdentity())) { connection.hDel(PSKID_SEC.getBytes(), previousIdentity.getBytes()); } @@ -130,7 +127,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { lock.lock(); byte[] data = connection.get((SEC_EP + endpoint).getBytes()); if (data != null && data.length > 0) { - return (TbLwM2MSecurityInfo) serializer.asObject(data); + return JavaSerDesUtil.decode(data); } else { return null; } @@ -149,7 +146,7 @@ public class TbLwM2mRedisSecurityStore implements TbEditableSecurityStore { lock.lock(); byte[] data = connection.get((SEC_EP + endpoint).getBytes()); if (data != null && data.length > 0) { - SecurityInfo info = ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo(); + SecurityInfo info = ((TbLwM2MSecurityInfo) JavaSerDesUtil.decode(data)).getSecurityInfo(); if (info != null && info.getIdentity() != null) { connection.hDel(PSKID_SEC.getBytes(), info.getIdentity().getBytes()); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileRedisCache.java index 25f919e881..1e4463cbea 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetProfileRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.asset.AssetProfile; @@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.asset.AssetProfile; public class AssetProfileRedisCache extends RedisTbTransactionalCache { public AssetProfileRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.ASSET_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.ASSET_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetRedisCache.java index c0fb23c5a4..b423edae43 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetRedisCache.java @@ -23,13 +23,13 @@ import org.thingsboard.server.cache.TBRedisCacheConfiguration; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.cache.RedisTbTransactionalCache; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @Service("AssetCache") public class AssetRedisCache extends RedisTbTransactionalCache { public AssetRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.ASSET_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.ASSET_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardTitlesRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardTitlesRedisCache.java index 990a175b71..ef59fb6f6d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardTitlesRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardTitlesRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.id.DashboardId; @@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.id.DashboardId; public class DashboardTitlesRedisCache extends RedisTbTransactionalCache { public DashboardTitlesRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.DASHBOARD_TITLES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.DASHBOARD_TITLES_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsRedisCache.java index 86a1086207..2c33e53c10 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceCredentialsRedisCache.java @@ -20,7 +20,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.cache.RedisTbTransactionalCache; @@ -30,6 +30,6 @@ import org.thingsboard.server.cache.RedisTbTransactionalCache; public class DeviceCredentialsRedisCache extends RedisTbTransactionalCache { public DeviceCredentialsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.DEVICE_CREDENTIALS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.DEVICE_CREDENTIALS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java index 726f19b74e..86628b4466 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileRedisCache.java @@ -20,7 +20,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.cache.RedisTbTransactionalCache; @@ -30,6 +30,6 @@ import org.thingsboard.server.cache.RedisTbTransactionalCache; public class DeviceProfileRedisCache extends RedisTbTransactionalCache { public DeviceProfileRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.DEVICE_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.DEVICE_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java index cd788f2695..2c6f4a80ad 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeRedisCache.java @@ -23,13 +23,13 @@ import org.thingsboard.server.cache.TBRedisCacheConfiguration; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.cache.RedisTbTransactionalCache; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @Service("EdgeCache") public class EdgeRedisCache extends RedisTbTransactionalCache { public EdgeRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.EDGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.EDGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/count/EntityCountRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/entity/count/EntityCountRedisCache.java index af431f3085..791921bbba 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/count/EntityCountRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/count/EntityCountRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.dao.entity.EntityCountCacheKey; @@ -30,6 +30,6 @@ import org.thingsboard.server.dao.entity.EntityCountCacheKey; public class EntityCountRedisCache extends RedisTbTransactionalCache { public EntityCountRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.ENTITY_COUNT_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.ENTITY_COUNT_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewRedisCache.java index 9343b4a205..9234ea57d5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewRedisCache.java @@ -22,13 +22,13 @@ import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.TBRedisCacheConfiguration; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.cache.RedisTbTransactionalCache; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @Service("EntityViewCache") public class EntityViewRedisCache extends RedisTbTransactionalCache { public EntityViewRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.ENTITY_VIEW_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.ENTITY_VIEW_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageRedisCache.java index 69ff998712..11c13eabca 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/ota/OtaPackageRedisCache.java @@ -20,7 +20,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.cache.RedisTbTransactionalCache; @@ -30,6 +30,6 @@ import org.thingsboard.server.cache.RedisTbTransactionalCache; public class OtaPackageRedisCache extends RedisTbTransactionalCache { public OtaPackageRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.OTA_PACKAGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.OTA_PACKAGE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationRedisCache.java index 35b52d7fe1..0154b1d9e1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationRedisCache.java @@ -20,7 +20,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.cache.RedisTbTransactionalCache; @@ -29,6 +29,6 @@ import org.thingsboard.server.cache.RedisTbTransactionalCache; public class RelationRedisCache extends RedisTbTransactionalCache { public RelationRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.RELATIONS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.RELATIONS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantExistsRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantExistsRedisCache.java index 9cd5ba18cb..3c223cbd36 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantExistsRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantExistsRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.id.TenantId; @@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.id.TenantId; public class TenantExistsRedisCache extends RedisTbTransactionalCache { public TenantExistsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.TENANTS_EXIST_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.TENANTS_EXIST_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileRedisCache.java index 302006fa00..4cf47f9a62 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantProfileRedisCache.java @@ -23,13 +23,13 @@ import org.thingsboard.server.cache.TBRedisCacheConfiguration; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.cache.RedisTbTransactionalCache; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; @ConditionalOnProperty(prefix = "cache", value = "type", havingValue = "redis") @Service("TenantProfileCache") public class TenantProfileRedisCache extends RedisTbTransactionalCache { public TenantProfileRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.TENANT_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.TENANT_PROFILE_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantRedisCache.java index 29ebcd9767..e9b225866b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; @@ -31,6 +31,6 @@ import org.thingsboard.server.common.data.id.TenantId; public class TenantRedisCache extends RedisTbTransactionalCache { public TenantRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.TENANTS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.TENANTS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserSettingsRedisCache.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserSettingsRedisCache.java index de321f3eb9..384336006e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/UserSettingsRedisCache.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserSettingsRedisCache.java @@ -21,9 +21,8 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; -import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.settings.UserSettings; import org.thingsboard.server.common.data.settings.UserSettingsCompositeKey; @@ -32,6 +31,6 @@ import org.thingsboard.server.common.data.settings.UserSettingsCompositeKey; public class UserSettingsRedisCache extends RedisTbTransactionalCache { public UserSettingsRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.USER_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.USER_SETTINGS_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } diff --git a/pom.xml b/pom.xml index f78a4826bc..6e6500c742 100755 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ 3.21.9 1.42.1 1.0.6 - 1.18.18 + 1.18.26 1.2.4 1.2.5 4.1.91.Final @@ -100,12 +100,12 @@ 5.0.2 0.2.1 + 15.4 3.2.0 4.1.1 - 2.57 2.7.7 2.0 1.11.747 @@ -607,7 +607,7 @@ maven-compiler-plugin 3.8.1 - 11 + 17 -Xlint:deprecation -Xlint:removal @@ -664,6 +664,7 @@ --illegal-access=permit -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=20 + --add-opens java.base/java.lang.reflect=ALL-UNNAMED @@ -1797,11 +1798,6 @@ bucket4j-core ${bucket4j.version} - - de.ruedigermoeller - fst - ${fst.version} - org.locationtech.spatial4j spatial4j @@ -2007,6 +2003,11 @@ oshi-core ${oshi.version} + + org.openjdk.nashorn + nashorn-core + ${nashorn-core.version} + From 184900761059a96a55776ac76b5952b3e4e32dd4 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 19 May 2023 19:08:03 +0200 Subject: [PATCH 04/61] msa and packaging java 17 support --- msa/monitoring/docker/Dockerfile | 2 +- msa/tb-node/docker/Dockerfile | 4 ++-- msa/tb/docker-cassandra/Dockerfile | 2 +- msa/tb/docker-postgres/Dockerfile | 2 +- msa/transport/coap/docker/Dockerfile | 2 +- msa/transport/http/docker/Dockerfile | 2 +- msa/transport/lwm2m/docker/Dockerfile | 2 +- msa/transport/mqtt/docker/Dockerfile | 2 +- msa/transport/snmp/docker/Dockerfile | 2 +- msa/vc-executor-docker/docker/Dockerfile | 2 +- packaging/java/build.gradle | 4 ++-- packaging/java/scripts/windows/install.bat | 6 +++--- pom.xml | 4 ++-- 13 files changed, 18 insertions(+), 18 deletions(-) diff --git a/msa/monitoring/docker/Dockerfile b/msa/monitoring/docker/Dockerfile index 5da050eb91..14c6246280 100644 --- a/msa/monitoring/docker/Dockerfile +++ b/msa/monitoring/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-monitoring.sh ${pkg.name}.deb /tmp/ diff --git a/msa/tb-node/docker/Dockerfile b/msa/tb-node/docker/Dockerfile index 68e428992a..2c8af18f9a 100644 --- a/msa/tb-node/docker/Dockerfile +++ b/msa/tb-node/docker/Dockerfile @@ -14,11 +14,11 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-node.sh ${pkg.name}.deb /tmp/ -RUN echo 'networkaddress.cache.ttl=60' >> /etc/java-11-openjdk/security/java.security \ +RUN echo 'networkaddress.cache.ttl=60' >> /etc/java-17-openjdk/security/java.security \ && chmod a+x /tmp/*.sh \ && mv /tmp/start-tb-node.sh /usr/bin && \ (yes | dpkg -i /tmp/${pkg.name}.deb) && \ diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile index 2f23aec399..f871d57ff8 100644 --- a/msa/tb/docker-cassandra/Dockerfile +++ b/msa/tb/docker-cassandra/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim ENV PG_MAJOR=12 diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile index 1c25624adf..2520bee62b 100644 --- a/msa/tb/docker-postgres/Dockerfile +++ b/msa/tb/docker-postgres/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim ENV PG_MAJOR 12 diff --git a/msa/transport/coap/docker/Dockerfile b/msa/transport/coap/docker/Dockerfile index 1786e93cb2..526a8620a8 100644 --- a/msa/transport/coap/docker/Dockerfile +++ b/msa/transport/coap/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-coap-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/http/docker/Dockerfile b/msa/transport/http/docker/Dockerfile index 0ba4f713b0..399df84000 100644 --- a/msa/transport/http/docker/Dockerfile +++ b/msa/transport/http/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-http-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/lwm2m/docker/Dockerfile b/msa/transport/lwm2m/docker/Dockerfile index c9270dd4f3..d17f368c8f 100644 --- a/msa/transport/lwm2m/docker/Dockerfile +++ b/msa/transport/lwm2m/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-lwm2m-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/mqtt/docker/Dockerfile b/msa/transport/mqtt/docker/Dockerfile index 2037d629bb..769164b86e 100644 --- a/msa/transport/mqtt/docker/Dockerfile +++ b/msa/transport/mqtt/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-mqtt-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/snmp/docker/Dockerfile b/msa/transport/snmp/docker/Dockerfile index 9edb97fbc4..2835c56bc7 100644 --- a/msa/transport/snmp/docker/Dockerfile +++ b/msa/transport/snmp/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-snmp-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/vc-executor-docker/docker/Dockerfile b/msa/vc-executor-docker/docker/Dockerfile index 653a5f2d35..70a3d3e18f 100644 --- a/msa/vc-executor-docker/docker/Dockerfile +++ b/msa/vc-executor-docker/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11:bullseye-slim +FROM thingsboard/openjdk17:bullseye-slim COPY start-tb-vc-executor.sh ${pkg.name}.deb /tmp/ diff --git a/packaging/java/build.gradle b/packaging/java/build.gradle index d4aa399d70..86dc908426 100644 --- a/packaging/java/build.gradle +++ b/packaging/java/build.gradle @@ -92,7 +92,7 @@ buildRpm { archiveVersion = projectVersion.replace('-', '') archiveFileName = "${pkgName}.rpm" - requires("java-11") + requires("java-17") from("${buildDir}/conf") { include "${pkgName}.conf" @@ -131,7 +131,7 @@ buildDeb { archiveFileName = "${pkgName}.deb" - requires("openjdk-11-jre").or("java11-runtime").or("oracle-java11-installer").or("openjdk-11-jre-headless") + requires("openjdk-17-jre").or("java17-runtime").or("oracle-java17-installer").or("openjdk-17-jre-headless") from("${buildDir}/conf") { include "${pkgName}.conf" diff --git a/packaging/java/scripts/windows/install.bat b/packaging/java/scripts/windows/install.bat index 6f168c76d8..5f71149c83 100644 --- a/packaging/java/scripts/windows/install.bat +++ b/packaging/java/scripts/windows/install.bat @@ -11,7 +11,7 @@ if %jver% NEQ 110 GOTO JAVA_NOT_INSTALLED :JAVA_INSTALLED -@ECHO Java 11 found! +@ECHO Java 17 found! @ECHO Installing thingsboard ... SET loadDemo=false @@ -50,8 +50,8 @@ POPD GOTO END :JAVA_NOT_INSTALLED -@ECHO Java 11 is not installed. Only Java 11 is supported -@ECHO Please go to https://adoptopenjdk.net/index.html and install Java 11. Then retry installation. +@ECHO Java 17 is not installed. Only Java 17 is supported +@ECHO Please go to https://adoptopenjdk.net/index.html and install Java 17. Then retry installation. PAUSE GOTO END diff --git a/pom.xml b/pom.xml index 825138a8dd..4d456b8f4e 100755 --- a/pom.xml +++ b/pom.xml @@ -605,7 +605,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.11.0 17 @@ -650,7 +650,7 @@ org.thingsboard gradle-maven-plugin - 1.0.11 + 1.0.12 com.github.eirslett From 3caae012d65b1cbf0ec98a3baaac8de947951049 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 19 May 2023 19:39:45 +0200 Subject: [PATCH 05/61] minor improvements --- common/util/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/util/pom.xml b/common/util/pom.xml index df09e302ba..14ae1748b2 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -92,6 +92,10 @@ com.github.oshi oshi-core + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + From 2a1259570bc06f63ec008d2a99c1f1434d78a34d Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 29 May 2023 13:43:10 +0300 Subject: [PATCH 06/61] Temporary version set to 3.5.2-SNAPSHOT to merge --- application/pom.xml | 2 +- common/actor/pom.xml | 2 +- common/cache/pom.xml | 2 +- common/cluster-api/pom.xml | 2 +- common/coap-server/pom.xml | 2 +- common/dao-api/pom.xml | 2 +- common/data/pom.xml | 2 +- common/edge-api/pom.xml | 2 +- common/message/pom.xml | 2 +- common/pom.xml | 2 +- common/queue/pom.xml | 2 +- common/script/pom.xml | 2 +- common/script/remote-js-client/pom.xml | 2 +- common/script/script-api/pom.xml | 2 +- common/stats/pom.xml | 2 +- common/transport/coap/pom.xml | 2 +- common/transport/http/pom.xml | 2 +- common/transport/lwm2m/pom.xml | 2 +- common/transport/mqtt/pom.xml | 2 +- common/transport/pom.xml | 2 +- common/transport/snmp/pom.xml | 2 +- common/transport/transport-api/pom.xml | 2 +- common/util/pom.xml | 2 +- common/version-control/pom.xml | 2 +- dao/pom.xml | 2 +- monitoring/pom.xml | 2 +- msa/black-box-tests/pom.xml | 2 +- msa/js-executor/pom.xml | 2 +- msa/monitoring/pom.xml | 2 +- msa/pom.xml | 2 +- msa/tb-node/pom.xml | 2 +- msa/tb/pom.xml | 2 +- msa/transport/coap/pom.xml | 2 +- msa/transport/http/pom.xml | 2 +- msa/transport/lwm2m/pom.xml | 2 +- msa/transport/mqtt/pom.xml | 2 +- msa/transport/pom.xml | 2 +- msa/transport/snmp/pom.xml | 2 +- msa/vc-executor-docker/pom.xml | 2 +- msa/vc-executor/pom.xml | 2 +- msa/web-ui/pom.xml | 2 +- netty-mqtt/pom.xml | 4 ++-- pom.xml | 2 +- rest-client/pom.xml | 2 +- rule-engine/pom.xml | 2 +- rule-engine/rule-engine-api/pom.xml | 2 +- rule-engine/rule-engine-components/pom.xml | 2 +- tools/pom.xml | 2 +- transport/coap/pom.xml | 2 +- transport/http/pom.xml | 2 +- transport/lwm2m/pom.xml | 2 +- transport/mqtt/pom.xml | 2 +- transport/pom.xml | 2 +- transport/snmp/pom.xml | 2 +- ui-ngx/pom.xml | 2 +- 55 files changed, 56 insertions(+), 56 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index 8c3976eb31..8e7c3cd524 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard application diff --git a/common/actor/pom.xml b/common/actor/pom.xml index 2de85be932..b113788a11 100644 --- a/common/actor/pom.xml +++ b/common/actor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/cache/pom.xml b/common/cache/pom.xml index 440860fda6..0a9141846f 100644 --- a/common/cache/pom.xml +++ b/common/cache/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/cluster-api/pom.xml b/common/cluster-api/pom.xml index c9fa6d0894..d6954a40f9 100644 --- a/common/cluster-api/pom.xml +++ b/common/cluster-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/coap-server/pom.xml b/common/coap-server/pom.xml index 420fc4dae6..116a94791d 100644 --- a/common/coap-server/pom.xml +++ b/common/coap-server/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index 029c660500..cf825ea637 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/data/pom.xml b/common/data/pom.xml index 677c3dfd25..f4e1fb2756 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/edge-api/pom.xml b/common/edge-api/pom.xml index 60562efbf2..c99a475236 100644 --- a/common/edge-api/pom.xml +++ b/common/edge-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index e64d4676ce..62e176e675 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index 0edd153a3c..51ca9546b1 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard common diff --git a/common/queue/pom.xml b/common/queue/pom.xml index edd4574bdd..a995d9b4a3 100644 --- a/common/queue/pom.xml +++ b/common/queue/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/script/pom.xml b/common/script/pom.xml index 26f60bd358..7a4304b77a 100644 --- a/common/script/pom.xml +++ b/common/script/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/script/remote-js-client/pom.xml b/common/script/remote-js-client/pom.xml index 8fa852d977..53e222ad76 100644 --- a/common/script/remote-js-client/pom.xml +++ b/common/script/remote-js-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT script org.thingsboard.common.script diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index c4e069f695..ae5f38f42f 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT script org.thingsboard.common.script diff --git a/common/stats/pom.xml b/common/stats/pom.xml index 0869243e7a..10d4ea3b95 100644 --- a/common/stats/pom.xml +++ b/common/stats/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/coap/pom.xml b/common/transport/coap/pom.xml index 2ac15d3e42..3e1174362c 100644 --- a/common/transport/coap/pom.xml +++ b/common/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/http/pom.xml b/common/transport/http/pom.xml index 8cf3e0efe8..09f822959f 100644 --- a/common/transport/http/pom.xml +++ b/common/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/lwm2m/pom.xml b/common/transport/lwm2m/pom.xml index 4433eae2b9..f5ee1eea52 100644 --- a/common/transport/lwm2m/pom.xml +++ b/common/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/mqtt/pom.xml b/common/transport/mqtt/pom.xml index bb4767640c..e11f923a0b 100644 --- a/common/transport/mqtt/pom.xml +++ b/common/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/pom.xml b/common/transport/pom.xml index 6879a4924d..4fc43aa3ea 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/snmp/pom.xml b/common/transport/snmp/pom.xml index 1865f498fa..0a615cfd4f 100644 --- a/common/transport/snmp/pom.xml +++ b/common/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml index 2e2174e0a9..6840a24ab2 100644 --- a/common/transport/transport-api/pom.xml +++ b/common/transport/transport-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/util/pom.xml b/common/util/pom.xml index df09e302ba..ee32f1e1e9 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/common/version-control/pom.xml b/common/version-control/pom.xml index a8acdf2be9..ae12a413c0 100644 --- a/common/version-control/pom.xml +++ b/common/version-control/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index 4d4dd2a30b..45f49790b0 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard dao diff --git a/monitoring/pom.xml b/monitoring/pom.xml index 399e34092d..cc3a78c04d 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -21,7 +21,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml index 12d36272c0..6413973d7c 100644 --- a/msa/black-box-tests/pom.xml +++ b/msa/black-box-tests/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index 0bd7bf4d60..fe92a77763 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/monitoring/pom.xml b/msa/monitoring/pom.xml index 1fe43219a0..bb0539ac98 100644 --- a/msa/monitoring/pom.xml +++ b/msa/monitoring/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.5.1-SNAPSHOT + 3.5.2-SNAPSHOT msa diff --git a/msa/pom.xml b/msa/pom.xml index bf4e15d9d4..451466f98a 100644 --- a/msa/pom.xml +++ b/msa/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard msa diff --git a/msa/tb-node/pom.xml b/msa/tb-node/pom.xml index 8437cc35c3..3d39ba285b 100644 --- a/msa/tb-node/pom.xml +++ b/msa/tb-node/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index c85ac88274..31380a4578 100644 --- a/msa/tb/pom.xml +++ b/msa/tb/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/coap/pom.xml b/msa/transport/coap/pom.xml index 386b91ea76..7c55ef4322 100644 --- a/msa/transport/coap/pom.xml +++ b/msa/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/http/pom.xml b/msa/transport/http/pom.xml index 344219a660..2d02b2f124 100644 --- a/msa/transport/http/pom.xml +++ b/msa/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/lwm2m/pom.xml b/msa/transport/lwm2m/pom.xml index 8dfef617cd..7a521a6718 100644 --- a/msa/transport/lwm2m/pom.xml +++ b/msa/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/mqtt/pom.xml b/msa/transport/mqtt/pom.xml index e1d740c877..4ab24589dd 100644 --- a/msa/transport/mqtt/pom.xml +++ b/msa/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/pom.xml b/msa/transport/pom.xml index e0bd5a9457..f12564c24f 100644 --- a/msa/transport/pom.xml +++ b/msa/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/snmp/pom.xml b/msa/transport/snmp/pom.xml index b6a4e15b04..c5b5617f69 100644 --- a/msa/transport/snmp/pom.xml +++ b/msa/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.msa transport - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT org.thingsboard.msa.transport diff --git a/msa/vc-executor-docker/pom.xml b/msa/vc-executor-docker/pom.xml index 9b6fc493cd..162ae1f801 100644 --- a/msa/vc-executor-docker/pom.xml +++ b/msa/vc-executor-docker/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/vc-executor/pom.xml b/msa/vc-executor/pom.xml index 9bd2befa90..c78b3fd129 100644 --- a/msa/vc-executor/pom.xml +++ b/msa/vc-executor/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index e9500cf5e0..58efe59856 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT msa org.thingsboard.msa diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index 0ae03f3980..d81be2fece 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -19,11 +19,11 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard netty-mqtt - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT jar Netty MQTT Client diff --git a/pom.xml b/pom.xml index 6c6608785d..98b2e1529a 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT pom Thingsboard diff --git a/rest-client/pom.xml b/rest-client/pom.xml index 638dc42009..728ffc5040 100644 --- a/rest-client/pom.xml +++ b/rest-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard rest-client diff --git a/rule-engine/pom.xml b/rule-engine/pom.xml index fe8cb3fab5..3ebb1f6c76 100644 --- a/rule-engine/pom.xml +++ b/rule-engine/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard rule-engine diff --git a/rule-engine/rule-engine-api/pom.xml b/rule-engine/rule-engine-api/pom.xml index 47d13e5658..f8c45d388b 100644 --- a/rule-engine/rule-engine-api/pom.xml +++ b/rule-engine/rule-engine-api/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index 34c6e315f7..ac493e79ce 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/tools/pom.xml b/tools/pom.xml index c0b74bb0a9..1cdd789ffb 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard tools diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 3b1e0a9e62..d7572a1523 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index 3d4b806d03..3a991911ce 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/lwm2m/pom.xml b/transport/lwm2m/pom.xml index efe76111f3..e8f639ba85 100644 --- a/transport/lwm2m/pom.xml +++ b/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index 75daa483a1..85ea0c86f1 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/pom.xml b/transport/pom.xml index 203ea6cbbb..ad614a8d2c 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard transport diff --git a/transport/snmp/pom.xml b/transport/snmp/pom.xml index c04e7d1f1f..e5ae7ce756 100644 --- a/transport/snmp/pom.xml +++ b/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT transport diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index d6dc28490f..5b5949a005 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.5.2-SNAPSHOT thingsboard org.thingsboard From 6b6e27bd60dd770ba7eeeb2d56cdf2d158e4a1a1 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Mon, 29 May 2023 14:07:02 +0300 Subject: [PATCH 07/61] Maven dependency fix --- common/util/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/util/pom.xml b/common/util/pom.xml index df09e302ba..14ae1748b2 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -92,6 +92,10 @@ com.github.oshi oshi-core + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + From 22aaadff858f603df2feebe9154013914385ae57 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 31 May 2023 17:26:03 +0200 Subject: [PATCH 08/61] jdk 17 for windows --- packaging/java/scripts/windows/install.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/java/scripts/windows/install.bat b/packaging/java/scripts/windows/install.bat index 5f71149c83..b0f6c9b203 100644 --- a/packaging/java/scripts/windows/install.bat +++ b/packaging/java/scripts/windows/install.bat @@ -7,7 +7,7 @@ setlocal ENABLEEXTENSIONS for /f tokens^=2-5^ delims^=.-_^" %%j in ('java -fullversion 2^>^&1') do set "jver=%%j%%k" @ECHO CurrentVersion %jver% -if %jver% NEQ 110 GOTO JAVA_NOT_INSTALLED +if %jver% NEQ 170 GOTO JAVA_NOT_INSTALLED :JAVA_INSTALLED From c9966ef3ef4ce1f5be77109103de2ff9f8416d27 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Fri, 2 Jun 2023 16:27:06 +0300 Subject: [PATCH 09/61] Extracted proto files to a separate module --- .../device/DeviceActorMessageProcessor.java | 27 +-- .../queue/DefaultTbCoreConsumerService.java | 5 +- .../subscription/TbSubscriptionUtils.java | 65 +------- common/cluster-api/pom.xml | 8 +- common/pom.xml | 1 + common/proto/pom.xml | 109 ++++++++++++ .../transport/adaptor/AdaptorException.java | 0 .../transport/adaptor/JsonConverter.java | 0 .../adaptor/JsonConverterConfig.java | 0 .../transport/adaptor/ProtoConverter.java | 0 .../common/transport/util/KvProtoUtil.java | 156 ++++++++++++++++++ .../src/main/proto/jsinvoke.proto | 0 .../src/main/proto/queue.proto | 0 .../src/main/proto/transport.proto | 0 common/queue/pom.xml | 4 + common/transport/transport-api/pom.xml | 9 - pom.xml | 7 + 17 files changed, 292 insertions(+), 99 deletions(-) create mode 100644 common/proto/pom.xml rename common/{transport/transport-api => proto}/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java (100%) rename common/{transport/transport-api => proto}/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java (100%) rename common/{transport/transport-api => proto}/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java (100%) rename common/{transport/transport-api => proto}/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java (100%) create mode 100644 common/proto/src/main/java/org/thingsboard/server/common/transport/util/KvProtoUtil.java rename common/{cluster-api => proto}/src/main/proto/jsinvoke.proto (100%) rename common/{cluster-api => proto}/src/main/proto/queue.proto (100%) rename common/{transport/transport-api => proto}/src/main/proto/transport.proto (100%) diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 934f309480..1831c6ab9c 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -63,6 +63,7 @@ import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; +import org.thingsboard.server.common.transport.util.KvProtoUtil; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; @@ -455,7 +456,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder() .setRequestId(requestId) .setSharedStateMsg(true) - .addAllSharedAttributeList(toTsKvProtos(result)) + .addAllSharedAttributeList(KvProtoUtil.attrToTsKvProtos(result)) .setIsMultipleAttributesRequest(request.getSharedAttributeNamesCount() > 1) .build(); sendToTransport(responseMsg, sessionInfo); @@ -476,8 +477,8 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso public void onSuccess(@Nullable List> result) { GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder() .setRequestId(requestId) - .addAllClientAttributeList(toTsKvProtos(result.get(0))) - .addAllSharedAttributeList(toTsKvProtos(result.get(1))) + .addAllClientAttributeList(KvProtoUtil.attrToTsKvProtos(result.get(0))) + .addAllSharedAttributeList(KvProtoUtil.attrToTsKvProtos(result.get(1))) .setIsMultipleAttributesRequest( request.getSharedAttributeNamesCount() + request.getClientAttributeNamesCount() > 1) .build(); @@ -547,7 +548,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso if (DataConstants.SHARED_SCOPE.equals(msg.getScope())) { List attributes = new ArrayList<>(msg.getValues()); if (attributes.size() > 0) { - List sharedUpdated = msg.getValues().stream().map(this::toTsKvProto) + List sharedUpdated = msg.getValues().stream().map(t -> KvProtoUtil.toTsKvProto(t.getLastUpdateTs(), t)) .collect(Collectors.toList()); if (!sharedUpdated.isEmpty()) { notification.addAllSharedUpdated(sharedUpdated); @@ -834,24 +835,6 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso }, systemContext.getDbCallbackExecutor()); } - private List toTsKvProtos(@Nullable List result) { - List clientAttributes; - if (result == null || result.isEmpty()) { - clientAttributes = Collections.emptyList(); - } else { - clientAttributes = new ArrayList<>(result.size()); - for (AttributeKvEntry attrEntry : result) { - clientAttributes.add(toTsKvProto(attrEntry)); - } - } - return clientAttributes; - } - - private TsKvProto toTsKvProto(AttributeKvEntry attrEntry) { - return TsKvProto.newBuilder().setTs(attrEntry.getLastUpdateTs()) - .setKv(toKeyValueProto(attrEntry)).build(); - } - private KeyValueProto toKeyValueProto(KvEntry kvEntry) { KeyValueProto.Builder builder = KeyValueProto.newBuilder(); builder.setKey(kvEntry.getKey()); diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java index 2bd0043046..e11b6cdd5b 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.stats.StatsFactory; +import org.thingsboard.server.common.transport.util.KvProtoUtil; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto; @@ -522,13 +523,13 @@ public class DefaultTbCoreConsumerService extends AbstractConsumerService builder.addData(toKeyValueProto(v.getTs(), v).build())); + ts.forEach(v -> builder.addData(KvProtoUtil.toKeyValueProto(v.getTs(), v).build())); SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder(); msgBuilder.setTsUpdate(builder); return ToCoreMsg.newBuilder().setToSubscriptionMgrMsg(msgBuilder.build()).build(); @@ -269,7 +270,7 @@ public class TbSubscriptionUtils { builder.setTenantIdMSB(tenantId.getId().getMostSignificantBits()); builder.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()); builder.setScope(scope); - attributes.forEach(v -> builder.addData(toKeyValueProto(v.getLastUpdateTs(), v).build())); + attributes.forEach(v -> builder.addData(KvProtoUtil.toKeyValueProto(v.getLastUpdateTs(), v).build())); SubscriptionMgrMsgProto.Builder msgBuilder = SubscriptionMgrMsgProto.newBuilder(); msgBuilder.setAttrUpdate(builder); @@ -292,70 +293,10 @@ public class TbSubscriptionUtils { return ToCoreMsg.newBuilder().setToSubscriptionMgrMsg(msgBuilder.build()).build(); } - - private static TsKvProto.Builder toKeyValueProto(long ts, KvEntry attr) { - KeyValueProto.Builder dataBuilder = KeyValueProto.newBuilder(); - dataBuilder.setKey(attr.getKey()); - dataBuilder.setType(KeyValueType.forNumber(attr.getDataType().ordinal())); - switch (attr.getDataType()) { - case BOOLEAN: - attr.getBooleanValue().ifPresent(dataBuilder::setBoolV); - break; - case LONG: - attr.getLongValue().ifPresent(dataBuilder::setLongV); - break; - case DOUBLE: - attr.getDoubleValue().ifPresent(dataBuilder::setDoubleV); - break; - case JSON: - attr.getJsonValue().ifPresent(dataBuilder::setJsonV); - break; - case STRING: - attr.getStrValue().ifPresent(dataBuilder::setStringV); - break; - } - return TsKvProto.newBuilder().setTs(ts).setKv(dataBuilder); - } - public static EntityId toEntityId(String entityType, long entityIdMSB, long entityIdLSB) { return EntityIdFactory.getByTypeAndUuid(entityType, new UUID(entityIdMSB, entityIdLSB)); } - public static List toTsKvEntityList(List dataList) { - List result = new ArrayList<>(dataList.size()); - dataList.forEach(proto -> result.add(new BasicTsKvEntry(proto.getTs(), getKvEntry(proto.getKv())))); - return result; - } - - public static List toAttributeKvList(List dataList) { - List result = new ArrayList<>(dataList.size()); - dataList.forEach(proto -> result.add(new BaseAttributeKvEntry(getKvEntry(proto.getKv()), proto.getTs()))); - return result; - } - - private static KvEntry getKvEntry(KeyValueProto proto) { - KvEntry entry = null; - DataType type = DataType.values()[proto.getType().getNumber()]; - switch (type) { - case BOOLEAN: - entry = new BooleanDataEntry(proto.getKey(), proto.getBoolV()); - break; - case LONG: - entry = new LongDataEntry(proto.getKey(), proto.getLongV()); - break; - case DOUBLE: - entry = new DoubleDataEntry(proto.getKey(), proto.getDoubleV()); - break; - case STRING: - entry = new StringDataEntry(proto.getKey(), proto.getStringV()); - break; - case JSON: - entry = new JsonDataEntry(proto.getKey(), proto.getJsonV()); - break; - } - return entry; - } - public static ToCoreMsg toAlarmUpdateProto(TenantId tenantId, EntityId entityId, AlarmInfo alarm) { TbAlarmUpdateProto.Builder builder = TbAlarmUpdateProto.newBuilder(); builder.setEntityType(entityId.getEntityType().name()); diff --git a/common/cluster-api/pom.xml b/common/cluster-api/pom.xml index c9fa6d0894..93cd7c665a 100644 --- a/common/cluster-api/pom.xml +++ b/common/cluster-api/pom.xml @@ -40,6 +40,10 @@ org.thingsboard.common data + + org.thingsboard.common + proto + org.thingsboard.common message @@ -119,10 +123,6 @@ - - org.xolstice.maven.plugins - protobuf-maven-plugin - org.apache.maven.plugins maven-source-plugin diff --git a/common/pom.xml b/common/pom.xml index 0edd153a3c..0c80189acf 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -35,6 +35,7 @@ data + proto util message actor diff --git a/common/proto/pom.xml b/common/proto/pom.xml new file mode 100644 index 0000000000..ab2cdf91c9 --- /dev/null +++ b/common/proto/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + + org.thingsboard + 3.6.0-SNAPSHOT + common + + org.thingsboard.common + proto + jar + + Thingsboard Server Common Protobuf and gRPC structures + https://thingsboard.io + + + UTF-8 + ${basedir}/../.. + + + + + org.thingsboard.common + data + + + org.thingsboard.common + message + + + com.google.protobuf + protobuf-java + + + com.google.protobuf + protobuf-java-util + + + io.grpc + grpc-netty-shaded + provided + + + io.grpc + grpc-protobuf + provided + + + io.grpc + grpc-stub + provided + + + org.springframework.boot + spring-boot-starter-web + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + test + + + org.awaitility + awaitility + test + + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + + + + + + + thingsboard-repo-deploy + ThingsBoard Repo Deployment + https://repo.thingsboard.io/artifactory/libs-release-public + + + + diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java b/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java similarity index 100% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java rename to common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java similarity index 100% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java rename to common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java b/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java similarity index 100% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java rename to common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java b/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java similarity index 100% rename from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java rename to common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java diff --git a/common/proto/src/main/java/org/thingsboard/server/common/transport/util/KvProtoUtil.java b/common/proto/src/main/java/org/thingsboard/server/common/transport/util/KvProtoUtil.java new file mode 100644 index 0000000000..172d014460 --- /dev/null +++ b/common/proto/src/main/java/org/thingsboard/server/common/transport/util/KvProtoUtil.java @@ -0,0 +1,156 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.transport.util; + +import org.thingsboard.server.common.data.kv.AttributeKvEntry; +import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; +import org.thingsboard.server.common.data.kv.BasicTsKvEntry; +import org.thingsboard.server.common.data.kv.BooleanDataEntry; +import org.thingsboard.server.common.data.kv.DataType; +import org.thingsboard.server.common.data.kv.DoubleDataEntry; +import org.thingsboard.server.common.data.kv.JsonDataEntry; +import org.thingsboard.server.common.data.kv.KvEntry; +import org.thingsboard.server.common.data.kv.LongDataEntry; +import org.thingsboard.server.common.data.kv.StringDataEntry; +import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.gen.transport.TransportProtos; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class KvProtoUtil { + + public static List attrToTsKvProtos(List result) { + List clientAttributes; + if (result == null || result.isEmpty()) { + clientAttributes = Collections.emptyList(); + } else { + clientAttributes = new ArrayList<>(result.size()); + for (AttributeKvEntry attrEntry : result) { + clientAttributes.add(toTsKvProto(attrEntry.getLastUpdateTs(), attrEntry)); + } + } + return clientAttributes; + } + + + public static List tsToTsKvProtos(List result) { + List ts; + if (result == null || result.isEmpty()) { + ts = Collections.emptyList(); + } else { + ts = new ArrayList<>(result.size()); + for (TsKvEntry attrEntry : result) { + ts.add(toTsKvProto(attrEntry.getTs(), attrEntry)); + } + } + return ts; + } + + public static TransportProtos.TsKvProto toTsKvProto(long ts, KvEntry kvEntry) { + return TransportProtos.TsKvProto.newBuilder().setTs(ts) + .setKv(KvProtoUtil.toKeyValueProto(kvEntry)).build(); + } + + public static TransportProtos.KeyValueProto toKeyValueProto(KvEntry kvEntry) { + TransportProtos.KeyValueProto.Builder builder = TransportProtos.KeyValueProto.newBuilder(); + builder.setKey(kvEntry.getKey()); + switch (kvEntry.getDataType()) { + case BOOLEAN: + builder.setType(TransportProtos.KeyValueType.BOOLEAN_V); + builder.setBoolV(kvEntry.getBooleanValue().get()); + break; + case DOUBLE: + builder.setType(TransportProtos.KeyValueType.DOUBLE_V); + builder.setDoubleV(kvEntry.getDoubleValue().get()); + break; + case LONG: + builder.setType(TransportProtos.KeyValueType.LONG_V); + builder.setLongV(kvEntry.getLongValue().get()); + break; + case STRING: + builder.setType(TransportProtos.KeyValueType.STRING_V); + builder.setStringV(kvEntry.getStrValue().get()); + break; + case JSON: + builder.setType(TransportProtos.KeyValueType.JSON_V); + builder.setJsonV(kvEntry.getJsonValue().get()); + break; + } + return builder.build(); + } + + public static TransportProtos.TsKvProto.Builder toKeyValueProto(long ts, KvEntry attr) { + TransportProtos.KeyValueProto.Builder dataBuilder = TransportProtos.KeyValueProto.newBuilder(); + dataBuilder.setKey(attr.getKey()); + dataBuilder.setType(TransportProtos.KeyValueType.forNumber(attr.getDataType().ordinal())); + switch (attr.getDataType()) { + case BOOLEAN: + attr.getBooleanValue().ifPresent(dataBuilder::setBoolV); + break; + case LONG: + attr.getLongValue().ifPresent(dataBuilder::setLongV); + break; + case DOUBLE: + attr.getDoubleValue().ifPresent(dataBuilder::setDoubleV); + break; + case JSON: + attr.getJsonValue().ifPresent(dataBuilder::setJsonV); + break; + case STRING: + attr.getStrValue().ifPresent(dataBuilder::setStringV); + break; + } + return TransportProtos.TsKvProto.newBuilder().setTs(ts).setKv(dataBuilder); + } + + public static List toTsKvEntityList(List dataList) { + List result = new ArrayList<>(dataList.size()); + dataList.forEach(proto -> result.add(new BasicTsKvEntry(proto.getTs(), getKvEntry(proto.getKv())))); + return result; + } + + public static List toAttributeKvList(List dataList) { + List result = new ArrayList<>(dataList.size()); + dataList.forEach(proto -> result.add(new BaseAttributeKvEntry(getKvEntry(proto.getKv()), proto.getTs()))); + return result; + } + + private static KvEntry getKvEntry(TransportProtos.KeyValueProto proto) { + KvEntry entry = null; + DataType type = DataType.values()[proto.getType().getNumber()]; + switch (type) { + case BOOLEAN: + entry = new BooleanDataEntry(proto.getKey(), proto.getBoolV()); + break; + case LONG: + entry = new LongDataEntry(proto.getKey(), proto.getLongV()); + break; + case DOUBLE: + entry = new DoubleDataEntry(proto.getKey(), proto.getDoubleV()); + break; + case STRING: + entry = new StringDataEntry(proto.getKey(), proto.getStringV()); + break; + case JSON: + entry = new JsonDataEntry(proto.getKey(), proto.getJsonV()); + break; + } + return entry; + } +} diff --git a/common/cluster-api/src/main/proto/jsinvoke.proto b/common/proto/src/main/proto/jsinvoke.proto similarity index 100% rename from common/cluster-api/src/main/proto/jsinvoke.proto rename to common/proto/src/main/proto/jsinvoke.proto diff --git a/common/cluster-api/src/main/proto/queue.proto b/common/proto/src/main/proto/queue.proto similarity index 100% rename from common/cluster-api/src/main/proto/queue.proto rename to common/proto/src/main/proto/queue.proto diff --git a/common/transport/transport-api/src/main/proto/transport.proto b/common/proto/src/main/proto/transport.proto similarity index 100% rename from common/transport/transport-api/src/main/proto/transport.proto rename to common/proto/src/main/proto/transport.proto diff --git a/common/queue/pom.xml b/common/queue/pom.xml index edd4574bdd..59e96d210d 100644 --- a/common/queue/pom.xml +++ b/common/queue/pom.xml @@ -36,6 +36,10 @@ + + org.thingsboard.common + proto + org.thingsboard.common data diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml index 2e2174e0a9..b45cd28e52 100644 --- a/common/transport/transport-api/pom.xml +++ b/common/transport/transport-api/pom.xml @@ -135,13 +135,4 @@ - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - - - - diff --git a/pom.xml b/pom.xml index 9b11160fab..c778ebcaab 100755 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,8 @@ 2016 + 17 + 17 ${basedir} true none @@ -892,6 +894,11 @@ version-control ${project.version} + + org.thingsboard.common + proto + ${project.version} + org.thingsboard.common cache From 4c470583f3467fc7d4a524e95dfa33cfe99a77a4 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Fri, 2 Jun 2023 16:31:38 +0300 Subject: [PATCH 10/61] Correct package name --- .../actors/device/DeviceActorMessageProcessor.java | 2 +- .../server/controller/TelemetryController.java | 2 +- .../rpc/constructor/EntityDataMsgConstructor.java | 2 +- .../telemetry/BaseTelemetryProcessor.java | 2 +- .../queue/DefaultTbCoreConsumerService.java | 2 +- .../service/subscription/TbSubscriptionUtils.java | 14 +------------- .../importing/csv/AbstractBulkImportService.java | 2 +- .../thingsboard/server/edge/DeviceEdgeTest.java | 2 +- .../{transport => }/adaptor/AdaptorException.java | 2 +- .../{transport => }/adaptor/JsonConverter.java | 2 +- .../adaptor/JsonConverterConfig.java | 2 +- .../{transport => }/adaptor/ProtoConverter.java | 2 +- .../common/{transport => }/util/KvProtoUtil.java | 3 +-- .../transport/coap/CoapTransportResource.java | 4 ++-- .../transport/coap/adaptors/CoapAdaptorUtils.java | 2 +- .../coap/adaptors/CoapTransportAdaptor.java | 2 +- .../transport/coap/adaptors/JsonCoapAdaptor.java | 4 ++-- .../transport/coap/adaptors/ProtoCoapAdaptor.java | 6 +++--- .../callback/GetAttributesSyncSessionCallback.java | 2 +- .../callback/ToServerRpcSyncSessionCallback.java | 2 +- .../transport/coap/client/CoapClientContext.java | 2 +- .../coap/client/DefaultCoapClientContext.java | 2 +- .../coap/efento/CoapEfentoTransportResource.java | 2 +- .../coap/efento/adaptor/EfentoCoapAdaptor.java | 4 ++-- .../server/transport/http/DeviceApiController.java | 2 +- .../lwm2m/server/adaptors/LwM2MJsonAdaptor.java | 4 ++-- .../server/adaptors/LwM2MTransportAdaptor.java | 2 +- .../transport/mqtt/MqttTransportHandler.java | 2 +- .../adaptors/BackwardCompatibilityAdaptor.java | 2 +- .../transport/mqtt/adaptors/JsonMqttAdaptor.java | 4 ++-- .../mqtt/adaptors/MqttTransportAdaptor.java | 2 +- .../transport/mqtt/adaptors/ProtoMqttAdaptor.java | 6 +++--- .../session/AbstractGatewaySessionHandler.java | 6 +++--- .../mqtt/session/GatewaySessionHandler.java | 2 +- .../mqtt/session/SparkplugNodeSessionHandler.java | 6 +++--- .../mqtt/util/sparkplug/MetricDataType.java | 2 +- .../snmp/service/SnmpTransportService.java | 2 +- .../src/test/java/JsonConverterTest.java | 2 +- .../action/TbCopyAttributesToEntityViewNode.java | 2 +- .../rule/engine/profile/AlarmRuleState.java | 2 +- .../rule/engine/profile/DeviceState.java | 2 +- .../rule/engine/telemetry/TbMsgAttributesNode.java | 2 +- .../rule/engine/telemetry/TbMsgTimeseriesNode.java | 2 +- 43 files changed, 56 insertions(+), 69 deletions(-) rename common/proto/src/main/java/org/thingsboard/server/common/{transport => }/adaptor/AdaptorException.java (94%) rename common/proto/src/main/java/org/thingsboard/server/common/{transport => }/adaptor/JsonConverter.java (99%) rename common/proto/src/main/java/org/thingsboard/server/common/{transport => }/adaptor/JsonConverterConfig.java (96%) rename common/proto/src/main/java/org/thingsboard/server/common/{transport => }/adaptor/ProtoConverter.java (99%) rename common/proto/src/main/java/org/thingsboard/server/common/{transport => }/util/KvProtoUtil.java (98%) diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 1831c6ab9c..fc8eaf9e1c 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -63,7 +63,7 @@ import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest; import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg; -import org.thingsboard.server.common.transport.util.KvProtoUtil; +import org.thingsboard.server.common.util.KvProtoUtil; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 05f56e93bd..670a65f862 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -74,7 +74,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.exception.InvalidParametersException; import org.thingsboard.server.exception.UncheckedApiException; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java index 242a15ba56..0cef8f3581 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/constructor/EntityDataMsgConstructor.java @@ -27,7 +27,7 @@ import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg; import org.thingsboard.server.gen.edge.v1.EntityDataProto; import org.thingsboard.server.gen.transport.TransportProtos; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java index fece86b92a..ebdf1b6c57 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java @@ -55,7 +55,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.common.msg.session.SessionMsgType; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.transport.util.JsonUtils; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.gen.edge.v1.AttributeDeleteMsg; diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java index e11b6cdd5b..36799e7fac 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java @@ -40,7 +40,7 @@ import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; import org.thingsboard.server.common.msg.rpc.FromDeviceRpcResponse; import org.thingsboard.server.common.stats.StatsFactory; -import org.thingsboard.server.common.transport.util.KvProtoUtil; +import org.thingsboard.server.common.util.KvProtoUtil; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.DeviceStateServiceMsgProto; diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java index 7bba9a429a..2f1dca9333 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbSubscriptionUtils.java @@ -22,20 +22,9 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; -import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; -import org.thingsboard.server.common.data.kv.BasicTsKvEntry; -import org.thingsboard.server.common.data.kv.BooleanDataEntry; -import org.thingsboard.server.common.data.kv.DataType; -import org.thingsboard.server.common.data.kv.DoubleDataEntry; -import org.thingsboard.server.common.data.kv.JsonDataEntry; -import org.thingsboard.server.common.data.kv.KvEntry; -import org.thingsboard.server.common.data.kv.LongDataEntry; -import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; -import org.thingsboard.server.common.transport.util.KvProtoUtil; +import org.thingsboard.server.common.util.KvProtoUtil; import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.gen.transport.TransportProtos.KeyValueProto; -import org.thingsboard.server.gen.transport.TransportProtos.KeyValueType; import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionMgrMsgProto; import org.thingsboard.server.gen.transport.TransportProtos.TbAlarmDeleteProto; import org.thingsboard.server.gen.transport.TransportProtos.TbAlarmUpdateProto; @@ -52,7 +41,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesSubscrip import org.thingsboard.server.gen.transport.TransportProtos.TbTimeSeriesUpdateProto; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToCoreNotificationMsg; -import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; import org.thingsboard.server.service.ws.notification.sub.NotificationRequestUpdate; import org.thingsboard.server.service.ws.notification.sub.NotificationUpdate; import org.thingsboard.server.service.ws.notification.sub.NotificationsCountSubscription; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java index 45805c5939..bc71505631 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java @@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportColumn import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportRequest; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.controller.BaseController; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.service.action.EntityActionService; diff --git a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java index 15d5b5c809..d3a8083b4a 100644 --- a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java @@ -51,7 +51,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.msg.session.FeatureType; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.gen.edge.v1.AttributesRequestMsg; import org.thingsboard.server.gen.edge.v1.DeviceCredentialsRequestMsg; diff --git a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/AdaptorException.java similarity index 94% rename from common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java rename to common/proto/src/main/java/org/thingsboard/server/common/adaptor/AdaptorException.java index 8b2908a4b5..1c22163c1f 100644 --- a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/AdaptorException.java +++ b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/AdaptorException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.transport.adaptor; +package org.thingsboard.server.common.adaptor; public class AdaptorException extends Exception { diff --git a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/JsonConverter.java similarity index 99% rename from common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java rename to common/proto/src/main/java/org/thingsboard/server/common/adaptor/JsonConverter.java index 51e74d5097..c51bc784a6 100644 --- a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java +++ b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/JsonConverter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.transport.adaptor; +package org.thingsboard.server.common.adaptor; import com.google.gson.Gson; import com.google.gson.JsonArray; diff --git a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/JsonConverterConfig.java similarity index 96% rename from common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java rename to common/proto/src/main/java/org/thingsboard/server/common/adaptor/JsonConverterConfig.java index 0a9df150e5..e160c051f5 100644 --- a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverterConfig.java +++ b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/JsonConverterConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.transport.adaptor; +package org.thingsboard.server.common.adaptor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; diff --git a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/ProtoConverter.java similarity index 99% rename from common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java rename to common/proto/src/main/java/org/thingsboard/server/common/adaptor/ProtoConverter.java index 54358709f0..098108c864 100644 --- a/common/proto/src/main/java/org/thingsboard/server/common/transport/adaptor/ProtoConverter.java +++ b/common/proto/src/main/java/org/thingsboard/server/common/adaptor/ProtoConverter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.transport.adaptor; +package org.thingsboard.server.common.adaptor; import com.google.gson.Gson; import com.google.gson.JsonElement; diff --git a/common/proto/src/main/java/org/thingsboard/server/common/transport/util/KvProtoUtil.java b/common/proto/src/main/java/org/thingsboard/server/common/util/KvProtoUtil.java similarity index 98% rename from common/proto/src/main/java/org/thingsboard/server/common/transport/util/KvProtoUtil.java rename to common/proto/src/main/java/org/thingsboard/server/common/util/KvProtoUtil.java index 172d014460..63ef81d35f 100644 --- a/common/proto/src/main/java/org/thingsboard/server/common/transport/util/KvProtoUtil.java +++ b/common/proto/src/main/java/org/thingsboard/server/common/util/KvProtoUtil.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.common.transport.util; +package org.thingsboard.server.common.util; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; @@ -28,7 +28,6 @@ import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.gen.transport.TransportProtos; -import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java index 7dde25bfd0..96f4cfecac 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java @@ -35,8 +35,8 @@ import org.thingsboard.server.common.data.security.DeviceTokenCredentials; import org.thingsboard.server.common.msg.session.FeatureType; import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.transport.TransportServiceCallback; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.coap.callback.CoapDeviceAuthCallback; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java index 710f18a8b7..629e0380e0 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapAdaptorUtils.java @@ -17,7 +17,7 @@ package org.thingsboard.server.transport.coap.adaptors; import org.eclipse.californium.core.coap.Request; import org.thingsboard.server.common.data.StringUtils; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos; import java.util.Arrays; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java index 05a38e1ad1..e88251c93c 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/CoapTransportAdaptor.java @@ -19,7 +19,7 @@ import com.google.protobuf.Descriptors; import com.google.protobuf.DynamicMessage; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.coap.Response; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceRequestMsg; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java index d81ff32edd..fffe1a7e1a 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java @@ -29,8 +29,8 @@ import org.eclipse.californium.core.coap.Response; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.coap.CoapTransportResource; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java index 4d3b0015ef..5287645591 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/ProtoCoapAdaptor.java @@ -28,9 +28,9 @@ import org.eclipse.californium.core.coap.Response; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; -import org.thingsboard.server.common.transport.adaptor.ProtoConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.ProtoConverter; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.coap.CoapTransportResource; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/GetAttributesSyncSessionCallback.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/GetAttributesSyncSessionCallback.java index 907e49f600..caacd31012 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/GetAttributesSyncSessionCallback.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/GetAttributesSyncSessionCallback.java @@ -20,7 +20,7 @@ import org.eclipse.californium.core.coap.CoAP; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.coap.Response; import org.eclipse.californium.core.server.resources.CoapExchange; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.coap.client.TbCoapClientState; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/ToServerRpcSyncSessionCallback.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/ToServerRpcSyncSessionCallback.java index 2209ea6613..fc35da0bd6 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/ToServerRpcSyncSessionCallback.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/ToServerRpcSyncSessionCallback.java @@ -19,7 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.californium.core.coap.CoAP; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.server.resources.CoapExchange; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.coap.client.TbCoapClientState; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/CoapClientContext.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/CoapClientContext.java index 36ef8472de..0ca21fd8cb 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/CoapClientContext.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/CoapClientContext.java @@ -19,7 +19,7 @@ import org.eclipse.californium.core.observe.ObserveRelation; import org.eclipse.californium.core.server.resources.CoapExchange; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.msg.session.SessionMsgType; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java index 3caaba0ba9..95f1698dc3 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DefaultCoapClientContext.java @@ -53,7 +53,7 @@ import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportDeviceProfileCache; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.common.transport.auth.SessionInfoCreator; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java index 93061d522a..5a59ab0f51 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/CoapEfentoTransportResource.java @@ -31,7 +31,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.device.profile.CoapDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.EfentoCoapDeviceTypeConfiguration; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.common.transport.auth.SessionInfoCreator; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.coap.MeasurementTypeProtos; diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/adaptor/EfentoCoapAdaptor.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/adaptor/EfentoCoapAdaptor.java index a6b588139a..42eebe86f1 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/adaptor/EfentoCoapAdaptor.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/efento/adaptor/EfentoCoapAdaptor.java @@ -18,8 +18,8 @@ package org.thingsboard.server.transport.coap.efento.adaptor; import com.google.gson.Gson; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource; diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index 041ae0510d..589e93d803 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -46,7 +46,7 @@ import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportContext; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.transport.auth.SessionInfoCreator; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MJsonAdaptor.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MJsonAdaptor.java index feb74b47f9..afe1d160ce 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MJsonAdaptor.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MJsonAdaptor.java @@ -19,8 +19,8 @@ import com.google.gson.JsonElement; import com.google.gson.JsonSyntaxException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MTransportAdaptor.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MTransportAdaptor.java index 96e6008c63..fe24b21053 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MTransportAdaptor.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MTransportAdaptor.java @@ -16,7 +16,7 @@ package org.thingsboard.server.transport.lwm2m.server.adaptors; import com.google.gson.JsonElement; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos; import java.util.Collection; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index efa5aee965..8347769bd7 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -63,7 +63,7 @@ import org.thingsboard.server.common.msg.tools.TbRateLimitsException; import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.common.transport.auth.SessionInfoCreator; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/BackwardCompatibilityAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/BackwardCompatibilityAdaptor.java index 40be642a1a..73bba60cff 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/BackwardCompatibilityAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/BackwardCompatibilityAdaptor.java @@ -21,7 +21,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.mqtt.session.MqttDeviceAwareSessionContext; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java index 513fd97cf6..a30749b17d 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java @@ -30,8 +30,8 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.mqtt.session.MqttDeviceAwareSessionContext; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java index 3764c2a9a9..10599d0be7 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/MqttTransportAdaptor.java @@ -24,7 +24,7 @@ import io.netty.handler.codec.mqtt.MqttMessageType; import io.netty.handler.codec.mqtt.MqttPublishMessage; import io.netty.handler.codec.mqtt.MqttPublishVariableHeader; import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java index 39176fa212..c1fba86776 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/ProtoMqttAdaptor.java @@ -28,9 +28,9 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; -import org.thingsboard.server.common.transport.adaptor.ProtoConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.ProtoConverter; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.mqtt.session.DeviceSessionCtx; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java index 95603e751c..9a7e6c5177 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java @@ -39,9 +39,9 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; -import org.thingsboard.server.common.transport.adaptor.ProtoConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.ProtoConverter; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.common.transport.auth.TransportDeviceInfo; import org.thingsboard.server.gen.transport.TransportApiProtos; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java index de0f2a502b..6ff505cb36 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java @@ -17,7 +17,7 @@ package org.thingsboard.server.transport.mqtt.session; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.mqtt.MqttPublishMessage; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import java.util.UUID; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java index 48998d58cd..f3aaa2708f 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java @@ -32,9 +32,9 @@ import org.springframework.util.CollectionUtils; import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; -import org.thingsboard.server.common.transport.adaptor.ProtoConverter; +import org.thingsboard.server.common.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.ProtoConverter; import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse; import org.thingsboard.server.gen.transport.TransportApiProtos; import org.thingsboard.server.gen.transport.TransportProtos; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java index d5e781a402..c49286a4b1 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/sparkplug/MetricDataType.java @@ -16,7 +16,7 @@ package org.thingsboard.server.transport.mqtt.util.sparkplug; import lombok.extern.slf4j.Slf4j; -import org.thingsboard.server.common.transport.adaptor.AdaptorException; +import org.thingsboard.server.common.adaptor.AdaptorException; import org.thingsboard.server.gen.transport.mqtt.SparkplugBProto; import java.math.BigInteger; diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java index 6e68a0bd44..51ed8d0485 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java @@ -46,7 +46,7 @@ import org.thingsboard.server.common.data.transport.snmp.config.RepeatingQueryin import org.thingsboard.server.common.data.transport.snmp.config.SnmpCommunicationConfig; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbSnmpTransportComponent; import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; diff --git a/common/transport/transport-api/src/test/java/JsonConverterTest.java b/common/transport/transport-api/src/test/java/JsonConverterTest.java index 39ed04a29a..1062199caf 100644 --- a/common/transport/transport-api/src/test/java/JsonConverterTest.java +++ b/common/transport/transport-api/src/test/java/JsonConverterTest.java @@ -19,7 +19,7 @@ import org.junit.Assert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import java.util.ArrayList; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java index 6f7bb7cf8d..9196561ed5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java @@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.util.CollectionsUtil; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.session.SessionMsgType; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import javax.annotation.Nullable; import java.util.ArrayList; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java index f31896a8c9..6bb37438a1 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java @@ -41,7 +41,7 @@ import org.thingsboard.server.common.data.query.KeyFilterPredicate; import org.thingsboard.server.common.data.query.NumericFilterPredicate; import org.thingsboard.server.common.data.query.StringFilterPredicate; import org.thingsboard.server.common.msg.tools.SchedulerUtils; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import java.time.Instant; import java.time.ZoneId; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java index 31f661417b..feedfaae60 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java @@ -41,7 +41,7 @@ import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.common.data.rule.RuleNodeState; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.session.SessionMsgType; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.dao.sql.query.EntityKeyMapping; import java.util.ArrayList; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 9cf9bfa1bd..5baba50565 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.session.SessionMsgType; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import java.util.ArrayList; import java.util.List; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java index dcc84813cd..b94df4268c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.session.SessionMsgType; -import org.thingsboard.server.common.transport.adaptor.JsonConverter; +import org.thingsboard.server.common.adaptor.JsonConverter; import java.util.ArrayList; import java.util.List; From db6f3102849a259090789ccce7c60befc033fbd8 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 5 Jun 2023 15:24:47 +0200 Subject: [PATCH 11/61] migration to spring boot 3.1 --- application/pom.xml | 11 +- .../server/actors/ActorSystemContext.java | 6 +- .../device/DeviceActorMessageProcessor.java | 2 +- .../actors/service/DefaultActorService.java | 4 +- ...tomOAuth2AuthorizationRequestResolver.java | 5 +- .../config/RateLimitProcessingFilter.java | 10 +- .../server/config/SwaggerConfiguration.java | 2 +- .../ThingsboardSecurityConfiguration.java | 82 +++--- .../thingsboard/server/config/WebConfig.java | 4 +- .../controller/AbstractRpcController.java | 2 +- .../server/controller/AuthController.java | 2 +- .../server/controller/BaseController.java | 8 +- .../server/controller/DeviceController.java | 2 +- .../server/controller/EdgeController.java | 2 +- .../controller/NotificationController.java | 2 +- .../NotificationRuleController.java | 2 +- .../NotificationTargetController.java | 2 +- .../NotificationTemplateController.java | 2 +- .../server/controller/OAuth2Controller.java | 2 +- .../server/controller/RpcV2Controller.java | 2 +- .../controller/SystemInfoController.java | 2 +- .../controller/TelemetryController.java | 6 +- .../TwoFactorAuthConfigController.java | 2 +- .../controller/TwoFactorAuthController.java | 2 +- .../server/controller/UserController.java | 2 +- .../controller/plugin/TbWebSocketHandler.java | 8 +- .../ThingsboardErrorResponseHandler.java | 16 +- .../DefaultTbApiUsageStateService.java | 4 +- .../limits/DefaultRateLimitService.java | 2 +- .../AnnotationComponentDiscoveryService.java | 2 +- .../device/ClaimDevicesServiceImpl.java | 2 +- .../edge/DefaultEdgeNotificationService.java | 4 +- .../DefaultEdgeInstallService.java | 2 +- .../edge/instructions/EdgeInstallService.java | 2 +- .../service/edge/rpc/EdgeGrpcService.java | 6 +- .../telemetry/BaseTelemetryProcessor.java | 4 +- .../DefaultTbEntityViewService.java | 2 +- .../entitiy/user/DefaultUserService.java | 2 +- .../service/entitiy/user/TbUserService.java | 2 +- .../SharedEventLoopGroupService.java | 4 +- .../DefaultSystemDataLoaderService.java | 6 +- .../TbRuleEngineQueueConfigService.java | 2 +- .../service/mail/DefaultMailService.java | 5 +- .../DefaultNotificationSchedulerService.java | 2 +- .../DefaultNotificationRuleProcessor.java | 2 +- .../cache/DefaultNotificationRulesCache.java | 2 +- .../ota/DefaultOtaPackageStateService.java | 2 +- .../queue/DefaultTbCoreConsumerService.java | 4 +- .../DefaultTbRuleEngineConsumerService.java | 5 +- .../processing/AbstractConsumerService.java | 2 +- .../rpc/DefaultTbCoreDeviceRpcService.java | 5 +- .../rpc/DefaultTbRuleEngineRpcService.java | 4 +- .../service/security/AccessValidator.java | 6 +- ...wtTokenAuthenticationProcessingFilter.java | 8 +- .../jwt/RefreshTokenProcessingFilter.java | 8 +- .../auth/jwt/SkipPathRequestMatcher.java | 2 +- .../extractor/JwtHeaderTokenExtractor.java | 2 +- .../jwt/extractor/JwtQueryTokenExtractor.java | 2 +- .../auth/jwt/extractor/TokenExtractor.java | 4 +- .../auth/oauth2/AppleOAuth2ClientMapper.java | 2 +- .../auth/oauth2/BasicOAuth2ClientMapper.java | 2 +- .../security/auth/oauth2/CookieUtils.java | 6 +- .../auth/oauth2/CustomOAuth2ClientMapper.java | 2 +- .../auth/oauth2/GithubOAuth2ClientMapper.java | 2 +- ...eOAuth2AuthorizationRequestRepository.java | 7 +- .../auth/oauth2/OAuth2ClientMapper.java | 2 +- .../Oauth2AuthenticationFailureHandler.java | 6 +- .../Oauth2AuthenticationSuccessHandler.java | 6 +- .../auth/rest/RestAuthenticationDetails.java | 2 +- .../rest/RestAuthenticationDetailsSource.java | 2 +- ...RestAwareAuthenticationFailureHandler.java | 6 +- ...RestAwareAuthenticationSuccessHandler.java | 8 +- .../auth/rest/RestLoginProcessingFilter.java | 8 +- .../rest/RestPublicLoginProcessingFilter.java | 8 +- .../system/DefaultSystemSecurityService.java | 4 +- .../system/SystemSecurityService.java | 2 +- .../server/service/sms/DefaultSmsService.java | 5 +- .../state/DefaultDeviceStateService.java | 11 +- .../service/stats/DefaultJsInvokeStats.java | 2 +- .../DefaultRuleEngineStatisticsService.java | 2 +- .../DefaultSubscriptionManagerService.java | 4 +- ...efaultTbEntityDataSubscriptionService.java | 4 +- .../DefaultTbLocalSubscriptionService.java | 4 +- .../csv/AbstractBulkImportService.java | 6 +- .../DefaultEntitiesVersionControlService.java | 4 +- .../system/DefaultSystemInfoService.java | 4 +- .../AbstractSubscriptionService.java | 6 +- .../DefaultTelemetrySubscriptionService.java | 6 +- .../transport/TbCoreTransportApiService.java | 4 +- .../service/update/DefaultUpdateService.java | 2 +- .../service/ws/DefaultWebSocketService.java | 6 +- .../thingsboard/server/utils/MiscUtils.java | 2 +- .../src/main/resources/thingsboard.yml | 2 +- .../controller/AbstractControllerTest.java | 2 +- .../server/edge/DeviceEdgeTest.java | 2 +- .../lwm2m/AbstractLwM2MIntegrationTest.java | 10 +- .../security/sql/PskLwm2mIntegrationTest.java | 2 +- .../security/sql/RpkLwM2MIntegrationTest.java | 2 +- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 2 +- common/cache/pom.xml | 4 +- .../server/cache/CacheSpecsMap.java | 2 +- .../cache/RedisTbTransactionalCache.java | 3 +- common/cluster-api/pom.xml | 4 +- .../coapserver/DefaultCoapServerService.java | 4 +- common/dao-api/pom.xml | 4 +- .../cassandra/AbstractCassandraCluster.java | 2 +- .../dao/cassandra/CassandraCluster.java | 2 +- .../dao/cassandra/CassandraDriverOptions.java | 2 +- .../cassandra/CassandraInstallCluster.java | 2 +- common/data/pom.xml | 4 +- .../server/common/data/DashboardInfo.java | 2 +- .../server/common/data/DeviceProfile.java | 2 +- .../AlarmCreateOrUpdateActiveRequest.java | 4 +- .../common/data/alarm/AlarmUpdateRequest.java | 4 +- .../data/device/profile/AlarmCondition.java | 2 +- .../device/profile/AlarmConditionFilter.java | 2 +- .../common/data/device/profile/AlarmRule.java | 2 +- .../device/profile/DeviceProfileAlarm.java | 2 +- .../device/profile/DeviceProfileData.java | 2 +- .../common/data/kv/BaseAttributeKvEntry.java | 2 +- .../server/common/data/kv/BasicTsKvEntry.java | 2 +- .../notification/NotificationRequest.java | 4 +- .../NotificationRequestConfig.java | 2 +- ...faultNotificationRuleRecipientsConfig.java | 2 +- ...latedNotificationRuleRecipientsConfig.java | 2 +- .../notification/rule/NotificationRule.java | 8 +- .../NotificationRuleRecipientsConfig.java | 2 +- ...signmentNotificationRuleTriggerConfig.java | 2 +- .../AlarmNotificationRuleTriggerConfig.java | 2 +- ...ActivityNotificationRuleTriggerConfig.java | 2 +- ...iesLimitNotificationRuleTriggerConfig.java | 2 +- .../settings/NotificationSettings.java | 4 +- ...SlackNotificationDeliveryMethodConfig.java | 2 +- .../targets/NotificationTarget.java | 6 +- .../targets/platform/CustomerUsersFilter.java | 2 +- ...PlatformUsersNotificationTargetConfig.java | 4 +- .../targets/platform/UserListFilter.java | 2 +- .../targets/slack/SlackConversation.java | 4 +- .../slack/SlackNotificationTargetConfig.java | 4 +- .../DeliveryMethodNotificationTemplate.java | 2 +- ...ailDeliveryMethodNotificationTemplate.java | 2 +- .../template/NotificationTemplate.java | 6 +- .../template/NotificationTemplateConfig.java | 4 +- ...WebDeliveryMethodNotificationTemplate.java | 2 +- .../OAuth2ClientRegistrationTemplate.java | 2 +- .../data/oauth2/OAuth2MapperConfig.java | 2 +- .../data/query/FilterPredicateValue.java | 2 +- .../data/query/StringFilterPredicate.java | 2 +- .../model/mfa/PlatformTwoFaSettings.java | 8 +- .../account/BackupCodeTwoFaAccountConfig.java | 2 +- .../mfa/account/EmailTwoFaAccountConfig.java | 4 +- .../mfa/account/SmsTwoFaAccountConfig.java | 4 +- .../mfa/account/TotpTwoFaAccountConfig.java | 4 +- .../BackupCodeTwoFaProviderConfig.java | 2 +- .../provider/OtpBasedTwoFaProviderConfig.java | 2 +- .../mfa/provider/SmsTwoFaProviderConfig.java | 4 +- .../mfa/provider/TotpTwoFaProviderConfig.java | 2 +- .../server/common/data/validation/Length.java | 4 +- .../server/common/data/validation/NoXss.java | 4 +- .../servicebus/TbServiceBusQueueConfigs.java | 2 +- .../AbstractTbQueueConsumerTemplate.java | 2 +- .../common/DefaultTbQueueRequestTemplate.java | 2 +- .../DefaultTbServiceInfoProvider.java | 2 +- .../queue/discovery/HashPartitionService.java | 4 +- .../queue/discovery/ZkDiscoveryService.java | 4 +- .../environment/EnvironmentLogService.java | 2 +- .../kafka/TbKafkaConsumerStatsService.java | 4 +- .../queue/kafka/TbKafkaTopicConfigs.java | 2 +- .../provider/AwsSqsMonolithQueueFactory.java | 2 +- .../provider/AwsSqsTbCoreQueueFactory.java | 2 +- .../AwsSqsTbRuleEngineQueueFactory.java | 2 +- .../AwsSqsTbVersionControlQueueFactory.java | 2 +- .../provider/AwsSqsTransportQueueFactory.java | 2 +- .../provider/KafkaMonolithQueueFactory.java | 2 +- .../provider/KafkaTbCoreQueueFactory.java | 2 +- .../KafkaTbRuleEngineQueueFactory.java | 2 +- .../KafkaTbTransportQueueFactory.java | 2 +- .../KafkaTbVersionControlQueueFactory.java | 2 +- .../provider/PubSubMonolithQueueFactory.java | 2 +- .../provider/PubSubTbCoreQueueFactory.java | 2 +- .../PubSubTbRuleEngineQueueFactory.java | 2 +- .../PubSubTbVersionControlQueueFactory.java | 2 +- .../provider/PubSubTransportQueueFactory.java | 2 +- .../RabbitMqMonolithQueueFactory.java | 2 +- .../provider/RabbitMqTbCoreQueueFactory.java | 2 +- .../RabbitMqTbRuleEngineQueueFactory.java | 2 +- .../RabbitMqTbVersionControlQueueFactory.java | 2 +- .../RabbitMqTransportQueueFactory.java | 2 +- .../ServiceBusMonolithQueueFactory.java | 2 +- .../ServiceBusTbCoreQueueFactory.java | 2 +- .../ServiceBusTbRuleEngineQueueFactory.java | 2 +- ...erviceBusTbVersionControlQueueFactory.java | 2 +- .../ServiceBusTransportQueueFactory.java | 2 +- .../provider/TbCoreQueueProducerProvider.java | 2 +- .../TbRuleEngineProducerProvider.java | 2 +- .../TbTransportQueueProducerProvider.java | 2 +- .../TbVersionControlProducerProvider.java | 2 +- .../server/queue/pubsub/TbPubSubSettings.java | 2 +- .../pubsub/TbPubSubSubscriptionSettings.java | 2 +- .../rabbitmq/TbRabbitMqQueueArguments.java | 2 +- .../queue/rabbitmq/TbRabbitMqSettings.java | 2 +- .../scheduler/DefaultSchedulerComponent.java | 4 +- .../queue/sqs/TbAwsSqsQueueAttributes.java | 2 +- .../DefaultTbApiUsageReportClient.java | 2 +- .../service/script/RemoteJsInvokeService.java | 4 +- .../script/api/ScriptStatCallback.java | 2 +- .../script/api/js/NashornJsInvokeService.java | 4 +- .../api/tbel/DefaultTbelInvokeService.java | 4 +- .../common/stats/DefaultStatsFactory.java | 2 +- .../transport/coap/CoapTransportService.java | 4 +- .../transport/http/DeviceApiController.java | 2 +- .../LwM2MTransportBootstrapService.java | 4 +- ...LwM2MDtlsBootstrapCertificateVerifier.java | 2 +- .../TbLwM2MDtlsCertificateVerifier.java | 2 +- .../server/DefaultLwM2mTransportService.java | 2 +- .../server/LwM2mTransportServerHelper.java | 4 +- .../DefaultLwM2mDownlinkMsgHandler.java | 4 +- .../model/LwM2MModelConfigServiceImpl.java | 2 +- .../ota/DefaultLwM2MOtaUpdateService.java | 4 +- .../uplink/DefaultLwM2mUplinkMsgHandler.java | 4 +- .../transport/mqtt/MqttTransportContext.java | 2 +- .../transport/mqtt/MqttTransportService.java | 4 +- .../AbstractGatewaySessionHandler.java | 2 +- .../session/SparkplugNodeSessionHandler.java | 2 +- .../snmp/service/SnmpTransportService.java | 4 +- .../common/transport/TransportContext.java | 4 +- .../config/ssl/SslCredentialsConfig.java | 2 +- .../service/DefaultTransportService.java | 4 +- common/util/pom.xml | 4 +- .../util/AbstractListeningExecutor.java | 4 +- common/version-control/pom.xml | 4 +- .../DefaultClusterVersionControlService.java | 4 +- .../sync/vc/DefaultGitRepositoryService.java | 2 +- dao/pom.xml | 8 +- .../server/dao/asset/AssetTypeFilter.java | 2 +- .../attributes/CachedAttributesService.java | 2 +- .../audit/sink/ElasticsearchAuditLogSink.java | 2 +- .../server/dao/edge/EdgeServiceImpl.java | 2 +- .../dao/entityview/EntityViewServiceImpl.java | 2 +- .../server/dao/model/BaseSqlEntity.java | 6 +- .../model/sql/AbstractAlarmCommentEntity.java | 13 +- .../dao/model/sql/AbstractAlarmEntity.java | 17 +- .../dao/model/sql/AbstractAssetEntity.java | 12 +- .../dao/model/sql/AbstractDeviceEntity.java | 22 +- .../dao/model/sql/AbstractEdgeEntity.java | 12 +- .../model/sql/AbstractEntityViewEntity.java | 17 +- .../dao/model/sql/AbstractTenantEntity.java | 12 +- .../dao/model/sql/AbstractTsKvEntity.java | 9 +- .../model/sql/AbstractWidgetTypeEntity.java | 4 +- .../dao/model/sql/AdminSettingsEntity.java | 16 +- .../dao/model/sql/AlarmCommentEntity.java | 11 +- .../server/dao/model/sql/AlarmEntity.java | 8 +- .../server/dao/model/sql/AlarmInfoEntity.java | 6 +- .../dao/model/sql/ApiUsageStateEntity.java | 13 +- .../server/dao/model/sql/AssetEntity.java | 8 +- .../dao/model/sql/AssetProfileEntity.java | 6 +- .../model/sql/AttributeKvCompositeKey.java | 8 +- .../dao/model/sql/AttributeKvEntity.java | 8 +- .../server/dao/model/sql/AuditLogEntity.java | 18 +- .../model/sql/ComponentDescriptorEntity.java | 19 +- .../server/dao/model/sql/CustomerEntity.java | 22 +- .../server/dao/model/sql/DashboardEntity.java | 16 +- .../dao/model/sql/DashboardInfoEntity.java | 9 +- .../model/sql/DeviceCredentialsEntity.java | 10 +- .../server/dao/model/sql/DeviceEntity.java | 13 +- .../dao/model/sql/DeviceInfoEntity.java | 6 +- .../dao/model/sql/DeviceProfileEntity.java | 21 +- .../server/dao/model/sql/EdgeEntity.java | 8 +- .../server/dao/model/sql/EdgeEventEntity.java | 20 +- .../model/sql/EntityAlarmCompositeKey.java | 2 +- .../dao/model/sql/EntityAlarmEntity.java | 10 +- .../dao/model/sql/EntityViewEntity.java | 8 +- .../dao/model/sql/ErrorEventEntity.java | 6 +- .../server/dao/model/sql/EventEntity.java | 6 +- .../dao/model/sql/LifecycleEventEntity.java | 6 +- .../dao/model/sql/NotificationEntity.java | 20 +- .../model/sql/NotificationRequestEntity.java | 24 +- .../dao/model/sql/NotificationRuleEntity.java | 25 +- .../model/sql/NotificationTargetEntity.java | 14 +- .../model/sql/NotificationTemplateEntity.java | 18 +- ...Auth2ClientRegistrationTemplateEntity.java | 20 +- .../dao/model/sql/OAuth2DomainEntity.java | 10 +- .../dao/model/sql/OAuth2MobileEntity.java | 6 +- .../dao/model/sql/OAuth2ParamsEntity.java | 6 +- .../model/sql/OAuth2RegistrationEntity.java | 18 +- .../dao/model/sql/OtaPackageEntity.java | 22 +- .../dao/model/sql/OtaPackageInfoEntity.java | 22 +- .../server/dao/model/sql/QueueEntity.java | 18 +- .../dao/model/sql/RelationCompositeKey.java | 2 +- .../server/dao/model/sql/RelationEntity.java | 20 +- .../server/dao/model/sql/RpcEntity.java | 22 +- .../model/sql/RuleChainDebugEventEntity.java | 6 +- .../server/dao/model/sql/RuleChainEntity.java | 20 +- .../model/sql/RuleNodeDebugEventEntity.java | 6 +- .../server/dao/model/sql/RuleNodeEntity.java | 16 +- .../dao/model/sql/RuleNodeStateEntity.java | 9 +- .../dao/model/sql/StatisticsEventEntity.java | 6 +- .../dao/model/sql/TbResourceEntity.java | 6 +- .../dao/model/sql/TbResourceInfoEntity.java | 6 +- .../server/dao/model/sql/TenantEntity.java | 8 +- .../dao/model/sql/TenantProfileEntity.java | 20 +- .../dao/model/sql/UserAuthSettingsEntity.java | 14 +- .../dao/model/sql/UserCredentialsEntity.java | 12 +- .../server/dao/model/sql/UserEntity.java | 18 +- .../dao/model/sql/UserSettingsEntity.java | 18 +- .../model/sql/WidgetTypeDetailsEntity.java | 15 +- .../dao/model/sql/WidgetTypeEntity.java | 15 +- .../dao/model/sql/WidgetsBundleEntity.java | 6 +- .../sqlts/dictionary/TsKvDictionary.java | 16 +- .../TsKvDictionaryCompositeKey.java | 2 +- .../sqlts/latest/TsKvLatestCompositeKey.java | 2 +- .../model/sqlts/latest/TsKvLatestEntity.java | 18 +- .../ts/TimescaleTsKvCompositeKey.java | 2 +- .../timescale/ts/TimescaleTsKvEntity.java | 19 +- .../dao/model/sqlts/ts/TsKvCompositeKey.java | 2 +- .../server/dao/model/sqlts/ts/TsKvEntity.java | 7 +- .../dao/nosql/CassandraAbstractAsyncDao.java | 6 +- .../CassandraBufferedRateReadExecutor.java | 2 +- .../CassandraBufferedRateWriteExecutor.java | 2 +- .../server/dao/oauth2/OAuth2ServiceImpl.java | 2 +- .../dao/relation/BaseRelationService.java | 4 +- .../dao/service/ConstraintValidator.java | 12 +- .../server/dao/service/NoXssValidator.java | 4 +- .../dao/service/StringLengthValidator.java | 4 +- .../sql/ScheduledLogExecutorComponent.java | 4 +- .../server/dao/sql/TbSqlBlockingQueue.java | 4 +- .../server/dao/sql/alarm/AlarmRepository.java | 88 ++++--- .../dao/sql/attributes/JpaAttributeDao.java | 12 +- .../dao/sql/audit/AuditLogRepository.java | 12 +- ...ctComponentDescriptorInsertRepository.java | 6 +- .../dao/sql/device/DeviceRepository.java | 2 +- .../dao/sql/edge/JpaBaseEdgeEventDao.java | 4 +- .../dao/sql/event/EventInsertRepository.java | 2 +- .../event/EventPartitionConfiguration.java | 2 +- .../server/dao/sql/event/JpaBaseEventDao.java | 4 +- .../server/dao/sql/query/QueryContext.java | 8 +- .../relation/SqlRelationInsertRepository.java | 6 +- ...stractChunkedAggregationTimeseriesDao.java | 4 +- .../dao/sqlts/AbstractSqlTimeseriesDao.java | 2 +- .../sqlts/BaseAbstractSqlTimeseriesDao.java | 10 +- .../dao/sqlts/SqlTimeseriesLatestDao.java | 4 +- .../latest/SearchTsKvLatestRepository.java | 4 +- .../timescale/AggregationRepository.java | 4 +- .../timescale/TimescaleTimeseriesDao.java | 4 +- .../server/dao/sqlts/ts/TsKvRepository.java | 60 ++--- .../AggregatePartitionsFunction.java | 2 +- .../CassandraBaseTimeseriesDao.java | 6 +- .../util/AbstractBufferedRateExecutor.java | 2 +- .../AbstractJsonSqlTypeDescriptor.java | 78 ------ .../mapping/JsonBinarySqlTypeDescriptor.java | 52 ---- .../dao/util/mapping/JsonBinaryType.java | 46 ---- .../dao/util/mapping/JsonConverter.java | 34 +++ .../mapping/JsonStringSqlTypeDescriptor.java | 61 ----- .../dao/util/mapping/JsonStringType.java | 48 ---- .../dao/util/mapping/JsonTypeDescriptor.java | 96 ------- .../impl/SlackNotificationChannel.java | 2 +- .../transport/TransportHealthChecker.java | 4 +- .../transport/TransportMonitoringService.java | 2 +- msa/monitoring/pom.xml | 2 +- netty-mqtt/pom.xml | 4 + .../thingsboard/mqtt/MqttClientConfig.java | 4 +- pom.xml | 114 ++++++--- rule-engine/rule-engine-api/pom.xml | 2 +- rule-engine/rule-engine-components/pom.xml | 10 +- .../TbCopyAttributesToEntityViewNode.java | 2 +- .../TbSaveToCustomCassandraTableNode.java | 2 +- .../engine/filter/TbCheckAlarmStatusNode.java | 3 +- .../TbNotificationNodeConfiguration.java | 4 +- .../TbSlackNodeConfiguration.java | 6 +- .../rule/engine/rest/TbHttpClient.java | 238 +++++++----------- .../rule/engine/rest/TbRestApiCallNode.java | 9 +- .../AttributesDeleteNodeCallback.java | 2 +- .../AttributesUpdateNodeCallback.java | 2 +- .../telemetry/TelemetryNodeCallback.java | 2 +- .../rule/engine/rest/TbHttpClientTest.java | 33 +-- .../engine/rest/TbRestApiCallNodeTest.java | 43 ++-- 376 files changed, 1261 insertions(+), 1739 deletions(-) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/mapping/AbstractJsonSqlTypeDescriptor.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinarySqlTypeDescriptor.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinaryType.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonConverter.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringSqlTypeDescriptor.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringType.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonTypeDescriptor.java diff --git a/application/pom.xml b/application/pom.xml index 8c3976eb31..1838c97c65 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -49,7 +49,6 @@ io.netty netty-transport-native-epoll - ${netty.version} linux-x86_64 @@ -212,7 +211,15 @@ com.sun.mail - javax.mail + jakarta.mail + + + jakarta.xml.bind + jakarta.xml.bind-api + + + javax.xml.bind + jaxb-api com.twilio.sdk diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index e0190bb388..437a18bbff 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -113,9 +113,9 @@ import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import org.thingsboard.server.service.transport.TbCoreToTransportService; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import java.io.IOException; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; + import java.io.PrintWriter; import java.io.StringWriter; import java.util.concurrent.ConcurrentHashMap; diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 934f309480..e9b10287b5 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -93,7 +93,7 @@ import org.thingsboard.server.service.rpc.RemoveRpcActorMsg; import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg; import org.thingsboard.server.service.transport.msg.TransportToDeviceActorMsgWrapper; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java index dd5bd4f1ed..3a78701d0b 100644 --- a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java +++ b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java @@ -35,8 +35,8 @@ import org.thingsboard.server.queue.discovery.TbApplicationEventListener; import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; import org.thingsboard.server.queue.util.AfterStartUp; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java index 4d227345b1..84789fc851 100644 --- a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java +++ b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.config; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.keygen.Base64StringKeyGenerator; @@ -42,7 +43,6 @@ import org.thingsboard.server.service.security.auth.oauth2.TbOAuth2ParameterName import org.thingsboard.server.service.security.model.token.OAuth2AppTokenFactory; import org.thingsboard.server.utils.MiscUtils; -import javax.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -113,7 +113,6 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza return request.getParameter("appToken"); } - @SuppressWarnings("deprecation") private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId, String redirectUriAction, String appPackage, String appToken) { if (registrationId == null) { return null; @@ -154,8 +153,6 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza addPkceParameters(attributes, additionalParameters); } builder.additionalParameters(additionalParameters); - } else if (AuthorizationGrantType.IMPLICIT.equals(clientRegistration.getAuthorizationGrantType())) { - builder = OAuth2AuthorizationRequest.implicit(); } else { throw new IllegalArgumentException("Invalid Authorization Grant Type (" + clientRegistration.getAuthorizationGrantType().getValue() + diff --git a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java index 0593b9765a..d18e999137 100644 --- a/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/config/RateLimitProcessingFilter.java @@ -33,11 +33,11 @@ import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.exception.ThingsboardErrorResponseHandler; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java index 4415f1a0bf..c7616ed865 100644 --- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java @@ -82,7 +82,7 @@ import static springfox.documentation.builders.PathSelectors.any; import static springfox.documentation.builders.PathSelectors.regex; @Slf4j -@Configuration +//@Configuration @TbCoreComponent @Profile("!test") public class SwaggerConfiguration { diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java index a418dc268b..052e1bb6ba 100644 --- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java @@ -26,10 +26,11 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; import org.springframework.security.config.annotation.ObjectPostProcessor; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver; @@ -60,7 +61,7 @@ import java.util.List; @Configuration @EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled=true) +@EnableMethodSecurity @Order(SecurityProperties.BASIC_AUTH_ORDER) @TbCoreComponent public class ThingsboardSecurityConfiguration { @@ -74,11 +75,12 @@ public class ThingsboardSecurityConfiguration { public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login"; public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public"; public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token"; - protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/assets/**", "/static/**", "/api/noauth/**", "/webjars/**", "/api/license/**"}; + protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[]{"/index.html", "/assets/**", "/static/**", "/api/noauth/**", "/webjars/**", "/api/license/**"}; public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**"; - @Autowired private ThingsboardErrorResponseHandler restAccessDeniedHandler; + @Autowired + private ThingsboardErrorResponseHandler restAccessDeniedHandler; @Autowired(required = false) @Qualifier("oauth2AuthenticationSuccessHandler") @@ -99,11 +101,15 @@ public class ThingsboardSecurityConfiguration { @Qualifier("defaultAuthenticationFailureHandler") private AuthenticationFailureHandler failureHandler; - @Autowired private RestAuthenticationProvider restAuthenticationProvider; - @Autowired private JwtAuthenticationProvider jwtAuthenticationProvider; - @Autowired private RefreshTokenAuthenticationProvider refreshTokenAuthenticationProvider; + @Autowired + private RestAuthenticationProvider restAuthenticationProvider; + @Autowired + private JwtAuthenticationProvider jwtAuthenticationProvider; + @Autowired + private RefreshTokenAuthenticationProvider refreshTokenAuthenticationProvider; - @Autowired(required = false) OAuth2Configuration oauth2Configuration; + @Autowired(required = false) + OAuth2Configuration oauth2Configuration; @Autowired @Qualifier("jwtHeaderTokenExtractor") @@ -113,9 +119,11 @@ public class ThingsboardSecurityConfiguration { @Qualifier("jwtQueryTokenExtractor") private TokenExtractor jwtQueryTokenExtractor; - @Autowired private AuthenticationManager authenticationManager; + @Autowired + private AuthenticationManager authenticationManager; - @Autowired private RateLimitProcessingFilter rateLimitProcessingFilter; + @Autowired + private RateLimitProcessingFilter rateLimitProcessingFilter; @Bean protected RestLoginProcessingFilter buildRestLoginProcessingFilter() throws Exception { @@ -180,35 +188,28 @@ public class ThingsboardSecurityConfiguration { @Bean public WebSecurityCustomizer webSecurityCustomizer() { - return (web) -> web.ignoring().antMatchers("/*.js","/*.css","/*.ico","/assets/**","/static/**"); + return (web) -> web.ignoring().requestMatchers("/*.js", "/*.css", "/*.ico", "/assets/**", "/static/**"); } @Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http.headers().cacheControl().and().frameOptions().disable() - .and() - .cors() - .and() - .csrf().disable() - .exceptionHandling() - .and() - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .authorizeRequests() - .antMatchers(WEBJARS_ENTRY_POINT).permitAll() // Webjars - .antMatchers(DEVICE_API_ENTRY_POINT).permitAll() // Device HTTP Transport API - .antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point - .antMatchers(PUBLIC_LOGIN_ENTRY_POINT).permitAll() // Public login end-point - .antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point - .antMatchers(NON_TOKEN_BASED_AUTH_ENTRY_POINTS).permitAll() // static resources, user activation and password reset end-points - .and() - .authorizeRequests() - .antMatchers(WS_TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected WebSocket API End-points - .antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected API End-points - .and() - .exceptionHandling().accessDeniedHandler(restAccessDeniedHandler) - .and() + http.headers(headers -> headers + .cacheControl(config -> {}) + .frameOptions(config -> {})) + .cors(cors -> {}) + .csrf(AbstractHttpConfigurer::disable) + .exceptionHandling(config -> {}) + .sessionManagement(config -> config.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeRequests(config -> config + .requestMatchers(WEBJARS_ENTRY_POINT).permitAll() // Webjars + .requestMatchers(DEVICE_API_ENTRY_POINT).permitAll() // Device HTTP Transport API + .requestMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point + .requestMatchers(PUBLIC_LOGIN_ENTRY_POINT).permitAll() // Public login end-point + .requestMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point + .requestMatchers(NON_TOKEN_BASED_AUTH_ENTRY_POINTS).permitAll() // static resources, user activation and password reset end-points + .requestMatchers(WS_TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected WebSocket API End-points + .requestMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()) // Protected API End-points + .exceptionHandling(config -> config.accessDeniedHandler(restAccessDeniedHandler)) .addFilterBefore(buildRestLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildRestPublicLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class) @@ -216,15 +217,14 @@ public class ThingsboardSecurityConfiguration { .addFilterBefore(buildWsJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterAfter(rateLimitProcessingFilter, UsernamePasswordAuthenticationFilter.class); if (oauth2Configuration != null) { - http.oauth2Login() - .authorizationEndpoint() - .authorizationRequestRepository(httpCookieOAuth2AuthorizationRequestRepository) - .authorizationRequestResolver(oAuth2AuthorizationRequestResolver) - .and() + http.oauth2Login(login -> login + .authorizationEndpoint(config -> config + .authorizationRequestRepository(httpCookieOAuth2AuthorizationRequestRepository) + .authorizationRequestResolver(oAuth2AuthorizationRequestResolver)) .loginPage("/oauth2Login") .loginProcessingUrl(oauth2Configuration.getLoginProcessingUrl()) .successHandler(oauth2AuthenticationSuccessHandler) - .failureHandler(oauth2AuthenticationFailureHandler); + .failureHandler(oauth2AuthenticationFailureHandler)); } return http.build(); } diff --git a/application/src/main/java/org/thingsboard/server/config/WebConfig.java b/application/src/main/java/org/thingsboard/server/config/WebConfig.java index 65396576c1..df57cf45f8 100644 --- a/application/src/main/java/org/thingsboard/server/config/WebConfig.java +++ b/application/src/main/java/org/thingsboard/server/config/WebConfig.java @@ -19,8 +19,8 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.thingsboard.server.utils.MiscUtils; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Controller diff --git a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java index 32797801c0..5f33eb951e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java @@ -45,7 +45,7 @@ import org.thingsboard.server.service.security.AccessValidator; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.Optional; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index f3a3a2397c..492296995c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -62,7 +62,7 @@ import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.system.SystemSecurityService; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.net.URI; import java.net.URISyntaxException; import java.util.concurrent.ConcurrentHashMap; diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 68a987a0bc..da2740a3b7 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -160,9 +160,9 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import javax.mail.MessagingException; -import javax.servlet.http.HttpServletResponse; -import javax.validation.ConstraintViolation; +import jakarta.mail.MessagingException; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.ConstraintViolation; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -390,7 +390,7 @@ public abstract class BaseController { } /** - * Handles validation error for controller method arguments annotated with @{@link javax.validation.Valid} + * Handles validation error for controller method arguments annotated with @{@link jakarta.validation.Valid} * */ @ExceptionHandler(MethodArgumentNotValidException.class) public void handleValidationError(MethodArgumentNotValidException validationError, HttpServletResponse response) { diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index bb34f6d5b2..9de6a66041 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -74,7 +74,7 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 9a021643cc..0213ae5686 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -64,7 +64,7 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java index 0f4a288e33..5893410b2a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java @@ -66,7 +66,7 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java index ccf2124113..06eabbc215 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java @@ -43,7 +43,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.UUID; import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END; diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java index a4c829796b..6b13e9de9d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java @@ -53,7 +53,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.Arrays; import java.util.List; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java index ab171efacf..fef919d710 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java @@ -48,7 +48,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.List; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java index ef5739a481..519629fbc3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java @@ -39,7 +39,7 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.utils.MiscUtils; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java index 464dc528a5..c611cfda54 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java @@ -49,7 +49,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rpc.RemoveRpcActorMsg; import org.thingsboard.server.service.security.permission.Operation; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.UUID; import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED; diff --git a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java index 3633cbbdeb..724cb59b73 100644 --- a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java +++ b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java @@ -41,7 +41,7 @@ import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import springfox.documentation.annotations.ApiIgnore; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 05f56e93bd..48864829ac 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -85,9 +85,9 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.telemetry.AttributeData; import org.thingsboard.server.service.telemetry.TsData; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; diff --git a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java index b07b1eb70b..a809f5280c 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java @@ -39,7 +39,7 @@ import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService; import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; diff --git a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java index 4a5bcb3d81..ee1db6868a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java @@ -44,7 +44,7 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.system.SystemSecurityService; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.Collections; import java.util.List; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index f79f5ee782..91434421d2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -75,7 +75,7 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.service.security.system.SystemSecurityService; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java index 7a396ff795..805d24e175 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java @@ -47,10 +47,10 @@ import org.thingsboard.server.service.ws.WebSocketService; import org.thingsboard.server.service.ws.WebSocketSessionRef; import org.thingsboard.server.service.ws.WebSocketSessionType; -import javax.websocket.RemoteEndpoint; -import javax.websocket.SendHandler; -import javax.websocket.SendResult; -import javax.websocket.Session; +import jakarta.websocket.RemoteEndpoint; +import jakarta.websocket.SendHandler; +import jakarta.websocket.SendResult; +import jakarta.websocket.Session; import java.io.IOException; import java.net.URI; import java.security.InvalidParameterException; diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java index ed641c2d4f..c037710e8b 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java @@ -16,9 +16,9 @@ package org.thingsboard.server.exception; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.lang.Nullable; @@ -43,9 +43,9 @@ import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedE import org.thingsboard.server.service.security.exception.JwtExpiredTokenException; import org.thingsboard.server.service.security.exception.UserPasswordExpiredException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -138,13 +138,13 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand @Override protected ResponseEntity handleExceptionInternal( Exception ex, @Nullable Object body, - HttpHeaders headers, HttpStatus status, + HttpHeaders headers, HttpStatusCode statusCode, WebRequest request) { - if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) { + if (HttpStatus.INTERNAL_SERVER_ERROR.equals(statusCode)) { request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST); } - ThingsboardErrorCode errorCode = statusToErrorCode(status); - return new ResponseEntity<>(ThingsboardErrorResponse.of(ex.getMessage(), errorCode, status), headers, status); + ThingsboardErrorCode errorCode = statusToErrorCode((HttpStatus) statusCode); + return new ResponseEntity<>(ThingsboardErrorResponse.of(ex.getMessage(), errorCode, (HttpStatus) statusCode), headers, statusCode); } private void handleThingsboardException(ThingsboardException thingsboardException, HttpServletResponse response) throws IOException { diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java index 9e17641c69..f0ee13ae69 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java @@ -68,8 +68,8 @@ import org.thingsboard.server.service.mail.MailExecutorService; import org.thingsboard.server.service.partition.AbstractPartitionBasedService; import org.thingsboard.server.service.telemetry.InternalTelemetryService; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/limits/DefaultRateLimitService.java b/application/src/main/java/org/thingsboard/server/service/apiusage/limits/DefaultRateLimitService.java index 9a0282c840..fac569110d 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/limits/DefaultRateLimitService.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/limits/DefaultRateLimitService.java @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.msg.tools.TbRateLimits; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.concurrent.TimeUnit; @Service diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index 1f5e41aeed..ab43208b85 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.dao.component.ComponentDescriptorService; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; diff --git a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java index ebc0fd0d24..a4ba2c8311 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java @@ -51,7 +51,7 @@ import org.thingsboard.server.dao.device.claim.ReclaimResult; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index 110760acbc..7c6267c4df 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -58,8 +58,8 @@ import org.thingsboard.server.service.edge.rpc.processor.user.UserEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.widget.WidgetBundleEdgeProcessor; import org.thingsboard.server.service.edge.rpc.processor.widget.WidgetTypeEdgeProcessor; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallService.java b/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallService.java index 2c4a14635d..344a4e6742 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/instructions/DefaultEdgeInstallService.java @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.install.InstallScripts; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallService.java b/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallService.java index 2a030fc4fa..52a9a5d820 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/instructions/EdgeInstallService.java @@ -19,7 +19,7 @@ import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.EdgeInstallInstructions; import org.thingsboard.server.common.data.id.TenantId; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; public interface EdgeInstallService { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index bda510a762..e0f6b3f6fc 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -52,9 +52,9 @@ import org.thingsboard.server.service.edge.EdgeContextComponent; import org.thingsboard.server.service.state.DefaultDeviceStateService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.io.IOException; import java.io.InputStream; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java index fece86b92a..4ed2e8f055 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java @@ -67,8 +67,8 @@ import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.service.edge.rpc.processor.BaseEdgeProcessor; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java index 48e6c4b634..e59340b99b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java @@ -49,7 +49,7 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java index c83c48cc8a..181e0b8b80 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/user/DefaultUserService.java @@ -32,7 +32,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.AbstractTbEntityService; import org.thingsboard.server.service.security.system.SystemSecurityService; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import static org.thingsboard.server.controller.UserController.ACTIVATE_URL_PATTERN; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java index 3ef79371d4..b5a5b83bfd 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/user/TbUserService.java @@ -20,7 +20,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; public interface TbUserService { User save(TenantId tenantId, CustomerId customerId, User tbUser, boolean sendActivationMail, HttpServletRequest request, User user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java b/application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java index 38b563472e..245387b70e 100644 --- a/application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java +++ b/application/src/main/java/org/thingsboard/server/service/executors/SharedEventLoopGroupService.java @@ -20,8 +20,8 @@ import io.netty.channel.nio.NioEventLoopGroup; import lombok.Getter; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.TimeUnit; @Component diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 497627f629..69cdebd55e 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -102,9 +102,9 @@ import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/install/TbRuleEngineQueueConfigService.java b/application/src/main/java/org/thingsboard/server/service/install/TbRuleEngineQueueConfigService.java index 455bd56309..36372650c1 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/TbRuleEngineQueueConfigService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/TbRuleEngineQueueConfigService.java @@ -24,7 +24,7 @@ import org.springframework.context.annotation.Profile; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.List; @Slf4j diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java index f3fd18141a..5fe876bb75 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.mail; import com.fasterxml.jackson.databind.JsonNode; import freemarker.template.Configuration; import freemarker.template.Template; +import jakarta.xml.bind.DatatypeConverter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -47,8 +48,8 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; -import javax.annotation.PostConstruct; -import javax.mail.internet.MimeMessage; +import jakarta.annotation.PostConstruct; +import jakarta.mail.internet.MimeMessage; import java.io.ByteArrayInputStream; import java.util.HashMap; import java.util.Locale; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java index 01591003ad..17dcfca40e 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java @@ -40,7 +40,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.executors.NotificationExecutorService; import org.thingsboard.server.service.partition.AbstractPartitionBasedService; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Collections; import java.util.HashSet; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java index 3e7f67e09b..913c9c9be3 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java @@ -53,7 +53,7 @@ import org.thingsboard.server.service.notification.rule.cache.NotificationRulesC import org.thingsboard.server.service.notification.rule.trigger.NotificationRuleTriggerProcessor; import org.thingsboard.server.service.notification.rule.trigger.RuleEngineMsgNotificationRuleTriggerProcessor; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.io.Serializable; import java.util.Collection; import java.util.EnumMap; diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java index a02b7bf1e4..bac51d3585 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java @@ -30,7 +30,7 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; import org.thingsboard.server.dao.notification.NotificationRuleService; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java b/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java index 6ab61426a8..a8d84bf63a 100644 --- a/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java @@ -51,7 +51,7 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.provider.TbCoreQueueFactory; import org.thingsboard.server.queue.provider.TbRuleEngineQueueFactory; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java index 2bd0043046..f9dbf695c3 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbCoreConsumerService.java @@ -89,8 +89,8 @@ import org.thingsboard.server.service.ws.notification.sub.NotificationRequestUpd import org.thingsboard.server.service.ws.notification.sub.NotificationUpdate; import org.thingsboard.server.service.ws.notification.sub.NotificationsSubscriptionUpdate; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.List; import java.util.Optional; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java index f8f6a7d25f..c47057b8dd 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/DefaultTbRuleEngineConsumerService.java @@ -64,8 +64,8 @@ import org.thingsboard.server.service.queue.processing.TbRuleEngineSubmitStrateg import org.thingsboard.server.service.rpc.TbRuleEngineDeviceRpcService; import org.thingsboard.server.service.stats.RuleEngineStatisticsService; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -107,7 +107,6 @@ public class DefaultTbRuleEngineConsumerService extends AbstractConsumerService< private final TbRuleEngineDeviceRpcService tbDeviceRpcService; private final TbServiceInfoProvider serviceInfoProvider; private final QueueService queueService; - // private final TenantId tenantId; private final ConcurrentMap>> consumers = new ConcurrentHashMap<>(); private final ConcurrentMap consumerConfigurations = new ConcurrentHashMap<>(); private final ConcurrentMap consumerStats = new ConcurrentHashMap<>(); diff --git a/application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java b/application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java index 2d517a2213..961d080aad 100644 --- a/application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java +++ b/application/src/main/java/org/thingsboard/server/service/queue/processing/AbstractConsumerService.java @@ -49,7 +49,7 @@ import org.thingsboard.server.service.queue.TbPackCallback; import org.thingsboard.server.service.queue.TbPackProcessingContext; import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.util.List; import java.util.Optional; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java index bca7c7d81a..2665c83884 100644 --- a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.rpc; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -38,8 +37,8 @@ import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java index 1fef6acbc0..3edd69bf0c 100644 --- a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbRuleEngineRpcService.java @@ -37,8 +37,8 @@ import org.thingsboard.server.queue.discovery.PartitionService; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.util.TbRuleEngineComponent; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; diff --git a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java index 9bb0a40a78..a3bdfc109e 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java +++ b/application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java @@ -81,9 +81,9 @@ import org.thingsboard.server.service.security.permission.AccessControlService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.BiConsumer; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java index 73cfe193e1..b380363e41 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java @@ -27,10 +27,10 @@ import org.thingsboard.server.service.security.auth.JwtAuthenticationToken; import org.thingsboard.server.service.security.auth.jwt.extractor.TokenExtractor; import org.thingsboard.server.service.security.model.token.RawAccessJwtToken; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; public class JwtTokenAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter { diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java index 66c206a7ad..c6d22b1478 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java @@ -30,10 +30,10 @@ import org.thingsboard.server.service.security.auth.RefreshAuthenticationToken; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.model.token.RawAccessJwtToken; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Slf4j diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java index b4c4843d1b..e3eca7217d 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java @@ -20,7 +20,7 @@ import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.Assert; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.List; import java.util.stream.Collectors; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java index 2f01decc73..22cf552ef5 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java @@ -20,7 +20,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.config.ThingsboardSecurityConfiguration; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @Component(value="jwtHeaderTokenExtractor") public class JwtHeaderTokenExtractor implements TokenExtractor { diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java index 7a458ef052..f58224fa6c 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtQueryTokenExtractor.java @@ -20,7 +20,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.config.ThingsboardSecurityConfiguration; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @Component(value="jwtQueryTokenExtractor") public class JwtQueryTokenExtractor implements TokenExtractor { diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/TokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/TokenExtractor.java index b1976dce9a..8d53395c57 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/TokenExtractor.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/TokenExtractor.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.service.security.auth.jwt.extractor; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; public interface TokenExtractor { - public String extract(HttpServletRequest request); + String extract(HttpServletRequest request); } \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java index 9bbb3643e3..2875ef4c09 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AppleOAuth2ClientMapper.java @@ -29,7 +29,7 @@ import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java index 91de70e35c..42a0e66171 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/BasicOAuth2ClientMapper.java @@ -24,7 +24,7 @@ import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.Map; @Service(value = "basicOAuth2ClientMapper") diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CookieUtils.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CookieUtils.java index 429e185b3e..f2692dc296 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CookieUtils.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CookieUtils.java @@ -17,9 +17,9 @@ package org.thingsboard.server.service.security.auth.oauth2; import org.springframework.util.SerializationUtils; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Base64; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java index 9cac9b87a0..739bbeda79 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java @@ -30,7 +30,7 @@ import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; @Service(value = "customOAuth2ClientMapper") @Slf4j diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/GithubOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/GithubOAuth2ClientMapper.java index 0381e64298..326e77403c 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/GithubOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/GithubOAuth2ClientMapper.java @@ -30,7 +30,7 @@ import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Map; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java index d63f759dd3..d52df7aec8 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java @@ -19,8 +19,8 @@ import org.springframework.security.oauth2.client.web.AuthorizationRequestReposi import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.stereotype.Component; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; @Component public class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository { @@ -48,9 +48,8 @@ public class HttpCookieOAuth2AuthorizationRequestRepository implements Authoriza CookieUtils.addCookie(response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME, CookieUtils.serialize(authorizationRequest), cookieExpireSeconds); } - @SuppressWarnings("deprecation") @Override - public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) { + public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { return this.loadAuthorizationRequest(request); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/OAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/OAuth2ClientMapper.java index 23befd67c8..5de5d216e7 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/OAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/OAuth2ClientMapper.java @@ -19,7 +19,7 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic import org.thingsboard.server.common.data.oauth2.OAuth2Registration; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; public interface OAuth2ClientMapper { SecurityUser getOrCreateUserByClientPrincipal(HttpServletRequest request, OAuth2AuthenticationToken token, String providerAccessToken, OAuth2Registration registration); diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationFailureHandler.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationFailureHandler.java index 4251c4bad4..5e416da302 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationFailureHandler.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationFailureHandler.java @@ -27,9 +27,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.system.SystemSecurityService; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationSuccessHandler.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationSuccessHandler.java index edfc826050..edbd96ec07 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationSuccessHandler.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/Oauth2AuthenticationSuccessHandler.java @@ -38,9 +38,9 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.system.SystemSecurityService; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetails.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetails.java index 1eafe66c8f..774fca5a48 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetails.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetails.java @@ -19,7 +19,7 @@ import lombok.Data; import ua_parser.Client; import ua_parser.Parser; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.Serializable; @Data diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetailsSource.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetailsSource.java index 36ce529e24..7d96c579ac 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetailsSource.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationDetailsSource.java @@ -17,7 +17,7 @@ package org.thingsboard.server.service.security.auth.rest; import org.springframework.security.authentication.AuthenticationDetailsSource; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; public class RestAuthenticationDetailsSource implements AuthenticationDetailsSource { diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationFailureHandler.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationFailureHandler.java index e5d20ac546..81529c62e2 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationFailureHandler.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationFailureHandler.java @@ -21,9 +21,9 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand import org.springframework.stereotype.Component; import org.thingsboard.server.exception.ThingsboardErrorResponseHandler; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Component(value = "defaultAuthenticationFailureHandler") diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java index 0229170781..25e1460438 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java @@ -30,10 +30,10 @@ import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManage import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.util.Optional; import java.util.concurrent.TimeUnit; diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java index b3ea3453b2..91ac6db711 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java @@ -31,10 +31,10 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.model.UserPrincipal; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Slf4j diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java index 23252c27ef..741055a8a2 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java @@ -30,10 +30,10 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.model.UserPrincipal; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @Slf4j diff --git a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java index 726a5d98f0..222db9d7c4 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java @@ -62,8 +62,8 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.utils.MiscUtils; import ua_parser.Client; -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/application/src/main/java/org/thingsboard/server/service/security/system/SystemSecurityService.java b/application/src/main/java/org/thingsboard/server/service/security/system/SystemSecurityService.java index 64550c438e..8c23fa6755 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/system/SystemSecurityService.java +++ b/application/src/main/java/org/thingsboard/server/service/security/system/SystemSecurityService.java @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettin import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; public interface SystemSecurityService { diff --git a/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java b/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java index ff1304208d..e21a8e5a79 100644 --- a/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java +++ b/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java @@ -34,10 +34,9 @@ import org.thingsboard.server.common.data.sms.config.TestSmsRequest; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; -import org.thingsboard.server.service.transport.DefaultTransportApiService; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; @Service @Slf4j diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index e33e501fbc..402be010ac 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -31,7 +31,6 @@ import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardExecutors; @@ -70,20 +69,18 @@ import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.dao.attributes.AttributesService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.sql.query.EntityQueryRepository; -import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.dao.util.DbTypeInfoComponent; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.discovery.PartitionService; -import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.partition.AbstractPartitionBasedService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/stats/DefaultJsInvokeStats.java b/application/src/main/java/org/thingsboard/server/service/stats/DefaultJsInvokeStats.java index bca8df431a..fcd1e5413f 100644 --- a/application/src/main/java/org/thingsboard/server/service/stats/DefaultJsInvokeStats.java +++ b/application/src/main/java/org/thingsboard/server/service/stats/DefaultJsInvokeStats.java @@ -22,7 +22,7 @@ import org.thingsboard.server.common.stats.StatsCounter; import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.common.stats.StatsType; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Service public class DefaultJsInvokeStats implements JsInvokeStats { diff --git a/application/src/main/java/org/thingsboard/server/service/stats/DefaultRuleEngineStatisticsService.java b/application/src/main/java/org/thingsboard/server/service/stats/DefaultRuleEngineStatisticsService.java index 1b5bfd56d1..50e35b8b28 100644 --- a/application/src/main/java/org/thingsboard/server/service/stats/DefaultRuleEngineStatisticsService.java +++ b/application/src/main/java/org/thingsboard/server/service/stats/DefaultRuleEngineStatisticsService.java @@ -32,7 +32,7 @@ import org.thingsboard.server.queue.util.TbRuleEngineComponent; import org.thingsboard.server.service.queue.TbRuleEngineConsumerStats; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java index 60fce13560..c3c050f73b 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java @@ -66,8 +66,8 @@ import org.thingsboard.server.service.ws.notification.sub.NotificationsSubscript import org.thingsboard.server.service.ws.telemetry.sub.AlarmSubscriptionUpdate; import org.thingsboard.server.service.ws.telemetry.sub.TelemetrySubscriptionUpdate; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.HashSet; import java.util.List; diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java index 4b37ba26b5..a70f0cba57 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java @@ -66,8 +66,8 @@ import org.thingsboard.server.service.ws.telemetry.cmd.v2.LatestValueCmd; import org.thingsboard.server.service.ws.telemetry.cmd.v2.TimeSeriesCmd; import org.thingsboard.server.service.ws.telemetry.cmd.v2.UnsubscribeCmd; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java index 64f1de8662..f8173d75e3 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java @@ -35,8 +35,8 @@ import org.thingsboard.server.service.ws.notification.sub.NotificationsSubscript import org.thingsboard.server.service.ws.telemetry.sub.AlarmSubscriptionUpdate; import org.thingsboard.server.service.ws.telemetry.sub.TelemetrySubscriptionUpdate; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Collections; import java.util.HashSet; import java.util.Map; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java index 45805c5939..87532fd587 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java @@ -59,9 +59,9 @@ import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; import org.thingsboard.server.utils.CsvUtils; import org.thingsboard.server.utils.TypeCastUtil; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java index a63600619a..075632774a 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/vc/DefaultEntitiesVersionControlService.java @@ -87,8 +87,8 @@ import org.thingsboard.server.service.sync.vc.data.ReimportTask; import org.thingsboard.server.service.sync.vc.data.SimpleEntitiesExportCtx; import org.thingsboard.server.service.sync.vc.repository.TbRepositorySettingsService; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.time.Instant; import java.util.ArrayList; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/system/DefaultSystemInfoService.java b/application/src/main/java/org/thingsboard/server/service/system/DefaultSystemInfoService.java index 80d4cede03..4b4a164856 100644 --- a/application/src/main/java/org/thingsboard/server/service/system/DefaultSystemInfoService.java +++ b/application/src/main/java/org/thingsboard/server/service/system/DefaultSystemInfoService.java @@ -48,8 +48,8 @@ import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import javax.annotation.Nullable; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/AbstractSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/AbstractSubscriptionService.java index 145f43fa3f..0e791c50c2 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/AbstractSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/AbstractSubscriptionService.java @@ -32,9 +32,9 @@ import org.thingsboard.server.queue.discovery.TbApplicationEventListener; import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; import org.thingsboard.server.service.subscription.SubscriptionManagerService; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java index 3f5e52796a..c2888f7487 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java @@ -48,9 +48,9 @@ import org.thingsboard.server.service.apiusage.TbApiUsageStateService; import org.thingsboard.server.service.entitiy.entityview.TbEntityViewService; import org.thingsboard.server.service.subscription.TbSubscriptionUtils; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java index a2afe6b433..4276d7b465 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/TbCoreTransportApiService.java @@ -34,8 +34,8 @@ import org.thingsboard.server.queue.provider.TbCoreQueueFactory; import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.ExecutorService; /** diff --git a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java index ef066a73f6..b7cf161853 100644 --- a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java @@ -33,7 +33,7 @@ import org.thingsboard.server.queue.notification.NotificationRuleProcessor; import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbCoreComponent; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; diff --git a/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java b/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java index 21d69d6b42..711a218f0e 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java @@ -81,9 +81,9 @@ import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityDataUpdate; import org.thingsboard.server.service.ws.telemetry.cmd.v2.UnsubscribeCmd; import org.thingsboard.server.service.ws.telemetry.sub.TelemetrySubscriptionUpdate; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; diff --git a/application/src/main/java/org/thingsboard/server/utils/MiscUtils.java b/application/src/main/java/org/thingsboard/server/utils/MiscUtils.java index 2fc0fa134c..efa642e8b1 100644 --- a/application/src/main/java/org/thingsboard/server/utils/MiscUtils.java +++ b/application/src/main/java/org/thingsboard/server/utils/MiscUtils.java @@ -18,7 +18,7 @@ package org.thingsboard.server.utils; import com.google.common.hash.HashFunction; import com.google.common.hash.Hashing; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.nio.charset.Charset; diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index f776887287..98635273b8 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -597,7 +597,7 @@ spring: enabled: "true" jpa: properties: - javax.persistence.query.timeout: "${JAVAX_PERSISTENCE_QUERY_TIMEOUT:30000}" + jakarta.persistence.query.timeout: "${JAVAX_PERSISTENCE_QUERY_TIMEOUT:30000}" open-in-view: "false" hibernate: ddl-auto: "none" diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java index 5809ab5e42..dbf7184bf6 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java @@ -21,7 +21,7 @@ import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootContextLoader; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; diff --git a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java index 15d5b5c809..b42e6f9733 100644 --- a/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java +++ b/application/src/test/java/org/thingsboard/server/edge/DeviceEdgeTest.java @@ -270,7 +270,7 @@ public class DeviceEdgeTest extends AbstractEdgeTest { (DefaultTenantProfileConfiguration) tenantProfile.getProfileData().getConfiguration(); profileConfiguration.setMaxDevices(1); tenantProfile.getProfileData().setConfiguration(profileConfiguration); - doPost("/api/tenantProfile/", tenantProfile, TenantProfile.class); + doPost("/api/tenantProfile", tenantProfile, TenantProfile.class); loginTenantAdmin(); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index 64382d5d51..7d2bc51ce6 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -30,7 +30,6 @@ import org.junit.Before; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.test.context.TestPropertySource; -import org.springframework.util.SocketUtils; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.Device; @@ -304,9 +303,12 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractTransportInte public void createNewClient(Security security, Configuration coapConfig, boolean isRpc, String endpoint, boolean isBootstrap, Security securityBs) throws Exception { this.clientDestroy(); lwM2MTestClient = new LwM2MTestClient(this.executor, endpoint); - int clientPort = SocketUtils.findAvailableUdpPort(); - lwM2MTestClient.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs, - securityBs, this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest); + + try (ServerSocket socket = new ServerSocket(0)) { + int clientPort = socket.getLocalPort(); + lwM2MTestClient.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs, + securityBs, this.defaultLwM2mUplinkMsgHandlerTest, this.clientContextTest); + } } private void clientDestroy() { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index 79b53bf15e..f041f0be55 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCred import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.nio.charset.StandardCharsets; import static org.eclipse.leshan.client.object.Security.psk; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java index c22a25a504..c75ecbd820 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCred import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.security.PrivateKey; import java.security.cert.X509Certificate; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java index e448a41f4b..1a908bffb8 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCre import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.security.PrivateKey; import java.security.cert.X509Certificate; diff --git a/common/cache/pom.xml b/common/cache/pom.xml index 440860fda6..a14c84d3f4 100644 --- a/common/cache/pom.xml +++ b/common/cache/pom.xml @@ -57,8 +57,8 @@ caffeine - javax.annotation - javax.annotation-api + jakarta.annotation + jakarta.annotation-api org.apache.commons diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/CacheSpecsMap.java b/common/cache/src/main/java/org/thingsboard/server/cache/CacheSpecsMap.java index bf3cc25a52..451d0e7c5d 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/CacheSpecsMap.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/CacheSpecsMap.java @@ -22,7 +22,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import org.thingsboard.server.common.data.CacheConstants; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Map; @Configuration diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/RedisTbTransactionalCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/RedisTbTransactionalCache.java index c5af954392..0332a25452 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/RedisTbTransactionalCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/RedisTbTransactionalCache.java @@ -27,6 +27,7 @@ import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.types.Expiration; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; +import redis.clients.jedis.Connection; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.util.JedisClusterCRC16; @@ -149,7 +150,7 @@ public abstract class RedisTbTransactionalCacheguava - javax.annotation - javax.annotation-api + jakarta.annotation + jakarta.annotation-api com.github.fge diff --git a/common/coap-server/src/main/java/org/thingsboard/server/coapserver/DefaultCoapServerService.java b/common/coap-server/src/main/java/org/thingsboard/server/coapserver/DefaultCoapServerService.java index 35e77ff584..afbd148c58 100644 --- a/common/coap-server/src/main/java/org/thingsboard/server/coapserver/DefaultCoapServerService.java +++ b/common/coap-server/src/main/java/org/thingsboard/server/coapserver/DefaultCoapServerService.java @@ -27,8 +27,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.thingsboard.common.util.ThingsBoardThreadFactory; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index 029c660500..6cfb7706a8 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -53,8 +53,8 @@ guava - javax.annotation - javax.annotation-api + jakarta.annotation + jakarta.annotation-api com.github.fge diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java index 293039a1d8..e20b4af7af 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java @@ -29,7 +29,7 @@ import org.thingsboard.server.dao.cassandra.guava.GuavaSession; import org.thingsboard.server.dao.cassandra.guava.GuavaSessionBuilder; import org.thingsboard.server.dao.cassandra.guava.GuavaSessionUtils; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.file.Paths; @Slf4j diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraCluster.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraCluster.java index c2438f258a..eab9108790 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraCluster.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraCluster.java @@ -19,7 +19,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.thingsboard.server.dao.util.NoSqlAnyDao; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Component("CassandraCluster") @NoSqlAnyDao diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java index 1b6524f8a9..9474fb574e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraDriverOptions.java @@ -29,7 +29,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.dao.util.NoSqlAnyDao; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraInstallCluster.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraInstallCluster.java index 13916ea48a..efa9fb7799 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraInstallCluster.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/CassandraInstallCluster.java @@ -19,7 +19,7 @@ import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; import org.thingsboard.server.dao.util.NoSqlAnyDao; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Component("CassandraInstallCluster") @NoSqlAnyDao diff --git a/common/data/pom.xml b/common/data/pom.xml index 3257d4cf32..68f7eb2393 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -37,8 +37,8 @@ - javax.validation - validation-api + jakarta.validation + jakarta.validation-api org.owasp.antisamy diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java index 3c791171d5..43927acd02 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.HashSet; import java.util.Objects; import java.util.Set; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index 7ff7d72023..7de86b86d3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java index 0f3dd5b636..1c71e66b87 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java @@ -27,8 +27,8 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Data @Builder diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java index 23edafd6d2..e97b40e1f1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java @@ -24,8 +24,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Data @Builder diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java index b771d591b1..a8b83a1cf6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java @@ -20,7 +20,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.io.Serializable; import java.util.List; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java index 00562ef677..7a44d707f9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.query.EntityKeyValueType; import org.thingsboard.server.common.data.query.KeyFilterPredicate; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.io.Serializable; @ApiModel diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java index 5302d42cad..0f23ae5624 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java @@ -21,7 +21,7 @@ import lombok.Data; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.io.Serializable; @ApiModel diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java index 24fff47fc2..96f365a152 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.io.Serializable; import java.util.List; import java.util.TreeMap; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java index 389b87f813..f6b2de915b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java @@ -19,7 +19,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.io.Serializable; import java.util.List; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java index eef43dd8b7..6e192ea473 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BaseAttributeKvEntry.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.kv; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.Optional; /** diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java index 3c612d3b78..a2e6bc0128 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/kv/BasicTsKvEntry.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.kv; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.Objects; import java.util.Optional; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java index 61d6982264..201fef7e0a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java @@ -33,8 +33,8 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import java.util.List; import java.util.UUID; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestConfig.java index 8bd9214f6b..b10d772c0b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequestConfig.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.notification; import lombok.Data; -import javax.validation.constraints.Max; +import jakarta.validation.constraints.Max; @Data public class NotificationRequestConfig { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/DefaultNotificationRuleRecipientsConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/DefaultNotificationRuleRecipientsConfig.java index 8c94ebf416..a37291f3ec 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/DefaultNotificationRuleRecipientsConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/DefaultNotificationRuleRecipientsConfig.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.notification.rule; import lombok.Data; import lombok.EqualsAndHashCode; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.List; import java.util.Map; import java.util.UUID; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/EscalatedNotificationRuleRecipientsConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/EscalatedNotificationRuleRecipientsConfig.java index c8858321de..c4899418ec 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/EscalatedNotificationRuleRecipientsConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/EscalatedNotificationRuleRecipientsConfig.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.notification.rule; import lombok.Data; import lombok.EqualsAndHashCode; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.List; import java.util.Map; import java.util.UUID; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java index 607ca7f639..a54a07f3ab 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRule.java @@ -30,10 +30,10 @@ import org.thingsboard.server.common.data.notification.rule.trigger.Notification import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; -import javax.validation.constraints.AssertTrue; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.AssertTrue; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.io.Serializable; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java index d31ec098ca..ed3a8c2cd6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/NotificationRuleRecipientsConfig.java @@ -23,7 +23,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.io.Serializable; import java.util.List; import java.util.Map; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentNotificationRuleTriggerConfig.java index 59ad9e5316..02a3bb8e23 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmAssignmentNotificationRuleTriggerConfig.java @@ -22,7 +22,7 @@ import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; import org.thingsboard.server.common.data.alarm.AlarmSeverity; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.Set; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java index 6118e9da00..3a2eeaadc7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/AlarmNotificationRuleTriggerConfig.java @@ -22,7 +22,7 @@ import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; import org.thingsboard.server.common.data.alarm.AlarmSeverity; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.io.Serializable; import java.util.Set; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityNotificationRuleTriggerConfig.java index 8deeada7c0..c0ce99e76d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/DeviceActivityNotificationRuleTriggerConfig.java @@ -20,7 +20,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.Set; import java.util.UUID; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitNotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitNotificationRuleTriggerConfig.java index a40ddfb081..8aeb715a11 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitNotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/EntitiesLimitNotificationRuleTriggerConfig.java @@ -21,7 +21,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.EntityType; -import javax.validation.constraints.Max; +import jakarta.validation.constraints.Max; import java.util.Set; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/NotificationSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/NotificationSettings.java index 4ed6cfc30d..86f5dee26a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/NotificationSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/NotificationSettings.java @@ -18,8 +18,8 @@ package org.thingsboard.server.common.data.notification.settings; import lombok.Data; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import java.io.Serializable; import java.util.Map; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/SlackNotificationDeliveryMethodConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/SlackNotificationDeliveryMethodConfig.java index 22a14c500c..98630482e4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/SlackNotificationDeliveryMethodConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/SlackNotificationDeliveryMethodConfig.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.notification.settings; import lombok.Data; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; @Data public class SlackNotificationDeliveryMethodConfig implements NotificationDeliveryMethodConfig { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/NotificationTarget.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/NotificationTarget.java index 9a2f9a5306..d49c2e893e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/NotificationTarget.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/NotificationTarget.java @@ -25,9 +25,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; @Data @EqualsAndHashCode(callSuper = true) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/CustomerUsersFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/CustomerUsersFilter.java index dd4c38b2a0..16d760c686 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/CustomerUsersFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/CustomerUsersFilter.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.notification.targets.platform; import lombok.Data; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotNull; import java.util.UUID; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/PlatformUsersNotificationTargetConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/PlatformUsersNotificationTargetConfig.java index d04411a194..7adb1aaebf 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/PlatformUsersNotificationTargetConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/PlatformUsersNotificationTargetConfig.java @@ -20,8 +20,8 @@ import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.notification.targets.NotificationTargetConfig; import org.thingsboard.server.common.data.notification.targets.NotificationTargetType; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Data @EqualsAndHashCode(callSuper = true) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/UserListFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/UserListFilter.java index d190000576..283dd78a97 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/UserListFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/platform/UserListFilter.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.notification.targets.platform; import lombok.Data; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.List; import java.util.UUID; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackConversation.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackConversation.java index ed9dee71b6..7e9d62e067 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackConversation.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackConversation.java @@ -24,8 +24,8 @@ import lombok.NoArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.thingsboard.server.common.data.notification.targets.NotificationRecipient; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import static org.apache.commons.lang3.StringUtils.isEmpty; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackNotificationTargetConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackNotificationTargetConfig.java index 5eb2b9a44f..6c55611904 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackNotificationTargetConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/targets/slack/SlackNotificationTargetConfig.java @@ -20,8 +20,8 @@ import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.notification.targets.NotificationTargetConfig; import org.thingsboard.server.common.data.notification.targets.NotificationTargetType; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; @Data @EqualsAndHashCode(callSuper = true) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java index ecb7f2d2b6..25f3bed1b9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java @@ -25,7 +25,7 @@ import lombok.NoArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "method") diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java index fe909a104e..ee9c1432e2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java @@ -24,7 +24,7 @@ import org.thingsboard.server.common.data.notification.NotificationDeliveryMetho import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; @Data @NoArgsConstructor diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplate.java index 71da2f862b..b0937b397a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplate.java @@ -26,9 +26,9 @@ import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; @Data @EqualsAndHashCode(callSuper = true) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java index 1dcb4aec0c..0797ecf164 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java @@ -18,8 +18,8 @@ package org.thingsboard.server.common.data.notification.template; import lombok.Data; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; import java.util.Map; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/WebDeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/WebDeliveryMethodNotificationTemplate.java index f26ed00568..cba325c064 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/WebDeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/WebDeliveryMethodNotificationTemplate.java @@ -28,7 +28,7 @@ import org.thingsboard.server.common.data.notification.NotificationDeliveryMetho import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.Optional; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java index 988af25d92..568664c01b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo; import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationTemplateId; import org.thingsboard.server.common.data.validation.Length; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.util.List; @EqualsAndHashCode(callSuper = true) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java index 0a149d90e2..89c8bcaa07 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java @@ -21,7 +21,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import javax.validation.Valid; +import jakarta.validation.Valid; @Builder(toBuilder = true) @EqualsAndHashCode diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/FilterPredicateValue.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/FilterPredicateValue.java index 28f401e22e..8f976459e3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/FilterPredicateValue.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/FilterPredicateValue.java @@ -22,7 +22,7 @@ import lombok.Data; import lombok.Getter; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.Valid; +import jakarta.validation.Valid; import java.io.Serializable; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java index 125ca4665a..e233e8291b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.query; import lombok.Data; -import javax.validation.Valid; +import jakarta.validation.Valid; @Data public class StringFilterPredicate implements SimpleKeyFilterPredicate { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java index 4f7cf4f545..7918813fa3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java @@ -20,10 +20,10 @@ import lombok.Data; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; -import javax.validation.Valid; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; +import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import java.util.List; import java.util.Optional; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/BackupCodeTwoFaAccountConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/BackupCodeTwoFaAccountConfig.java index 59ba4770b9..504bb12964 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/BackupCodeTwoFaAccountConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/BackupCodeTwoFaAccountConfig.java @@ -20,7 +20,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; -import javax.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotEmpty; import java.util.Set; @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/EmailTwoFaAccountConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/EmailTwoFaAccountConfig.java index 270f5f7298..590f314ecf 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/EmailTwoFaAccountConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/EmailTwoFaAccountConfig.java @@ -19,8 +19,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; -import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; @Data @EqualsAndHashCode(callSuper = true) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/SmsTwoFaAccountConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/SmsTwoFaAccountConfig.java index d1b739c378..dfbaa586af 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/SmsTwoFaAccountConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/SmsTwoFaAccountConfig.java @@ -19,8 +19,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; @EqualsAndHashCode(callSuper = true) @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/TotpTwoFaAccountConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/TotpTwoFaAccountConfig.java index 35c60bd540..60cd096ccb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/TotpTwoFaAccountConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/account/TotpTwoFaAccountConfig.java @@ -19,8 +19,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; @Data @EqualsAndHashCode(callSuper = true) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/BackupCodeTwoFaProviderConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/BackupCodeTwoFaProviderConfig.java index 36ac3150b5..a547a00f8d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/BackupCodeTwoFaProviderConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/BackupCodeTwoFaProviderConfig.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.security.model.mfa.provider; import lombok.Data; -import javax.validation.constraints.Min; +import jakarta.validation.constraints.Min; @Data public class BackupCodeTwoFaProviderConfig implements TwoFaProviderConfig { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/OtpBasedTwoFaProviderConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/OtpBasedTwoFaProviderConfig.java index f304b5858e..41d767b86f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/OtpBasedTwoFaProviderConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/OtpBasedTwoFaProviderConfig.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.security.model.mfa.provider; import lombok.Data; -import javax.validation.constraints.Min; +import jakarta.validation.constraints.Min; @Data public abstract class OtpBasedTwoFaProviderConfig implements TwoFaProviderConfig { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/SmsTwoFaProviderConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/SmsTwoFaProviderConfig.java index e5a9fb0f67..d7adfe7020 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/SmsTwoFaProviderConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/SmsTwoFaProviderConfig.java @@ -18,8 +18,8 @@ package org.thingsboard.server.common.data.security.model.mfa.provider; import lombok.Data; import lombok.EqualsAndHashCode; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Pattern; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; @EqualsAndHashCode(callSuper = true) @Data diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/TotpTwoFaProviderConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/TotpTwoFaProviderConfig.java index 70e4abc8a9..83fdc97d23 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/TotpTwoFaProviderConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/provider/TotpTwoFaProviderConfig.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.security.model.mfa.provider; import lombok.Data; -import javax.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; @Data public class TotpTwoFaProviderConfig implements TwoFaProviderConfig { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/validation/Length.java b/common/data/src/main/java/org/thingsboard/server/common/data/validation/Length.java index cb7b9b1693..a236f20037 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/validation/Length.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/validation/Length.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.common.data.validation; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/validation/NoXss.java b/common/data/src/main/java/org/thingsboard/server/common/data/validation/NoXss.java index fb7b048f7e..6b972ba112 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/validation/NoXss.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/validation/NoXss.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.common.data.validation; -import javax.validation.Constraint; -import javax.validation.Payload; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusQueueConfigs.java b/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusQueueConfigs.java index 5e404bc928..2fea26625d 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusQueueConfigs.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusQueueConfigs.java @@ -21,7 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; import org.thingsboard.server.queue.util.PropertyUtils; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Map; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/common/AbstractTbQueueConsumerTemplate.java b/common/queue/src/main/java/org/thingsboard/server/queue/common/AbstractTbQueueConsumerTemplate.java index 86146dabd1..003306c83a 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/common/AbstractTbQueueConsumerTemplate.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/common/AbstractTbQueueConsumerTemplate.java @@ -21,7 +21,7 @@ import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; import org.thingsboard.server.queue.TbQueueConsumer; import org.thingsboard.server.queue.TbQueueMsg; -import javax.annotation.Nonnull; +import jakarta.annotation.Nonnull; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java b/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java index 453183fc58..0b1988935b 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/common/DefaultTbQueueRequestTemplate.java @@ -33,7 +33,7 @@ import org.thingsboard.server.queue.TbQueueMsgMetadata; import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.TbQueueRequestTemplate; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java index 3c85aef350..2f69f79c4b 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/DefaultTbServiceInfoProvider.java @@ -28,7 +28,7 @@ import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.gen.transport.TransportProtos.ServiceInfo; import org.thingsboard.server.queue.util.AfterContextReady; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java index 08f2e849f8..d0b732ba71 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/HashPartitionService.java @@ -33,7 +33,7 @@ import org.thingsboard.server.queue.discovery.event.PartitionChangeEvent; import org.thingsboard.server.queue.discovery.event.ServiceListChangedEvent; import org.thingsboard.server.queue.util.AfterStartUp; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; @@ -379,7 +379,7 @@ public class HashPartitionService implements PartitionService { } } - private TenantId getIsolatedOrSystemTenantId(ServiceType serviceType, TenantId tenantId) { + protected TenantId getIsolatedOrSystemTenantId(ServiceType serviceType, TenantId tenantId) { return isIsolated(serviceType, tenantId) ? tenantId : TenantId.SYS_TENANT_ID; } diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java index fcf80bcf3d..3a8189aef8 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/discovery/ZkDiscoveryService.java @@ -40,8 +40,8 @@ import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.AfterStartUp; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.Executors; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/environment/EnvironmentLogService.java b/common/queue/src/main/java/org/thingsboard/server/queue/environment/EnvironmentLogService.java index 0a9e3a1ac0..77e52cedf6 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/environment/EnvironmentLogService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/environment/EnvironmentLogService.java @@ -20,7 +20,7 @@ import org.apache.zookeeper.Environment; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; /** * Created by igor on 11/24/16. diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java index 00f76ed50b..d15b29799a 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaConsumerStatsService.java @@ -35,8 +35,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.queue.discovery.PartitionService; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.time.Duration; import java.util.ArrayList; import java.util.List; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java index 9888066ee7..b688dfb045 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/kafka/TbKafkaTopicConfigs.java @@ -21,7 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import org.thingsboard.server.queue.util.PropertyUtils; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Map; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java index 08609b13d0..d1000c7580 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsMonolithQueueFactory.java @@ -54,7 +54,7 @@ import org.thingsboard.server.queue.sqs.TbAwsSqsProducerTemplate; import org.thingsboard.server.queue.sqs.TbAwsSqsQueueAttributes; import org.thingsboard.server.queue.sqs.TbAwsSqsSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java index 257ac37408..244ca4a985 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbCoreQueueFactory.java @@ -52,7 +52,7 @@ import org.thingsboard.server.queue.sqs.TbAwsSqsProducerTemplate; import org.thingsboard.server.queue.sqs.TbAwsSqsQueueAttributes; import org.thingsboard.server.queue.sqs.TbAwsSqsSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbRuleEngineQueueFactory.java index 9b1f9dba0d..0b66e93299 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbRuleEngineQueueFactory.java @@ -45,7 +45,7 @@ import org.thingsboard.server.queue.sqs.TbAwsSqsProducerTemplate; import org.thingsboard.server.queue.sqs.TbAwsSqsQueueAttributes; import org.thingsboard.server.queue.sqs.TbAwsSqsSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbVersionControlQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbVersionControlQueueFactory.java index 24453d3c5c..89fe2b0c6e 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbVersionControlQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTbVersionControlQueueFactory.java @@ -30,7 +30,7 @@ import org.thingsboard.server.queue.sqs.TbAwsSqsProducerTemplate; import org.thingsboard.server.queue.sqs.TbAwsSqsQueueAttributes; import org.thingsboard.server.queue.sqs.TbAwsSqsSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='aws-sqs' && '${service.type:null}'=='tb-vc-executor'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java index c1ae9fe855..aee2ff39dc 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/AwsSqsTransportQueueFactory.java @@ -41,7 +41,7 @@ import org.thingsboard.server.queue.sqs.TbAwsSqsProducerTemplate; import org.thingsboard.server.queue.sqs.TbAwsSqsQueueAttributes; import org.thingsboard.server.queue.sqs.TbAwsSqsSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='aws-sqs' && (('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport')") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java index 364abcff4c..86b7da5d31 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaMonolithQueueFactory.java @@ -54,7 +54,7 @@ import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicLong; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java index 9c25a5d420..edd092f3f0 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbCoreQueueFactory.java @@ -53,7 +53,7 @@ import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java index b8e07a45f7..a99e874310 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbRuleEngineQueueFactory.java @@ -49,7 +49,7 @@ import org.thingsboard.server.queue.settings.TbQueueRemoteJsInvokeSettings; import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; import java.util.concurrent.atomic.AtomicLong; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java index 51e3dc99c7..67e12568f9 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbTransportQueueFactory.java @@ -42,7 +42,7 @@ import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='kafka' && (('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport')") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbVersionControlQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbVersionControlQueueFactory.java index d851956420..ace91f0e74 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbVersionControlQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/KafkaTbVersionControlQueueFactory.java @@ -34,7 +34,7 @@ import org.thingsboard.server.queue.kafka.TbKafkaTopicConfigs; import org.thingsboard.server.queue.settings.TbQueueCoreSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='kafka' && '${service.type:null}'=='tb-vc-executor'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java index 857641098c..79d252c4e5 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubMonolithQueueFactory.java @@ -54,7 +54,7 @@ import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java index f197082829..16c0cba977 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbCoreQueueFactory.java @@ -51,7 +51,7 @@ import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbRuleEngineQueueFactory.java index 9766bf9915..5416a78699 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbRuleEngineQueueFactory.java @@ -48,7 +48,7 @@ import org.thingsboard.server.queue.settings.TbQueueRemoteJsInvokeSettings; import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbVersionControlQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbVersionControlQueueFactory.java index 57db7b884c..e0431a28aa 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbVersionControlQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTbVersionControlQueueFactory.java @@ -30,7 +30,7 @@ import org.thingsboard.server.queue.pubsub.TbPubSubSubscriptionSettings; import org.thingsboard.server.queue.settings.TbQueueCoreSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='pubsub' && '${service.type:null}'=='tb-vc-executor'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java index d5665e2fbe..9581e3833e 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/PubSubTransportQueueFactory.java @@ -41,7 +41,7 @@ import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='pubsub' && (('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport')") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java index 0318b5d06f..d4a3824f1d 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqMonolithQueueFactory.java @@ -54,7 +54,7 @@ import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java index 45f5a92980..362a118190 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbCoreQueueFactory.java @@ -51,7 +51,7 @@ import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbRuleEngineQueueFactory.java index 37633ced95..66ef4dfc36 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbRuleEngineQueueFactory.java @@ -48,7 +48,7 @@ import org.thingsboard.server.queue.settings.TbQueueRemoteJsInvokeSettings; import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbVersionControlQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbVersionControlQueueFactory.java index ed1da6a302..1d2ff91bb0 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbVersionControlQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTbVersionControlQueueFactory.java @@ -30,7 +30,7 @@ import org.thingsboard.server.queue.rabbitmq.TbRabbitMqSettings; import org.thingsboard.server.queue.settings.TbQueueCoreSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='rabbitmq' && '${service.type:null}'=='tb-vc-executor'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java index f11a877fc5..9bd84e63a2 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/RabbitMqTransportQueueFactory.java @@ -41,7 +41,7 @@ import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='rabbitmq' && (('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport')") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java index 950e49dc93..eacf4f4aa8 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusMonolithQueueFactory.java @@ -53,7 +53,7 @@ import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java index b92629633d..fc31678eb5 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbCoreQueueFactory.java @@ -51,7 +51,7 @@ import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbRuleEngineQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbRuleEngineQueueFactory.java index a1571becc7..71051e0df0 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbRuleEngineQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbRuleEngineQueueFactory.java @@ -48,7 +48,7 @@ import org.thingsboard.server.queue.settings.TbQueueRemoteJsInvokeSettings; import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.nio.charset.StandardCharsets; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbVersionControlQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbVersionControlQueueFactory.java index 24cb4fe8bc..b327d81f6f 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbVersionControlQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTbVersionControlQueueFactory.java @@ -30,7 +30,7 @@ import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.settings.TbQueueCoreSettings; import org.thingsboard.server.queue.settings.TbQueueVersionControlSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='service-bus' && '${service.type:null}'=='tb-vc-executor'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java index 15e661f5b0..2443bce7a3 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/ServiceBusTransportQueueFactory.java @@ -41,7 +41,7 @@ import org.thingsboard.server.queue.settings.TbQueueRuleEngineSettings; import org.thingsboard.server.queue.settings.TbQueueTransportApiSettings; import org.thingsboard.server.queue.settings.TbQueueTransportNotificationSettings; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; @Component @ConditionalOnExpression("'${queue.type:null}'=='service-bus' && (('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport')") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java index 71f79627cc..3890a5b8e7 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbCoreQueueProducerProvider.java @@ -27,7 +27,7 @@ import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; import org.thingsboard.server.queue.util.TbCoreComponent; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Service @TbCoreComponent diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java index 137b84a208..2769fbf4d2 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbRuleEngineProducerProvider.java @@ -27,7 +27,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceM import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Service @ConditionalOnExpression("'${service.type:null}'=='tb-rule-engine'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java index e9177d8b1c..3c5c63d740 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbTransportQueueProducerProvider.java @@ -27,7 +27,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceM import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Service @ConditionalOnExpression("'${service.type:null}'=='tb-transport'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbVersionControlProducerProvider.java b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbVersionControlProducerProvider.java index 77a27dedd8..bb5289350c 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbVersionControlProducerProvider.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/provider/TbVersionControlProducerProvider.java @@ -27,7 +27,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToUsageStatsServiceM import org.thingsboard.server.queue.TbQueueProducer; import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Service @ConditionalOnExpression("'${service.type:null}'=='tb-vc-executor'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java b/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java index fe9d85c306..7594cde20d 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSubscriptionSettings.java b/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSubscriptionSettings.java index 3d7ab85ecc..0288aa021c 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSubscriptionSettings.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSubscriptionSettings.java @@ -21,7 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; import org.thingsboard.server.queue.util.PropertyUtils; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.Map; @Component diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqQueueArguments.java b/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqQueueArguments.java index cb96abdf3c..ac03ca7da9 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqQueueArguments.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqQueueArguments.java @@ -21,7 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqSettings.java b/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqSettings.java index 0273374ddc..f8e8d59877 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqSettings.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/rabbitmq/TbRabbitMqSettings.java @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Slf4j @ConditionalOnExpression("'${queue.type:null}'=='rabbitmq'") diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/scheduler/DefaultSchedulerComponent.java b/common/queue/src/main/java/org/thingsboard/server/queue/scheduler/DefaultSchedulerComponent.java index 808e7c2c83..eaf90ead0f 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/scheduler/DefaultSchedulerComponent.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/scheduler/DefaultSchedulerComponent.java @@ -18,8 +18,8 @@ package org.thingsboard.server.queue.scheduler; import org.springframework.stereotype.Component; import org.thingsboard.common.util.ThingsBoardThreadFactory; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsQueueAttributes.java b/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsQueueAttributes.java index 66110ade74..b1c033ed29 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsQueueAttributes.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/sqs/TbAwsSqsQueueAttributes.java @@ -22,7 +22,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.StringUtils; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageReportClient.java b/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageReportClient.java index 8a5857e6a7..e56c9e25c5 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageReportClient.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageReportClient.java @@ -37,7 +37,7 @@ import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.scheduler.SchedulerComponent; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.EnumMap; import java.util.Random; import java.util.UUID; diff --git a/common/script/remote-js-client/src/main/java/org/thingsboard/server/service/script/RemoteJsInvokeService.java b/common/script/remote-js-client/src/main/java/org/thingsboard/server/service/script/RemoteJsInvokeService.java index dc4068edcc..63977d6fab 100644 --- a/common/script/remote-js-client/src/main/java/org/thingsboard/server/service/script/RemoteJsInvokeService.java +++ b/common/script/remote-js-client/src/main/java/org/thingsboard/server/service/script/RemoteJsInvokeService.java @@ -37,8 +37,8 @@ import org.thingsboard.server.queue.TbQueueRequestTemplate; import org.thingsboard.server.queue.common.TbProtoJsQueueMsg; import org.thingsboard.server.queue.common.TbProtoQueueMsg; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Map; import java.util.Optional; import java.util.UUID; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java index 42131c9dc3..9b449f63e3 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/ScriptStatCallback.java @@ -19,7 +19,7 @@ import com.google.common.util.concurrent.FutureCallback; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java index 9e3ae3c032..18f9a63e76 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/js/NashornJsInvokeService.java @@ -31,8 +31,8 @@ import org.thingsboard.script.api.TbScriptException; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.common.stats.TbApiUsageStateClient; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java index f98e33b615..8b0274c81d 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/DefaultTbelInvokeService.java @@ -43,8 +43,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.common.stats.TbApiUsageStateClient; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.Calendar; diff --git a/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java b/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java index 6f5c7eb752..97e5d38f1e 100644 --- a/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java +++ b/common/stats/src/main/java/org/thingsboard/server/common/stats/DefaultStatsFactory.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.StringUtils; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.concurrent.atomic.AtomicInteger; @Service diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java index 8ad2d01e47..ff20d95d5e 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java @@ -27,8 +27,8 @@ import org.thingsboard.server.common.data.TbTransportService; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.net.UnknownHostException; @Service("CoapTransportService") diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index 041ae0510d..4cc876a122 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -64,7 +64,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcRequestMs import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; -import javax.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; import java.util.UUID; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java index 209478f4ff..75a2f936ca 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapService.java @@ -33,8 +33,8 @@ import org.thingsboard.server.transport.lwm2m.bootstrap.store.LwM2MInMemoryBoots import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.security.cert.X509Certificate; import static java.util.concurrent.TimeUnit.MILLISECONDS; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/TbLwM2MDtlsBootstrapCertificateVerifier.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/TbLwM2MDtlsBootstrapCertificateVerifier.java index 5f215e51a0..cd5f62eb28 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/TbLwM2MDtlsBootstrapCertificateVerifier.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/TbLwM2MDtlsBootstrapCertificateVerifier.java @@ -41,7 +41,7 @@ import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import javax.security.auth.x500.X500Principal; import java.net.InetSocketAddress; import java.security.PublicKey; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MDtlsCertificateVerifier.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MDtlsCertificateVerifier.java index a412d1c918..aa3942f508 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MDtlsCertificateVerifier.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MDtlsCertificateVerifier.java @@ -47,7 +47,7 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; import org.thingsboard.server.transport.lwm2m.server.store.TbMainSecurityStore; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import javax.security.auth.x500.X500Principal; import java.net.InetSocketAddress; import java.security.PublicKey; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java index 3eb096cd38..5fb36f6f55 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java @@ -39,7 +39,7 @@ import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore; import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.security.cert.X509Certificate; import static java.util.concurrent.TimeUnit.MILLISECONDS; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java index 8c65c04939..2f0876157d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java @@ -33,8 +33,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java index de960ea436..09ecf500b6 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java @@ -75,8 +75,8 @@ import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogServic import org.thingsboard.server.transport.lwm2m.server.rpc.composite.RpcWriteCompositeRequest; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Arrays; import java.util.Collection; import java.util.Date; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java index 302bd20c8b..39938d9e53 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/model/LwM2MModelConfigServiceImpl.java @@ -38,7 +38,7 @@ import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogServic import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MModelConfigStore; import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.util.List; import java.util.Map; import java.util.Set; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java index f59643cbeb..4e43d7b653 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java @@ -57,8 +57,8 @@ import org.thingsboard.server.transport.lwm2m.server.ota.software.SoftwareUpdate import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MClientOtaInfoStore; import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java index f8ff5c70a0..4369f5f532 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2mUplinkMsgHandler.java @@ -100,8 +100,8 @@ import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore; import org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java index 51dc2bc55b..13d9115941 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java @@ -27,7 +27,7 @@ import org.thingsboard.server.common.transport.TransportContext; import org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor; import org.thingsboard.server.transport.mqtt.adaptors.ProtoMqttAdaptor; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.net.InetSocketAddress; import java.util.concurrent.atomic.AtomicInteger; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportService.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportService.java index e953f64b87..c658052467 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportService.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportService.java @@ -31,8 +31,8 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.TbTransportService; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.net.InetSocketAddress; /** diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java index 95603e751c..03ee4fcdc9 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/AbstractGatewaySessionHandler.java @@ -56,7 +56,7 @@ import org.thingsboard.server.transport.mqtt.adaptors.ProtoMqttAdaptor; import org.thingsboard.server.transport.mqtt.util.ReturnCode; import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugConnectionState; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.Date; diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java index 48998d58cd..626a658556 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/SparkplugNodeSessionHandler.java @@ -43,7 +43,7 @@ import org.thingsboard.server.transport.mqtt.MqttTransportHandler; import org.thingsboard.server.transport.mqtt.util.sparkplug.MetricDataType; import org.thingsboard.server.transport.mqtt.util.sparkplug.SparkplugTopic; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java index 6e68a0bd44..577f089f2e 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/service/SnmpTransportService.java @@ -51,8 +51,8 @@ import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.queue.util.TbSnmpTransportComponent; import org.thingsboard.server.transport.snmp.session.DeviceSessionContext; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.io.IOException; import java.util.Arrays; import java.util.Collections; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java index b0e7a527aa..e428b03e0c 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportContext.java @@ -26,8 +26,8 @@ import org.thingsboard.server.common.transport.limits.TransportRateLimitService; import org.thingsboard.server.queue.discovery.TbServiceInfoProvider; import org.thingsboard.server.queue.scheduler.SchedulerComponent; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.ExecutorService; /** diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/config/ssl/SslCredentialsConfig.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/config/ssl/SslCredentialsConfig.java index 7304d6a5c6..a3dd52c62d 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/config/ssl/SslCredentialsConfig.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/config/ssl/SslCredentialsConfig.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.transport.config.ssl; import lombok.Data; import lombok.extern.slf4j.Slf4j; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; @Slf4j @Data diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index b495448d90..8c397bd2d4 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -99,8 +99,8 @@ import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.queue.util.TbTransportComponent; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; diff --git a/common/util/pom.xml b/common/util/pom.xml index 14ae1748b2..59669b11fd 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -46,8 +46,8 @@ provided - javax.annotation - javax.annotation-api + jakarta.annotation + jakarta.annotation-api com.fasterxml.jackson.core diff --git a/common/util/src/main/java/org/thingsboard/common/util/AbstractListeningExecutor.java b/common/util/src/main/java/org/thingsboard/common/util/AbstractListeningExecutor.java index a0b88df49e..d9814336e4 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/AbstractListeningExecutor.java +++ b/common/util/src/main/java/org/thingsboard/common/util/AbstractListeningExecutor.java @@ -19,8 +19,8 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.Callable; /** diff --git a/common/version-control/pom.xml b/common/version-control/pom.xml index a8acdf2be9..370ecc24a9 100644 --- a/common/version-control/pom.xml +++ b/common/version-control/pom.xml @@ -62,8 +62,8 @@ provided - javax.annotation - javax.annotation-api + jakarta.annotation + jakarta.annotation-api com.google.guava diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java index 618eb11d98..2c8a902a8a 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultClusterVersionControlService.java @@ -76,8 +76,8 @@ import org.thingsboard.server.queue.provider.TbVersionControlQueueFactory; import org.thingsboard.server.queue.util.DataDecodingEncodingService; import org.thingsboard.server.queue.util.TbVersionControlComponent; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java index 1905c50ba4..d6722fd5ed 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/DefaultGitRepositoryService.java @@ -36,7 +36,7 @@ import org.thingsboard.server.common.data.sync.vc.VersionCreationResult; import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo; import org.thingsboard.server.service.sync.vc.GitRepository.Diff; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; diff --git a/dao/pom.xml b/dao/pom.xml index 4d4dd2a30b..36526567de 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -122,7 +122,7 @@ org.glassfish - javax.el + jakarta.el org.springframework @@ -149,6 +149,12 @@ com.datastax.oss java-driver-query-builder + + io.netty + netty-transport-native-epoll + linux-x86_64 + test + io.dropwizard.metrics metrics-jmx diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetTypeFilter.java b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetTypeFilter.java index ce07d27f7d..2525387357 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/AssetTypeFilter.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/AssetTypeFilter.java @@ -17,7 +17,7 @@ package org.thingsboard.server.dao.asset; import lombok.Data; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.List; /** diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java index b95ce39d9a..555975434a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java @@ -37,7 +37,7 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.cache.CacheExecutorService; import org.thingsboard.server.dao.service.Validator; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java b/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java index 6ba72a377a..ea0213240d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java +++ b/dao/src/main/java/org/thingsboard/server/dao/audit/sink/ElasticsearchAuditLogSink.java @@ -38,7 +38,7 @@ import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.audit.AuditLog; import org.thingsboard.server.common.data.id.TenantId; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Collections; diff --git a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java index 31b446fbd5..36ae061a1d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java @@ -61,7 +61,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.service.Validator; import org.thingsboard.server.dao.user.UserService; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java index 6433db5ae8..59caf26638 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java @@ -48,7 +48,7 @@ import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.sql.JpaExecutorService; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/BaseSqlEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/BaseSqlEntity.java index 916c459a6b..435b10779f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/BaseSqlEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/BaseSqlEntity.java @@ -23,9 +23,9 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UUIDBased; -import javax.persistence.Column; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; +import jakarta.persistence.Column; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmCommentEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmCommentEntity.java index 773156adb1..7c19e40141 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmCommentEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmCommentEntity.java @@ -16,10 +16,11 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.MappedSuperclass; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmCommentType; import org.thingsboard.server.common.data.id.AlarmCommentId; @@ -28,10 +29,8 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_ALARM_ID; @@ -40,7 +39,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_TYPE @Data @EqualsAndHashCode(callSuper = true) -@TypeDef(name = "json", typeClass = JsonStringType.class) @MappedSuperclass public abstract class AbstractAlarmCommentEntity extends BaseSqlEntity implements BaseEntity { @@ -53,7 +51,7 @@ public abstract class AbstractAlarmCommentEntity extends @Column(name = ALARM_COMMENT_TYPE) private AlarmCommentType type; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ALARM_COMMENT_COMMENT) private JsonNode comment; @@ -84,6 +82,7 @@ public abstract class AbstractAlarmCommentEntity extends this.type = alarmCommentEntity.getType(); this.comment = alarmCommentEntity.getComment(); } + protected AlarmComment toAlarmComment() { AlarmComment alarmComment = new AlarmComment(new AlarmCommentId(id)); alarmComment.setCreatedTime(createdTime); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java index 164e1518a1..f11faa6210 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAlarmEntity.java @@ -16,10 +16,13 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.MappedSuperclass; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.springframework.util.CollectionUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; @@ -33,12 +36,8 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.MappedSuperclass; import java.util.Arrays; import java.util.Collections; import java.util.UUID; @@ -64,7 +63,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.ALARM_TYPE_PROPERT @Data @EqualsAndHashCode(callSuper = true) -@TypeDef(name = "json", typeClass = JsonStringType.class) @MappedSuperclass public abstract class AbstractAlarmEntity extends BaseSqlEntity implements BaseEntity { @@ -87,7 +85,6 @@ public abstract class AbstractAlarmEntity extends BaseSqlEntity @Column(name = ALARM_SEVERITY_PROPERTY) private AlarmSeverity severity; - @Type(type="pg-uuid") @Column(name = ALARM_ASSIGNEE_ID_PROPERTY) private UUID assigneeId; @@ -112,7 +109,7 @@ public abstract class AbstractAlarmEntity extends BaseSqlEntity @Column(name = ALARM_ASSIGN_TS_PROPERTY) private Long assignTs; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.ALARM_DETAILS_PROPERTY) private JsonNode details; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAssetEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAssetEntity.java index 3b7abed70d..aa11045759 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAssetEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractAssetEntity.java @@ -16,10 +16,11 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.MappedSuperclass; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.AssetProfileId; @@ -28,10 +29,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_PROPERTY; @@ -44,7 +43,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPER @Data @EqualsAndHashCode(callSuper = true) -@TypeDef(name = "json", typeClass = JsonStringType.class) @MappedSuperclass public abstract class AbstractAssetEntity extends BaseSqlEntity implements SearchTextEntity { @@ -66,7 +64,7 @@ public abstract class AbstractAssetEntity extends BaseSqlEntity @Column(name = SEARCH_TEXT_PROPERTY) private String searchText; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java index 403cb04aef..237fae77b3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractDeviceEntity.java @@ -17,11 +17,13 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.MappedSuperclass; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; -import org.hibernate.annotations.TypeDefs; +import org.hibernate.annotations.JdbcType; +import org.hibernate.dialect.PostgreSQLJsonPGObjectJsonbType; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.device.data.DeviceData; @@ -33,19 +35,12 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonBinaryType; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) -@TypeDefs({ - @TypeDef(name = "json", typeClass = JsonStringType.class), - @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) -}) @MappedSuperclass public abstract class AbstractDeviceEntity extends BaseSqlEntity implements SearchTextEntity { @@ -67,7 +62,7 @@ public abstract class AbstractDeviceEntity extends BaseSqlEnti @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) private String searchText; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; @@ -80,7 +75,8 @@ public abstract class AbstractDeviceEntity extends BaseSqlEnti @Column(name = ModelConstants.DEVICE_SOFTWARE_ID_PROPERTY, columnDefinition = "uuid") private UUID softwareId; - @Type(type = "jsonb") + @Convert(converter = JsonConverter.class) + @JdbcType(PostgreSQLJsonPGObjectJsonbType.class) @Column(name = ModelConstants.DEVICE_DEVICE_DATA_PROPERTY, columnDefinition = "jsonb") private JsonNode deviceData; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEdgeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEdgeEntity.java index f5a7423df9..0e5da92ecc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEdgeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEdgeEntity.java @@ -16,10 +16,11 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.MappedSuperclass; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; @@ -28,10 +29,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY; @@ -46,7 +45,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPER @Data @EqualsAndHashCode(callSuper = true) -@TypeDef(name = "json", typeClass = JsonStringType.class) @MappedSuperclass public abstract class AbstractEdgeEntity extends BaseSqlEntity implements SearchTextEntity { @@ -77,7 +75,7 @@ public abstract class AbstractEdgeEntity extends BaseSqlEntity extends BaseSqlEntity implements SearchTextEntity { @@ -85,7 +82,7 @@ public abstract class AbstractEntityViewEntity extends Bas @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) private String searchText; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java index 39dca43d29..d122de2b15 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTenantEntity.java @@ -16,25 +16,23 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.MappedSuperclass; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) -@TypeDef(name = "json", typeClass = JsonStringType.class) @MappedSuperclass public abstract class AbstractTenantEntity extends BaseSqlEntity implements SearchTextEntity { @@ -71,7 +69,7 @@ public abstract class AbstractTenantEntity extends BaseSqlEnti @Column(name = ModelConstants.EMAIL_PROPERTY) private String email; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.TENANT_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTsKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTsKvEntity.java index 6d3378c0c7..0b9a3aaebe 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTsKvEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractTsKvEntity.java @@ -15,6 +15,10 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Column; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; +import jakarta.persistence.Transient; import lombok.Data; import org.thingsboard.server.common.data.kv.AggTsKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; @@ -27,10 +31,6 @@ import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.dao.model.ToData; -import javax.persistence.Column; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; -import javax.persistence.Transient; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.BOOLEAN_VALUE_COLUMN; @@ -59,7 +59,6 @@ public abstract class AbstractTsKvEntity implements ToData { @Column(name = KEY_COLUMN) protected int key; - @Id @Column(name = TS_COLUMN) protected Long ts; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractWidgetTypeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractWidgetTypeEntity.java index 127e8509b7..626f158829 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractWidgetTypeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractWidgetTypeEntity.java @@ -24,8 +24,8 @@ import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import javax.persistence.Column; -import javax.persistence.MappedSuperclass; +import jakarta.persistence.Column; +import jakarta.persistence.MappedSuperclass; import java.util.UUID; @Data diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java index 7f61fb0fe6..52a505a035 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AdminSettingsEntity.java @@ -16,31 +16,29 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.id.AdminSettingsId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; import java.util.UUID; -import static org.thingsboard.server.dao.model.ModelConstants.ADMIN_SETTINGS_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.ADMIN_SETTINGS_JSON_VALUE_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.ADMIN_SETTINGS_KEY_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.ADMIN_SETTINGS_TABLE_NAME; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ADMIN_SETTINGS_TABLE_NAME) public final class AdminSettingsEntity extends BaseSqlEntity implements BaseEntity { @@ -50,7 +48,7 @@ public final class AdminSettingsEntity extends BaseSqlEntity impl @Column(name = ADMIN_SETTINGS_KEY_PROPERTY) private String key; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ADMIN_SETTINGS_JSON_VALUE_PROPERTY) private JsonNode jsonValue; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentEntity.java index 7baa81755f..444229672d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmCommentEntity.java @@ -15,25 +15,20 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.alarm.AlarmComment; import org.thingsboard.server.common.data.alarm.AlarmCommentInfo; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Entity; -import javax.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_COMMENT_TABLE_NAME; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ALARM_COMMENT_TABLE_NAME) - -public class AlarmCommentEntity extends AbstractAlarmCommentEntity { +public class AlarmCommentEntity extends AbstractAlarmCommentEntity { public AlarmCommentEntity() { super(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java index 19d1040656..beb2849a92 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmEntity.java @@ -15,22 +15,18 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmInfo; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Entity; -import javax.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_TABLE_NAME; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ALARM_TABLE_NAME) public final class AlarmEntity extends AbstractAlarmEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmInfoEntity.java index db55756060..e87e4d8257 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AlarmInfoEntity.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.alarm.AlarmAssignee; import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.id.UserId; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ASSIGNEE_EMAIL_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.ALARM_ASSIGNEE_FIRST_NAME_PROPERTY; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java index b18f414c63..298ddcac81 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ApiUsageStateEntity.java @@ -15,9 +15,13 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.ApiUsageState; import org.thingsboard.server.common.data.ApiUsageStateValue; import org.thingsboard.server.common.data.id.ApiUsageStateId; @@ -26,13 +30,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; /** @@ -41,7 +39,6 @@ import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.API_USAGE_STATE_TABLE_NAME) public class ApiUsageStateEntity extends BaseSqlEntity implements BaseEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java index c30a572068..bb551ffbda 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java @@ -15,21 +15,17 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.asset.Asset; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Entity; -import javax.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TABLE_NAME; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ASSET_TABLE_NAME) public final class AssetEntity extends AbstractAssetEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetProfileEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetProfileEntity.java index 1deb1e5c7b..a276047796 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetProfileEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetProfileEntity.java @@ -26,9 +26,9 @@ import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import java.util.UUID; @Data diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java index 745e5893f2..936a18eeeb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java @@ -15,15 +15,15 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.EntityType; -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; import java.io.Serializable; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java index b39384eb5a..bc97c0394f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java @@ -26,10 +26,10 @@ import org.thingsboard.server.common.data.kv.LongDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.dao.model.ToData; -import javax.persistence.Column; -import javax.persistence.EmbeddedId; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.EmbeddedId; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import java.io.Serializable; import static org.thingsboard.server.dao.model.ModelConstants.BOOLEAN_VALUE_COLUMN; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AuditLogEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AuditLogEntity.java index 86df16872c..21ef4e09a0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AuditLogEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AuditLogEntity.java @@ -16,10 +16,14 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.audit.ActionStatus; import org.thingsboard.server.common.data.audit.ActionType; @@ -32,13 +36,8 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.AUDIT_LOG_ACTION_DATA_PROPERTY; @@ -56,7 +55,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.AUDIT_LOG_USER_NAM @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.AUDIT_LOG_TABLE_NAME) public class AuditLogEntity extends BaseSqlEntity implements BaseEntity { @@ -86,7 +84,7 @@ public class AuditLogEntity extends BaseSqlEntity implements BaseEntit @Column(name = AUDIT_LOG_ACTION_TYPE_PROPERTY) private ActionType actionType; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = AUDIT_LOG_ACTION_DATA_PROPERTY) private JsonNode actionData; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java index 09cabb72f1..ca12c0a112 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ComponentDescriptorEntity.java @@ -16,10 +16,14 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.ComponentDescriptorId; import org.thingsboard.server.common.data.plugin.ComponentClusteringMode; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; @@ -28,18 +32,11 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; +import org.thingsboard.server.dao.util.mapping.JsonConverter; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.COMPONENT_DESCRIPTOR_TABLE_NAME) public class ComponentDescriptorEntity extends BaseSqlEntity implements SearchTextEntity { @@ -61,7 +58,7 @@ public class ComponentDescriptorEntity extends BaseSqlEntity implements SearchTextEntity { @Column(name = ModelConstants.CUSTOMER_TENANT_ID_PROPERTY) private UUID tenantId; - + @Column(name = ModelConstants.CUSTOMER_TITLE_PROPERTY) private String title; - + @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) private String searchText; - + @Column(name = ModelConstants.COUNTRY_PROPERTY) private String country; - + @Column(name = ModelConstants.STATE_PROPERTY) private String state; @@ -73,7 +71,7 @@ public final class CustomerEntity extends BaseSqlEntity implements Sea @Column(name = ModelConstants.EMAIL_PROPERTY) private String email; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.CUSTOMER_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java index 1e99a59773..c794e1b963 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardEntity.java @@ -15,14 +15,15 @@ */ package org.thingsboard.server.dao.model.sql; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.ShortCustomerInfo; @@ -32,12 +33,8 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import java.io.IOException; import java.util.HashSet; import java.util.UUID; @@ -45,7 +42,6 @@ import java.util.UUID; @Slf4j @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.DASHBOARD_TABLE_NAME) public final class DashboardEntity extends BaseSqlEntity implements SearchTextEntity { @@ -73,7 +69,7 @@ public final class DashboardEntity extends BaseSqlEntity implements S @Column(name = ModelConstants.DASHBOARD_MOBILE_ORDER_PROPERTY) private Integer mobileOrder; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY) private JsonNode configuration; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java index d3c8bbeb34..5dfaaa8de1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DashboardInfoEntity.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.model.sql; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JavaType; import lombok.Data; import lombok.EqualsAndHashCode; @@ -30,10 +29,10 @@ import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; -import java.io.IOException; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; + import java.util.HashSet; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java index 9af4ec64e7..4ab2452168 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceCredentialsEntity.java @@ -25,11 +25,11 @@ import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import java.util.UUID; @Data diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java index d476596dc1..5d2f34ee16 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java @@ -15,25 +15,16 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; -import org.hibernate.annotations.TypeDefs; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonBinaryType; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Entity; -import javax.persistence.Table; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDefs({ - @TypeDef(name = "json", typeClass = JsonStringType.class), - @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) -}) @Table(name = ModelConstants.DEVICE_TABLE_NAME) public final class DeviceEntity extends AbstractDeviceEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java index d8be0eb4b8..f448a79c2b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceInfoEntity.java @@ -21,9 +21,9 @@ import org.hibernate.annotations.Immutable; import org.thingsboard.server.common.data.DeviceInfo; import org.thingsboard.server.dao.model.ModelConstants; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; @Data @EqualsAndHashCode(callSuper = true) diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java index 1b084c4817..cedfe5c748 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceProfileEntity.java @@ -17,10 +17,16 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.JdbcType; +import org.hibernate.dialect.PostgreSQLJsonPGObjectJsonbType; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileProvisionType; @@ -35,19 +41,13 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonBinaryType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) @Table(name = ModelConstants.DEVICE_PROFILE_TABLE_NAME) public final class DeviceProfileEntity extends BaseSqlEntity implements SearchTextEntity { @@ -90,7 +90,8 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl @Column(name = ModelConstants.DEVICE_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY) private String defaultQueueName; - @Type(type = "jsonb") + @Convert(converter = JsonConverter.class) + @JdbcType(PostgreSQLJsonPGObjectJsonbType.class) @Column(name = ModelConstants.DEVICE_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") private JsonNode profileData; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEntity.java index 3c857b3246..a6467da03d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEntity.java @@ -15,21 +15,17 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.edge.Edge; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Entity; -import javax.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TABLE_NAME; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = EDGE_TABLE_NAME) public class EdgeEntity extends AbstractEdgeEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java index 1edc47f197..6ba856df1d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EdgeEventEntity.java @@ -16,11 +16,15 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.edge.EdgeEvent; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventType; @@ -29,20 +33,15 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ACTION_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_BODY_PROPERTY; -import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_EDGE_ID_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_ENTITY_ID_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TENANT_ID_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TYPE_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_UID_PROPERTY; @@ -52,7 +51,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.TS_COLUMN; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = EDGE_EVENT_TABLE_NAME) @NoArgsConstructor public class EdgeEventEntity extends BaseSqlEntity implements BaseEntity { @@ -74,7 +72,7 @@ public class EdgeEventEntity extends BaseSqlEntity implements BaseEnt @Column(name = EDGE_EVENT_ACTION_PROPERTY) private EdgeEventActionType edgeEventAction; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = EDGE_EVENT_BODY_PROPERTY) private JsonNode entityBody; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmCompositeKey.java index ad0c3af521..83e9584385 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmCompositeKey.java @@ -20,7 +20,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.alarm.EntityAlarm; -import javax.persistence.Transient; +import jakarta.persistence.Transient; import java.io.Serializable; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmEntity.java index 6304a5324d..a203195f65 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityAlarmEntity.java @@ -23,11 +23,11 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.ToData; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; +import jakarta.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.CREATED_TIME_PROPERTY; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java index 4bec68240d..dbd442c3d9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java @@ -15,20 +15,16 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Entity; -import javax.persistence.Table; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.ENTITY_VIEW_TABLE_NAME) public class EntityViewEntity extends AbstractEntityViewEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java index 2eb356ac8b..a9d460df01 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/ErrorEventEntity.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.event.ErrorEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.ERROR_EVENT_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java index f0ac6af704..db1ec2b208 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/EventEntity.java @@ -21,9 +21,9 @@ import org.thingsboard.server.common.data.event.Event; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.ModelConstants; -import javax.persistence.Column; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; +import jakarta.persistence.Column; +import jakarta.persistence.Id; +import jakarta.persistence.MappedSuperclass; import java.util.HashMap; import java.util.Map; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java index e20555147f..b247542228 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/LifecycleEventEntity.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.event.LifecycleEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_SUCCESS_COLUMN_NAME; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationEntity.java index 560bea2b91..eb154221d8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationEntity.java @@ -16,11 +16,15 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.annotations.Formula; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.NotificationId; import org.thingsboard.server.common.data.id.NotificationRequestId; import org.thingsboard.server.common.data.id.UserId; @@ -30,19 +34,13 @@ import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.NOTIFICATION_TABLE_NAME) public class NotificationEntity extends BaseSqlEntity { @@ -62,11 +60,11 @@ public class NotificationEntity extends BaseSqlEntity { @Column(name = ModelConstants.NOTIFICATION_TEXT_PROPERTY, nullable = false) private String text; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.NOTIFICATION_ADDITIONAL_CONFIG_PROPERTY) private JsonNode additionalConfig; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Formula("(SELECT r.info FROM notification_request r WHERE r.id = request_id)") private JsonNode info; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRequestEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRequestEntity.java index 713aac62e2..12814e92a2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRequestEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationRequestEntity.java @@ -16,10 +16,14 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.NotificationRequestId; @@ -33,19 +37,13 @@ import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.NOTIFICATION_REQUEST_TABLE_NAME) public class NotificationRequestEntity extends BaseSqlEntity { @@ -58,15 +56,15 @@ public class NotificationRequestEntity extends BaseSqlEntity { @@ -60,15 +59,15 @@ public class NotificationRuleEntity extends BaseSqlEntity { @Column(name = ModelConstants.NOTIFICATION_RULE_TRIGGER_TYPE_PROPERTY, nullable = false) private NotificationRuleTriggerType triggerType; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.NOTIFICATION_RULE_TRIGGER_CONFIG_PROPERTY, nullable = false) private JsonNode triggerConfig; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.NOTIFICATION_RULE_RECIPIENTS_CONFIG_PROPERTY, nullable = false) private JsonNode recipientsConfig; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.NOTIFICATION_RULE_ADDITIONAL_CONFIG_PROPERTY) private JsonNode additionalConfig; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTargetEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTargetEntity.java index a4748ae0c2..4da12fa404 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTargetEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTargetEntity.java @@ -16,26 +16,24 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.NotificationTargetConfig; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.NOTIFICATION_TARGET_TABLE_NAME) public class NotificationTargetEntity extends BaseSqlEntity { @@ -45,7 +43,7 @@ public class NotificationTargetEntity extends BaseSqlEntity @Column(name = ModelConstants.NAME_PROPERTY, nullable = false) private String name; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.NOTIFICATION_TARGET_CONFIGURATION_PROPERTY, nullable = false) private JsonNode configuration; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTemplateEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTemplateEntity.java index 09b0ee7ee9..ef758918e4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTemplateEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/NotificationTemplateEntity.java @@ -16,29 +16,27 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.NotificationTemplateId; import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.NOTIFICATION_TEMPLATE_TABLE_NAME) public class NotificationTemplateEntity extends BaseSqlEntity { @@ -52,7 +50,7 @@ public class NotificationTemplateEntity extends BaseSqlEntity { @@ -89,7 +87,7 @@ public class OAuth2ClientRegistrationTemplateEntity extends BaseSqlEntity { @@ -110,7 +108,7 @@ public class OAuth2RegistrationEntity extends BaseSqlEntity @Column(name = ModelConstants.OAUTH2_MAPPER_SEND_TOKEN_PROPERTY) private Boolean sendToken; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.OAUTH2_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageEntity.java index dcb3bce546..10af250d29 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageEntity.java @@ -16,10 +16,15 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Lob; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.OtaPackage; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.OtaPackageId; @@ -29,14 +34,8 @@ import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Lob; -import javax.persistence.Table; +import org.thingsboard.server.dao.util.mapping.JsonConverter; + import java.nio.ByteBuffer; import java.util.UUID; @@ -59,7 +58,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPER @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = OTA_PACKAGE_TABLE_NAME) public class OtaPackageEntity extends BaseSqlEntity implements SearchTextEntity { @@ -105,7 +103,7 @@ public class OtaPackageEntity extends BaseSqlEntity implements Searc @Column(name = OTA_PACKAGE_DATA_SIZE_COLUMN) private Long dataSize; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.OTA_PACKAGE_ADDITIONAL_INFO_COLUMN) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageInfoEntity.java index 5a2eb6008b..8e14cc198e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/OtaPackageInfoEntity.java @@ -16,10 +16,15 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.OtaPackageInfo; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -30,14 +35,8 @@ import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; -import javax.persistence.Transient; +import org.thingsboard.server.dao.util.mapping.JsonConverter; + import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.OTA_PACKAGE_CHECKSUM_ALGORITHM_COLUMN; @@ -58,7 +57,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPER @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = OTA_PACKAGE_TABLE_NAME) public class OtaPackageInfoEntity extends BaseSqlEntity implements SearchTextEntity { @@ -100,7 +98,7 @@ public class OtaPackageInfoEntity extends BaseSqlEntity implemen @Column(name = OTA_PACKAGE_DATA_SIZE_COLUMN) private Long dataSize; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.OTA_PACKAGE_ADDITIONAL_INFO_COLUMN) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/QueueEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/QueueEntity.java index 75f3332fbe..b81ddb04e1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/QueueEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/QueueEntity.java @@ -16,10 +16,12 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.TenantId; @@ -29,17 +31,13 @@ import org.thingsboard.server.common.data.queue.SubmitStrategy; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.QUEUE_TABLE_NAME) public class QueueEntity extends BaseSqlEntity { @@ -63,15 +61,15 @@ public class QueueEntity extends BaseSqlEntity { @Column(name = ModelConstants.QUEUE_PACK_PROCESSING_TIMEOUT_PROPERTY) private long packProcessingTimeout; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.QUEUE_SUBMIT_STRATEGY_PROPERTY) private JsonNode submitStrategy; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.QUEUE_PROCESSING_STRATEGY_PROPERTY) private JsonNode processingStrategy; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.QUEUE_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java index aeae9e5b86..76e953fdbf 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationCompositeKey.java @@ -20,7 +20,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.relation.EntityRelation; -import javax.persistence.Transient; +import jakarta.persistence.Transient; import java.io.Serializable; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java index 1e502adde1..a87123a8c0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RelationEntity.java @@ -16,26 +16,25 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; +import jakarta.persistence.Table; import lombok.Data; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.dao.model.ToData; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.ADDITIONAL_INFO_PROPERTY; -import static org.thingsboard.server.dao.model.ModelConstants.RELATION_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.RELATION_FROM_ID_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.RELATION_FROM_TYPE_PROPERTY; +import static org.thingsboard.server.dao.model.ModelConstants.RELATION_TABLE_NAME; import static org.thingsboard.server.dao.model.ModelConstants.RELATION_TO_ID_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.RELATION_TO_TYPE_PROPERTY; import static org.thingsboard.server.dao.model.ModelConstants.RELATION_TYPE_GROUP_PROPERTY; @@ -43,7 +42,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.RELATION_TYPE_PROP @Data @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = RELATION_TABLE_NAME) @IdClass(RelationCompositeKey.class) public final class RelationEntity implements ToData { @@ -72,7 +70,7 @@ public final class RelationEntity implements ToData { @Column(name = RELATION_TYPE_PROPERTY) private String relationType; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RpcEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RpcEntity.java index 8906619d5b..abf32bd444 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RpcEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RpcEntity.java @@ -16,10 +16,14 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.RpcId; import org.thingsboard.server.common.data.id.TenantId; @@ -27,13 +31,8 @@ import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.RPC_ADDITIONAL_INFO; @@ -48,7 +47,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.RPC_TENANT_ID_COLU @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = RPC_TABLE_NAME) public class RpcEntity extends BaseSqlEntity implements BaseEntity { @@ -61,11 +59,11 @@ public class RpcEntity extends BaseSqlEntity implements BaseEntity { @Column(name = RPC_EXPIRATION_TIME) private long expirationTime; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = RPC_REQUEST) private JsonNode request; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = RPC_RESPONSE) private JsonNode response; @@ -73,7 +71,7 @@ public class RpcEntity extends BaseSqlEntity implements BaseEntity { @Column(name = RPC_STATUS) private RpcStatus status; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = RPC_ADDITIONAL_INFO) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java index 7e0921d381..08a2fa6b72 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainDebugEventEntity.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.event.RuleChainDebugEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERROR_COLUMN_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MESSAGE_COLUMN_NAME; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java index 82362e0259..f55e331d4f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleChainEntity.java @@ -16,10 +16,14 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; @@ -29,19 +33,13 @@ import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.RULE_CHAIN_TABLE_NAME) public class RuleChainEntity extends BaseSqlEntity implements SearchTextEntity { @@ -67,11 +65,11 @@ public class RuleChainEntity extends BaseSqlEntity implements SearchT @Column(name = ModelConstants.DEBUG_MODE) private boolean debugMode; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.RULE_CHAIN_CONFIGURATION_PROPERTY) private JsonNode configuration; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java index ee4d6c3bd1..ce28037a89 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeDebugEventEntity.java @@ -23,9 +23,9 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_DATA_COLUMN_NAME; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java index c03920d954..26bfdd3c3d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeEntity.java @@ -16,10 +16,12 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.rule.RuleNode; @@ -27,17 +29,13 @@ import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.RULE_NODE_TABLE_NAME) public class RuleNodeEntity extends BaseSqlEntity implements SearchTextEntity { @@ -53,11 +51,11 @@ public class RuleNodeEntity extends BaseSqlEntity implements SearchTex @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) private String searchText; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.RULE_NODE_CONFIGURATION_PROPERTY) private JsonNode configuration; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeStateEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeStateEntity.java index 9a9efe432a..a71e57ce8b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeStateEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/RuleNodeStateEntity.java @@ -15,9 +15,11 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeStateId; @@ -25,17 +27,12 @@ import org.thingsboard.server.common.data.rule.RuleNodeState; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.RULE_NODE_STATE_TABLE_NAME) public class RuleNodeStateEntity extends BaseSqlEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java index 0ac017d48d..43395f2f87 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/StatisticsEventEntity.java @@ -22,9 +22,9 @@ import org.thingsboard.server.common.data.event.StatisticsEvent; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_ERRORS_OCCURRED_COLUMN_NAME; import static org.thingsboard.server.dao.model.ModelConstants.EVENT_MESSAGES_PROCESSED_COLUMN_NAME; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java index 1b30123b2e..741e21532e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceEntity.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.SearchTextEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_DATA_COLUMN; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java index 5ebc0297af..9314c42bcc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TbResourceInfoEntity.java @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.SearchTextEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.RESOURCE_KEY_COLUMN; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java index 46d3f34c9e..592326c20f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantEntity.java @@ -15,20 +15,16 @@ */ package org.thingsboard.server.dao.model.sql; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Entity; -import javax.persistence.Table; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.TENANT_TABLE_NAME) public final class TenantEntity extends AbstractTenantEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java index 9672ed2bab..302a51b4c4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/TenantProfileEntity.java @@ -17,10 +17,14 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.JdbcType; +import org.hibernate.dialect.PostgreSQLJsonPGObjectJsonbType; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.TenantProfileId; @@ -28,16 +32,11 @@ import org.thingsboard.server.common.data.tenant.profile.TenantProfileData; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonBinaryType; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import org.thingsboard.server.dao.util.mapping.JsonConverter; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) @Table(name = ModelConstants.TENANT_PROFILE_TABLE_NAME) public final class TenantProfileEntity extends BaseSqlEntity implements SearchTextEntity { @@ -56,8 +55,9 @@ public final class TenantProfileEntity extends BaseSqlEntity impl @Column(name = ModelConstants.TENANT_PROFILE_ISOLATED_TB_RULE_ENGINE) private boolean isolatedTbRuleEngine; - @Type(type = "jsonb") - @Column(name = ModelConstants.TENANT_PROFILE_PROFILE_DATA_PROPERTY, columnDefinition = "jsonb") + @Convert(converter = JsonConverter.class) + @JdbcType(PostgreSQLJsonPGObjectJsonbType.class) + @Column(name = ModelConstants.TENANT_PROFILE_PROFILE_DATA_PROPERTY) private JsonNode profileData; public TenantProfileEntity() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserAuthSettingsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserAuthSettingsEntity.java index 9d63b4d586..1ea283a18b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserAuthSettingsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserAuthSettingsEntity.java @@ -16,11 +16,13 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.id.UserAuthSettingsId; import org.thingsboard.server.common.data.id.UserId; @@ -29,24 +31,20 @@ import org.thingsboard.server.common.data.security.model.mfa.account.AccountTwoF import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; import java.util.UUID; @EqualsAndHashCode(callSuper = true) @Data @NoArgsConstructor -@TypeDef(name = "json", typeClass = JsonStringType.class) @Entity @Table(name = ModelConstants.USER_AUTH_SETTINGS_TABLE_NAME) public class UserAuthSettingsEntity extends BaseSqlEntity implements BaseEntity { @Column(name = ModelConstants.USER_AUTH_SETTINGS_USER_ID_PROPERTY, nullable = false, unique = true) private UUID userId; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.USER_AUTH_SETTINGS_TWO_FA_SETTINGS) private JsonNode twoFaSettings; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java index 7c93fd0be2..f02080bf58 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserCredentialsEntity.java @@ -16,9 +16,9 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Convert; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; import org.thingsboard.server.common.data.id.UserCredentialsId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.UserCredentials; @@ -26,9 +26,11 @@ import org.thingsboard.server.dao.model.BaseEntity; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import org.thingsboard.server.dao.util.mapping.JsonConverter; + import java.util.UUID; @Data @@ -52,7 +54,7 @@ public final class UserCredentialsEntity extends BaseSqlEntity @Column(name = ModelConstants.USER_CREDENTIALS_RESET_TOKEN_PROPERTY, unique = true) private String resetToken; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.USER_CREDENTIALS_ADDITIONAL_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java index 33b19d765e..145b8508d3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserEntity.java @@ -16,10 +16,14 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; @@ -28,13 +32,8 @@ import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Table; import java.util.UUID; /** @@ -43,7 +42,6 @@ import java.util.UUID; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.USER_PG_HIBERNATE_TABLE_NAME) public class UserEntity extends BaseSqlEntity implements SearchTextEntity { @@ -72,7 +70,7 @@ public class UserEntity extends BaseSqlEntity implements SearchTextEntity< @Column(name = ModelConstants.PHONE_PROPERTY) private String phone; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.USER_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserSettingsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserSettingsEntity.java index a494b8096c..9e383f0359 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserSettingsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/UserSettingsEntity.java @@ -16,28 +16,26 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; +import jakarta.persistence.Table; import lombok.Data; import lombok.NoArgsConstructor; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.settings.UserSettings; import org.thingsboard.server.common.data.settings.UserSettingsCompositeKey; import org.thingsboard.server.common.data.settings.UserSettingsType; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.ToData; -import org.thingsboard.server.dao.util.mapping.JsonStringType; +import org.thingsboard.server.dao.util.mapping.JsonConverter; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.Table; import java.util.UUID; @Data @NoArgsConstructor -@TypeDef(name = "json", typeClass = JsonStringType.class) @Entity @Table(name = ModelConstants.USER_SETTINGS_TABLE_NAME) @IdClass(UserSettingsCompositeKey.class) @@ -49,7 +47,7 @@ public class UserSettingsEntity implements ToData { @Id @Column(name = ModelConstants.USER_SETTINGS_TYPE_PROPERTY) private String type; - @Type(type = "json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.USER_SETTINGS_SETTINGS) private JsonNode settings; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeDetailsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeDetailsEntity.java index c936952b40..a304318fee 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeDetailsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeDetailsEntity.java @@ -16,23 +16,20 @@ package org.thingsboard.server.dao.model.sql; import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; -import org.hibernate.annotations.TypeDef; import org.thingsboard.server.common.data.widget.BaseWidgetType; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.dao.model.ModelConstants; -import org.thingsboard.server.dao.util.mapping.JsonStringType; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import org.thingsboard.server.dao.util.mapping.JsonConverter; @Data @EqualsAndHashCode(callSuper = true) @Entity -@TypeDef(name = "json", typeClass = JsonStringType.class) @Table(name = ModelConstants.WIDGET_TYPE_TABLE_NAME) public class WidgetTypeDetailsEntity extends AbstractWidgetTypeEntity { @@ -42,7 +39,7 @@ public class WidgetTypeDetailsEntity extends AbstractWidgetTypeEntity { - @Type(type="json") + @Convert(converter = JsonConverter.class) @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY) private JsonNode descriptor; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java index 0bc2f0ba36..272863134a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java @@ -25,9 +25,9 @@ import org.thingsboard.server.dao.model.BaseSqlEntity; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.model.SearchTextEntity; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; import java.util.UUID; @Data diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionary.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionary.java index 36f34d4239..5f1ff6a9c1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionary.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionary.java @@ -15,15 +15,13 @@ */ package org.thingsboard.server.dao.model.sqlts.dictionary; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; +import jakarta.persistence.Table; import lombok.Data; import org.hibernate.annotations.Generated; -import org.hibernate.annotations.GenerationTime; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.IdClass; -import javax.persistence.Table; import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.KEY_ID_COLUMN; @@ -38,8 +36,8 @@ public final class TsKvDictionary { @Column(name = KEY_COLUMN) private String key; - @Column(name = KEY_ID_COLUMN, unique = true, columnDefinition="int") - @Generated(GenerationTime.INSERT) + @Column(name = KEY_ID_COLUMN, unique = true, columnDefinition = "int") + @Generated private int keyId; } \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionaryCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionaryCompositeKey.java index 5a83260bac..49ab8b6822 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionaryCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionaryCompositeKey.java @@ -19,7 +19,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Transient; +import jakarta.persistence.Transient; import java.io.Serializable; @Data diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestCompositeKey.java index ae1c34310c..c46d6f3d5d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestCompositeKey.java @@ -19,7 +19,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Transient; +import jakarta.persistence.Transient; import java.io.Serializable; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java index 58a76ddf31..7c57babdb1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/latest/TsKvLatestEntity.java @@ -15,19 +15,19 @@ */ package org.thingsboard.server.dao.model.sqlts.latest; +import jakarta.persistence.ColumnResult; +import jakarta.persistence.ConstructorResult; +import jakarta.persistence.Entity; +import jakarta.persistence.IdClass; +import jakarta.persistence.NamedNativeQueries; +import jakarta.persistence.NamedNativeQuery; +import jakarta.persistence.SqlResultSetMapping; +import jakarta.persistence.SqlResultSetMappings; +import jakarta.persistence.Table; import lombok.Data; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.sqlts.latest.SearchTsKvLatestRepository; -import javax.persistence.ColumnResult; -import javax.persistence.ConstructorResult; -import javax.persistence.Entity; -import javax.persistence.IdClass; -import javax.persistence.NamedNativeQueries; -import javax.persistence.NamedNativeQuery; -import javax.persistence.SqlResultSetMapping; -import javax.persistence.SqlResultSetMappings; -import javax.persistence.Table; import java.util.UUID; @Data diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvCompositeKey.java index a7f2ed4210..23006f63e7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvCompositeKey.java @@ -15,11 +15,11 @@ */ package org.thingsboard.server.dao.model.sqlts.timescale.ts; +import jakarta.persistence.Transient; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Transient; import java.io.Serializable; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java index f50af42073..2d09caf150 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/timescale/ts/TimescaleTsKvEntity.java @@ -15,21 +15,20 @@ */ package org.thingsboard.server.dao.model.sqlts.timescale.ts; +import jakarta.persistence.ColumnResult; +import jakarta.persistence.ConstructorResult; +import jakarta.persistence.Entity; +import jakarta.persistence.IdClass; +import jakarta.persistence.NamedNativeQueries; +import jakarta.persistence.NamedNativeQuery; +import jakarta.persistence.SqlResultSetMapping; +import jakarta.persistence.SqlResultSetMappings; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; -import javax.persistence.ColumnResult; -import javax.persistence.ConstructorResult; -import javax.persistence.Entity; -import javax.persistence.IdClass; -import javax.persistence.NamedNativeQueries; -import javax.persistence.NamedNativeQuery; -import javax.persistence.SqlResultSetMapping; -import javax.persistence.SqlResultSetMappings; -import javax.persistence.Table; - import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG; import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_AVG_QUERY; import static org.thingsboard.server.dao.sqlts.timescale.AggregationRepository.FIND_COUNT; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvCompositeKey.java index 14fe2b6eb7..7da73e5012 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvCompositeKey.java @@ -19,7 +19,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import javax.persistence.Transient; +import jakarta.persistence.Transient; import java.io.Serializable; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvEntity.java index 9f5b8d87ef..d0577b6288 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/ts/TsKvEntity.java @@ -15,14 +15,13 @@ */ package org.thingsboard.server.dao.model.sqlts.ts; +import jakarta.persistence.Entity; +import jakarta.persistence.IdClass; +import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; -import javax.persistence.Entity; -import javax.persistence.IdClass; -import javax.persistence.Table; - @EqualsAndHashCode(callSuper = true) @Data @Entity diff --git a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraAbstractAsyncDao.java b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraAbstractAsyncDao.java index 425724bf2c..87bb2f0e5c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraAbstractAsyncDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraAbstractAsyncDao.java @@ -21,9 +21,9 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.common.util.ThingsBoardThreadFactory; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; diff --git a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java index adeee5f174..3ed763b43b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateReadExecutor.java @@ -29,7 +29,7 @@ import org.thingsboard.server.dao.util.AbstractBufferedRateExecutor; import org.thingsboard.server.dao.util.AsyncTaskContext; import org.thingsboard.server.dao.util.NoSqlAnyDao; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; /** * Created by ashvayka on 24.10.18. diff --git a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java index 55b1b5410d..e09dab1034 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/nosql/CassandraBufferedRateWriteExecutor.java @@ -29,7 +29,7 @@ import org.thingsboard.server.dao.util.AbstractBufferedRateExecutor; import org.thingsboard.server.dao.util.AsyncTaskContext; import org.thingsboard.server.dao.util.NoSqlAnyDao; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; /** * Created by ashvayka on 24.10.18. diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java index 9818f4a2f0..0ba74f5811 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/OAuth2ServiceImpl.java @@ -43,7 +43,7 @@ import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.IncorrectParameterException; -import javax.transaction.Transactional; +import jakarta.transaction.Transactional; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index fb86e09ab3..6b631bf041 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -50,8 +50,8 @@ import org.thingsboard.server.dao.service.ConstraintValidator; import org.thingsboard.server.dao.sql.JpaExecutorService; import org.thingsboard.server.dao.sql.relation.JpaRelationQueryExecutorService; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/ConstraintValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/ConstraintValidator.java index b884de0094..b0ced3dcc3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/ConstraintValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/ConstraintValidator.java @@ -30,11 +30,11 @@ import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; import org.thingsboard.server.dao.exception.DataValidationException; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.constraints.AssertTrue; -import javax.validation.metadata.ConstraintDescriptor; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.constraints.AssertTrue; +import jakarta.validation.metadata.ConstraintDescriptor; import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; @@ -100,7 +100,7 @@ public class ConstraintValidator { } private static ConstraintMapping getCustomConstraintMapping() { - ConstraintMapping constraintMapping = new DefaultConstraintMapping(); + ConstraintMapping constraintMapping = new DefaultConstraintMapping(null); constraintMapping.constraintDefinition(NoXss.class).validatedBy(NoXssValidator.class); constraintMapping.constraintDefinition(Length.class).validatedBy(StringLengthValidator.class); return constraintMapping; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/NoXssValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/NoXssValidator.java index 632caf10c4..8e7b2c6af0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/NoXssValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/NoXssValidator.java @@ -23,8 +23,8 @@ import org.owasp.validator.html.PolicyException; import org.owasp.validator.html.ScanException; import org.thingsboard.server.common.data.validation.NoXss; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; import java.util.Optional; @Slf4j diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/StringLengthValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/StringLengthValidator.java index d4299dcc0b..935eebf19a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/StringLengthValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/StringLengthValidator.java @@ -20,8 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.validation.Length; -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; @Slf4j public class StringLengthValidator implements ConstraintValidator { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/ScheduledLogExecutorComponent.java b/dao/src/main/java/org/thingsboard/server/dao/sql/ScheduledLogExecutorComponent.java index 83e1bf4afe..fa39130049 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/ScheduledLogExecutorComponent.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/ScheduledLogExecutorComponent.java @@ -18,8 +18,8 @@ package org.thingsboard.server.dao.sql; import org.springframework.stereotype.Component; import org.thingsboard.common.util.ThingsBoardThreadFactory; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/TbSqlBlockingQueue.java b/dao/src/main/java/org/thingsboard/server/dao/sql/TbSqlBlockingQueue.java index fd3822bb5f..88145a9cf1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/TbSqlBlockingQueue.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/TbSqlBlockingQueue.java @@ -41,6 +41,7 @@ public class TbSqlBlockingQueue implements TbSqlQueue { private ExecutorService executor; private final MessagesStats stats; + private volatile boolean stopped = false; public TbSqlBlockingQueue(TbSqlBlockingQueueParams params, MessagesStats stats) { this.params = params; @@ -55,7 +56,7 @@ public class TbSqlBlockingQueue implements TbSqlQueue { int batchSize = params.getBatchSize(); long maxDelay = params.getMaxDelay(); List> entities = new ArrayList<>(batchSize); - while (!Thread.interrupted()) { + while (!stopped) { try { long currentTs = System.currentTimeMillis(); TbSqlQueueElement attr = queue.poll(maxDelay, TimeUnit.MILLISECONDS); @@ -109,6 +110,7 @@ public class TbSqlBlockingQueue implements TbSqlQueue { @Override public void destroy() { + stopped = true; if (executor != null) { executor.shutdownNow(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java index 92537dc850..7fb6b31a3c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/alarm/AlarmRepository.java @@ -52,8 +52,8 @@ public interface AlarmRepository extends JpaRepository { "AND ea.entityType = :affectedEntityType " + "AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " + "AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -69,8 +69,8 @@ public interface AlarmRepository extends JpaRepository { "AND ea.entityType = :affectedEntityType " + "AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " + "AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -97,10 +97,12 @@ public interface AlarmRepository extends JpaRepository { "AND ea.entityType = :affectedEntityType " + "AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " + "AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " + - "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + - "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968 + "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968 +// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + +// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -116,10 +118,12 @@ public interface AlarmRepository extends JpaRepository { "AND ea.entityType = :affectedEntityType " + "AND (:startTime IS NULL OR (a.createdTime >= :startTime AND ea.createdTime >= :startTime)) " + "AND (:endTime IS NULL OR (a.createdTime <= :endTime AND ea.createdTime <= :endTime)) " + - "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + - "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968 + "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968 +// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + +// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -144,8 +148,8 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -156,8 +160,8 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -178,10 +182,12 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + - "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968 + "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968 +// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + +// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -192,10 +198,12 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + - "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968 + "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968 +// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + +// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -218,8 +226,8 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId AND a.customerId = :customerId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -231,8 +239,8 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId AND a.customerId = :customerId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -254,10 +262,12 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId AND a.customerId = :customerId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + - "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968 + "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968 +// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + +// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -269,10 +279,12 @@ public interface AlarmRepository extends JpaRepository { "WHERE a.tenantId = :tenantId AND a.customerId = :customerId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + - "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:#{#alarmTypes == null} = true) OR a.type IN (:alarmTypes)) " + //HHH-15968 + "AND ((:#{#alarmSeverities == null} = true) OR a.severity IN (:alarmSeverities)) " + //HHH-15968 +// "AND ((:alarmTypes) IS NULL OR a.type IN (:alarmTypes)) " + +// "AND ((:alarmSeverities) IS NULL OR a.severity IN (:alarmSeverities)) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId)) " + "AND (LOWER(a.type) LIKE LOWER(CONCAT('%', :searchText, '%')) " + " OR LOWER(a.severity) LIKE LOWER(CONCAT('%', :searchText, '%')) " + @@ -297,8 +309,8 @@ public interface AlarmRepository extends JpaRepository { "AND ea.tenantId = :tenantId " + "AND ea.entityId = :affectedEntityId " + "AND ea.entityType = :affectedEntityType " + - "AND ((:clearFilterEnabled) IS FALSE OR a.cleared = :clearFilter) " + - "AND ((:ackFilterEnabled) IS FALSE OR a.acknowledged = :ackFilter) " + + "AND ((:clearFilterEnabled) = FALSE OR a.cleared = :clearFilter) " + + "AND ((:ackFilterEnabled) = FALSE OR a.acknowledged = :ackFilter) " + "AND (:assigneeId IS NULL OR a.assigneeId = uuid(:assigneeId))") Set findAlarmSeverities(@Param("tenantId") UUID tenantId, @Param("affectedEntityId") UUID affectedEntityId, diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java index 4474378f32..6d195d1cc4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java @@ -19,6 +19,8 @@ import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -39,8 +41,6 @@ import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; import org.thingsboard.server.dao.util.SqlDao; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; @@ -132,10 +132,10 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl @Override public List findAll(TenantId tenantId, EntityId entityId, String attributeType) { return DaoUtil.convertDataList(Lists.newArrayList( - attributeKvRepository.findAllByEntityTypeAndEntityIdAndAttributeType( - entityId.getEntityType(), - entityId.getId(), - attributeType))); + attributeKvRepository.findAllByEntityTypeAndEntityIdAndAttributeType( + entityId.getEntityType(), + entityId.getId(), + attributeType))); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java index 3d35383eb0..68aa2a0ee9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/audit/AuditLogRepository.java @@ -33,7 +33,8 @@ public interface AuditLogRepository extends JpaRepository "a.tenantId = :tenantId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + + "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968 +// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + "AND (LOWER(a.entityType) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.entityName) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.userName) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + @@ -53,7 +54,8 @@ public interface AuditLogRepository extends JpaRepository "AND a.entityType = :entityType AND a.entityId = :entityId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + + "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968 +// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + "AND (LOWER(a.entityName) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.userName) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.actionType) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + @@ -73,7 +75,8 @@ public interface AuditLogRepository extends JpaRepository "AND a.customerId = :customerId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + + "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968 +// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + "AND (LOWER(a.entityType) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.entityName) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.userName) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + @@ -93,7 +96,8 @@ public interface AuditLogRepository extends JpaRepository "AND a.userId = :userId " + "AND (:startTime IS NULL OR a.createdTime >= :startTime) " + "AND (:endTime IS NULL OR a.createdTime <= :endTime) " + - "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + + "AND ((:#{#actionTypes == null} = true) OR a.actionType IN (:actionTypes)) " + //HHH-15968 +// "AND ((:actionTypes) IS NULL OR a.actionType in (:actionTypes)) " + "AND (LOWER(a.entityType) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.entityName) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + "OR LOWER(a.actionType) LIKE LOWER(CONCAT('%', :textSearch, '%'))" + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java index 943697149c..83c841459f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/AbstractComponentDescriptorInsertRepository.java @@ -25,9 +25,9 @@ import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; @Slf4j public abstract class AbstractComponentDescriptorInsertRepository implements ComponentDescriptorInsertRepository { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java index 89ed713975..f1f07381d3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java @@ -122,7 +122,7 @@ public interface DeviceRepository extends JpaRepository, Exp "AND (:edgeId IS NULL OR d.id IN (SELECT re.toId FROM RelationEntity re WHERE re.toType = 'DEVICE' AND re.relationTypeGroup = 'EDGE' AND re.relationType = 'Contains' AND re.fromType = 'EDGE' AND re.fromId = uuid(:edgeId))) " + "AND ((:deviceType) IS NULL OR d.type = :deviceType) " + "AND (:deviceProfileId IS NULL OR d.deviceProfileId = uuid(:deviceProfileId)) " + - "AND ((:filterByActive) IS FALSE OR d.active = :deviceActive) " + + "AND ((:filterByActive) = FALSE OR d.active = :deviceActive) " + "AND (LOWER(d.searchText) LIKE LOWER(CONCAT('%', :textSearch, '%')) " + "OR LOWER(d.label) LIKE LOWER(CONCAT('%', :textSearch, '%')) " + "OR LOWER(d.type) LIKE LOWER(CONCAT('%', :textSearch, '%')) " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java index 239fe1f098..6527f022f6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaBaseEdgeEventDao.java @@ -17,6 +17,8 @@ package org.thingsboard.server.dao.sql.edge; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.google.common.util.concurrent.ListenableFuture; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -41,8 +43,6 @@ import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; import org.thingsboard.server.dao.util.SqlDao; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.Comparator; import java.util.Objects; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java index 8d0df9e48d..1f08da69fa 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java @@ -33,7 +33,7 @@ import org.thingsboard.server.common.data.event.RuleNodeDebugEvent; import org.thingsboard.server.common.data.event.StatisticsEvent; import org.thingsboard.server.dao.util.SqlDao; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventPartitionConfiguration.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventPartitionConfiguration.java index 452e9b744f..546f813382 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventPartitionConfiguration.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventPartitionConfiguration.java @@ -20,7 +20,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.event.EventType; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.concurrent.TimeUnit; @Component diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java index f35e7e608f..3ba6d21aa0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/JpaBaseEventDao.java @@ -17,6 +17,8 @@ package org.thingsboard.server.dao.sql.event; import com.datastax.oss.driver.api.core.uuid.Uuids; import com.google.common.util.concurrent.ListenableFuture; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -43,8 +45,6 @@ import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; import org.thingsboard.server.dao.util.SqlDao; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.Comparator; import java.util.List; import java.util.Map; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/QueryContext.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/QueryContext.java index 8ced23cdb4..a37432d66a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/QueryContext.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/QueryContext.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.sql.query; import lombok.extern.slf4j.Slf4j; -import org.hibernate.type.PostgresUUIDType; +import org.hibernate.type.descriptor.jdbc.UUIDJdbcType; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.CustomerId; @@ -30,7 +30,7 @@ import java.util.UUID; @Slf4j public class QueryContext implements SqlParameterSource { - private static final PostgresUUIDType UUID_TYPE = new PostgresUUIDType(); + private static final UUIDJdbcType UUID_TYPE = UUIDJdbcType.INSTANCE; private final QuerySecurityContext securityCtx; private final StringBuilder query; @@ -91,7 +91,7 @@ public class QueryContext implements SqlParameterSource { } public void addUuidParameter(String name, UUID value) { - addParameter(name, value, UUID_TYPE.sqlType(), UUID_TYPE.getName()); + addParameter(name, value, UUID_TYPE.getJdbcTypeCode(), UUID_TYPE.getFriendlyName()); } public void addStringParameter(String name, String value) { @@ -115,7 +115,7 @@ public class QueryContext implements SqlParameterSource { } public void addUuidListParameter(String name, List value) { - addParameter(name, value, UUID_TYPE.sqlType(), UUID_TYPE.getName()); + addParameter(name, value, UUID_TYPE.getJdbcTypeCode(), UUID_TYPE.getFriendlyName()); } public String getQuery() { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/SqlRelationInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/SqlRelationInsertRepository.java index 835a23f6b5..fded581981 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/SqlRelationInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/SqlRelationInsertRepository.java @@ -23,9 +23,9 @@ import org.springframework.transaction.annotation.Transactional; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.dao.model.sql.RelationEntity; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java index 71f9af99e5..991043db88 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java @@ -17,6 +17,8 @@ package org.thingsboard.server.dao.sqlts; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; @@ -38,8 +40,6 @@ import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; import org.thingsboard.server.dao.sqlts.ts.TsKvRepository; import org.thingsboard.server.dao.timeseries.TimeseriesDao; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import java.util.ArrayList; import java.util.Comparator; import java.util.List; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractSqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractSqlTimeseriesDao.java index ee0dbab8c2..8c82981633 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractSqlTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractSqlTimeseriesDao.java @@ -29,7 +29,7 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java index c4c3e021c8..52c4216c69 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java @@ -31,7 +31,7 @@ import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryComposite import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -53,11 +53,15 @@ public abstract class BaseAbstractSqlTimeseriesDao extends JpaAbstractDaoListeni if (keyId == null) { Optional tsKvDictionaryOptional; tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); - if (!tsKvDictionaryOptional.isPresent()) { + if (tsKvDictionaryOptional.isEmpty()) { tsCreationLock.lock(); try { + keyId = tsKvDictionaryMap.get(strKey); + if (keyId != null) { + return keyId; + } tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); - if (!tsKvDictionaryOptional.isPresent()) { + if (tsKvDictionaryOptional.isEmpty()) { TsKvDictionary tsKvDictionary = new TsKvDictionary(); tsKvDictionary.setKey(strKey); try { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java index b58f0dc7c7..2312fa3cb2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java @@ -49,8 +49,8 @@ import org.thingsboard.server.dao.sqlts.latest.TsKvLatestRepository; import org.thingsboard.server.dao.timeseries.TimeseriesLatestDao; import org.thingsboard.server.dao.util.SqlTsLatestAnyDao; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java index 7969e9c3c8..beaa4a5f0d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java @@ -19,8 +19,8 @@ import org.springframework.stereotype.Repository; import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; import org.thingsboard.server.dao.util.SqlTsLatestAnyDao; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import java.util.List; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/AggregationRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/AggregationRepository.java index 43ad0a18fc..23a1f4e397 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/AggregationRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/AggregationRepository.java @@ -19,8 +19,8 @@ import org.springframework.stereotype.Repository; import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; import org.thingsboard.server.dao.util.TimescaleDBTsOrTsLatestDao; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; import java.util.List; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java index 42577c2d45..128073323c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java @@ -42,8 +42,8 @@ import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; import org.thingsboard.server.dao.timeseries.TimeseriesDao; import org.thingsboard.server.dao.util.TimescaleDBTsDao; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/ts/TsKvRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/ts/TsKvRepository.java index 76b7af20a5..3a907f12bd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/ts/TsKvRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/ts/TsKvRepository.java @@ -30,12 +30,12 @@ import java.util.UUID; public interface TsKvRepository extends JpaRepository { /* - * Using native query to avoid adding 'nulls first' or 'nulls last' (ignoring spring.jpa.properties.hibernate.order_by.default_null_ordering) - * to the order so that index scan is done instead of full scan. - * - * Note: even when setting custom NullHandling for the Sort.Order for non-native queries, - * it will be ignored and default_null_ordering will be used - * */ + * Using native query to avoid adding 'nulls first' or 'nulls last' (ignoring spring.jpa.properties.hibernate.order_by.default_null_ordering) + * to the order so that index scan is done instead of full scan. + * + * Note: even when setting custom NullHandling for the Sort.Order for non-native queries, + * it will be ignored and default_null_ordering will be used + * */ @Query(value = "SELECT * FROM ts_kv WHERE entity_id = :entityId " + "AND key = :entityKey AND ts >= :startTs AND ts < :endTs ", nativeQuery = true) List findAllWithLimit(@Param("entityId") UUID entityId, @@ -57,41 +57,41 @@ public interface TsKvRepository extends JpaRepository= :startTs AND tskv.ts < :endTs") TsKvEntity findStringMax(@Param("entityId") UUID entityId, - @Param("entityKey") int entityKey, - @Param("startTs") long startTs, - @Param("endTs") long endTs); + @Param("entityKey") int entityKey, + @Param("startTs") long startTs, + @Param("endTs") long endTs); @Query("SELECT new TsKvEntity(MAX(COALESCE(tskv.longValue, -9223372036854775807)), " + - "MAX(COALESCE(tskv.doubleValue, -1.79769E+308)), " + + "MAX(COALESCE(tskv.doubleValue, java.lang.Double.MIN_VALUE)), " + "SUM(CASE WHEN tskv.longValue IS NULL THEN 0 ELSE 1 END), " + "SUM(CASE WHEN tskv.doubleValue IS NULL THEN 0 ELSE 1 END), " + "'MAX', MAX(tskv.ts)) FROM TsKvEntity tskv " + "WHERE tskv.entityId = :entityId AND tskv.key = :entityKey AND tskv.ts >= :startTs AND tskv.ts < :endTs") TsKvEntity findNumericMax(@Param("entityId") UUID entityId, - @Param("entityKey") int entityKey, - @Param("startTs") long startTs, - @Param("endTs") long endTs); + @Param("entityKey") int entityKey, + @Param("startTs") long startTs, + @Param("endTs") long endTs); @Query("SELECT new TsKvEntity(MIN(tskv.strValue), MAX(tskv.ts)) FROM TsKvEntity tskv " + "WHERE tskv.strValue IS NOT NULL " + "AND tskv.entityId = :entityId AND tskv.key = :entityKey AND tskv.ts >= :startTs AND tskv.ts < :endTs") TsKvEntity findStringMin(@Param("entityId") UUID entityId, - @Param("entityKey") int entityKey, - @Param("startTs") long startTs, - @Param("endTs") long endTs); + @Param("entityKey") int entityKey, + @Param("startTs") long startTs, + @Param("endTs") long endTs); @Query("SELECT new TsKvEntity(MIN(COALESCE(tskv.longValue, 9223372036854775807)), " + - "MIN(COALESCE(tskv.doubleValue, 1.79769E+308)), " + + "MIN(COALESCE(tskv.doubleValue, java.lang.Double.MAX_VALUE)), " + "SUM(CASE WHEN tskv.longValue IS NULL THEN 0 ELSE 1 END), " + "SUM(CASE WHEN tskv.doubleValue IS NULL THEN 0 ELSE 1 END), " + "'MIN', MAX(tskv.ts)) FROM TsKvEntity tskv " + "WHERE tskv.entityId = :entityId AND tskv.key = :entityKey AND tskv.ts >= :startTs AND tskv.ts < :endTs") TsKvEntity findNumericMin( - @Param("entityId") UUID entityId, - @Param("entityKey") int entityKey, - @Param("startTs") long startTs, - @Param("endTs") long endTs); + @Param("entityId") UUID entityId, + @Param("entityKey") int entityKey, + @Param("startTs") long startTs, + @Param("endTs") long endTs); @Query("SELECT new TsKvEntity(SUM(CASE WHEN tskv.booleanValue IS NULL THEN 0 ELSE 1 END), " + "SUM(CASE WHEN tskv.strValue IS NULL THEN 0 ELSE 1 END), " + @@ -100,9 +100,9 @@ public interface TsKvRepository extends JpaRepository= :startTs AND tskv.ts < :endTs") TsKvEntity findCount(@Param("entityId") UUID entityId, - @Param("entityKey") int entityKey, - @Param("startTs") long startTs, - @Param("endTs") long endTs); + @Param("entityKey") int entityKey, + @Param("startTs") long startTs, + @Param("endTs") long endTs); @Query("SELECT new TsKvEntity(SUM(COALESCE(tskv.longValue, 0)), " + "SUM(COALESCE(tskv.doubleValue, 0.0)), " + @@ -111,9 +111,9 @@ public interface TsKvRepository extends JpaRepository= :startTs AND tskv.ts < :endTs") TsKvEntity findAvg(@Param("entityId") UUID entityId, - @Param("entityKey") int entityKey, - @Param("startTs") long startTs, - @Param("endTs") long endTs); + @Param("entityKey") int entityKey, + @Param("startTs") long startTs, + @Param("endTs") long endTs); @Query("SELECT new TsKvEntity(SUM(COALESCE(tskv.longValue, 0)), " + "SUM(COALESCE(tskv.doubleValue, 0.0)), " + @@ -122,8 +122,8 @@ public interface TsKvRepository extends JpaRepository= :startTs AND tskv.ts < :endTs") TsKvEntity findSum(@Param("entityId") UUID entityId, - @Param("entityKey") int entityKey, - @Param("startTs") long startTs, - @Param("endTs") long endTs); + @Param("entityKey") int entityKey, + @Param("startTs") long startTs, + @Param("endTs") long endTs); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java index e4aca8ecd1..16655514b3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java @@ -32,7 +32,7 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvEntryAggWrapper; import org.thingsboard.server.dao.nosql.TbResultSet; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.List; import java.util.Optional; import java.util.concurrent.Executor; diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index 6f14b526a5..4be65b3a93 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -52,9 +52,9 @@ import org.thingsboard.server.dao.nosql.TbResultSetFuture; import org.thingsboard.server.dao.sqlts.AggregationTimeseriesDao; import org.thingsboard.server.dao.util.NoSqlTsDao; -import javax.annotation.Nullable; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java index 9fbf796eb0..e70a6ba4ac 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java +++ b/dao/src/main/java/org/thingsboard/server/dao/util/AbstractBufferedRateExecutor.java @@ -41,7 +41,7 @@ import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.nosql.CassandraStatementTask; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.HashMap; import java.util.Map; import java.util.UUID; diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/AbstractJsonSqlTypeDescriptor.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/AbstractJsonSqlTypeDescriptor.java deleted file mode 100644 index 9f69d65fc6..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/AbstractJsonSqlTypeDescriptor.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util.mapping; - -import org.hibernate.type.descriptor.ValueExtractor; -import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.java.JavaTypeDescriptor; -import org.hibernate.type.descriptor.sql.BasicExtractor; -import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; - -import java.sql.CallableStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -public abstract class AbstractJsonSqlTypeDescriptor - implements SqlTypeDescriptor { - - @Override - public int getSqlType() { - return Types.VARCHAR; - } - - @Override - public boolean canBeRemapped() { - return true; - } - - @Override - public ValueExtractor getExtractor( - final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicExtractor(javaTypeDescriptor, this) { - @Override - protected X doExtract( - ResultSet rs, - String name, - WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( - rs.getObject(name), options - ); - } - - @Override - protected X doExtract( - CallableStatement statement, - int index, - WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( - statement.getObject(index), options - ); - } - - @Override - protected X doExtract( - CallableStatement statement, - String name, - WrapperOptions options) throws SQLException { - return javaTypeDescriptor.wrap( - statement.getObject(name), options - ); - } - }; - } - -} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinarySqlTypeDescriptor.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinarySqlTypeDescriptor.java deleted file mode 100644 index e41b998148..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinarySqlTypeDescriptor.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util.mapping; - -import com.fasterxml.jackson.databind.JsonNode; -import org.hibernate.type.descriptor.ValueBinder; -import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.java.JavaTypeDescriptor; -import org.hibernate.type.descriptor.sql.BasicBinder; - -import java.sql.CallableStatement; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -public class JsonBinarySqlTypeDescriptor extends AbstractJsonSqlTypeDescriptor { - - public static final JsonBinarySqlTypeDescriptor INSTANCE = new JsonBinarySqlTypeDescriptor(); - - @Override - public int getSqlType() { - return Types.OTHER; - } - - @Override - public ValueBinder getBinder(final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicBinder(javaTypeDescriptor, this) { - @Override - protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options) throws SQLException { - st.setObject(index, javaTypeDescriptor.unwrap(value, JsonNode.class, options), getSqlType()); - } - - @Override - protected void doBind(CallableStatement st, X value, String name, WrapperOptions options) throws SQLException { - st.setObject(name, javaTypeDescriptor.unwrap(value, JsonNode.class, options), getSqlType()); - } - }; - } -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinaryType.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinaryType.java deleted file mode 100644 index 7b4760a38f..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonBinaryType.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util.mapping; - -import org.hibernate.type.AbstractSingleColumnStandardBasicType; -import org.hibernate.usertype.DynamicParameterizedType; - -import java.util.Properties; - -public class JsonBinaryType extends AbstractSingleColumnStandardBasicType implements DynamicParameterizedType { - - public JsonBinaryType() { - super( - JsonBinarySqlTypeDescriptor.INSTANCE, - new JsonTypeDescriptor() - ); - } - - public String getName() { - return "jsonb"; - } - - @Override - protected boolean registerUnderJavaType() { - return true; - } - - @Override - public void setParameterValues(Properties parameters) { - ((JsonTypeDescriptor) getJavaTypeDescriptor()) - .setParameterValues(parameters); - } -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonConverter.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonConverter.java new file mode 100644 index 0000000000..78c2b8852c --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonConverter.java @@ -0,0 +1,34 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.util.mapping; + +import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; +import org.thingsboard.common.util.JacksonUtil; + +@Converter +public class JsonConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(JsonNode jsonNode) { + return JacksonUtil.toString(jsonNode); + } + + @Override + public JsonNode convertToEntityAttribute(String s) { + return JacksonUtil.toJsonNode(s); + } +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringSqlTypeDescriptor.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringSqlTypeDescriptor.java deleted file mode 100644 index 314eb2751f..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringSqlTypeDescriptor.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util.mapping; - -import org.hibernate.type.descriptor.ValueBinder; -import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.java.JavaTypeDescriptor; -import org.hibernate.type.descriptor.sql.BasicBinder; - -import java.sql.CallableStatement; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -public class JsonStringSqlTypeDescriptor - extends AbstractJsonSqlTypeDescriptor { - - public static final JsonStringSqlTypeDescriptor INSTANCE = - new JsonStringSqlTypeDescriptor(); - - @Override - public ValueBinder getBinder( - final JavaTypeDescriptor javaTypeDescriptor) { - return new BasicBinder(javaTypeDescriptor, this) { - @Override - protected void doBind( - PreparedStatement st, - X value, - int index, - WrapperOptions options) throws SQLException { - st.setString(index, - javaTypeDescriptor.unwrap(value, String.class, options) - ); - } - - @Override - protected void doBind( - CallableStatement st, - X value, - String name, - WrapperOptions options) - throws SQLException { - st.setString(name, - javaTypeDescriptor.unwrap(value, String.class, options - )); - } - }; - } -} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringType.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringType.java deleted file mode 100644 index 42627ef27f..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonStringType.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util.mapping; - -import org.hibernate.type.AbstractSingleColumnStandardBasicType; -import org.hibernate.usertype.DynamicParameterizedType; - -import java.util.Properties; - -public class JsonStringType - extends AbstractSingleColumnStandardBasicType - implements DynamicParameterizedType { - - public JsonStringType() { - super( - JsonStringSqlTypeDescriptor.INSTANCE, - new JsonTypeDescriptor() - ); - } - - public String getName() { - return "json"; - } - - @Override - protected boolean registerUnderJavaType() { - return true; - } - - @Override - public void setParameterValues(Properties parameters) { - ((JsonTypeDescriptor) getJavaTypeDescriptor()) - .setParameterValues(parameters); - } -} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonTypeDescriptor.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonTypeDescriptor.java deleted file mode 100644 index 0654cab84f..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JsonTypeDescriptor.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util.mapping; - -import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.java.AbstractTypeDescriptor; -import org.hibernate.type.descriptor.java.MutableMutabilityPlan; -import org.hibernate.usertype.DynamicParameterizedType; -import org.thingsboard.common.util.JacksonUtil; - -import java.util.Properties; - -/** - * Created by Valerii Sosliuk on 5/12/2017. - */ -public class JsonTypeDescriptor - extends AbstractTypeDescriptor - implements DynamicParameterizedType { - - private Class jsonObjectClass; - - @Override - public void setParameterValues(Properties parameters) { - jsonObjectClass = ( (ParameterType) parameters.get( PARAMETER_TYPE ) ) - .getReturnedClass(); - - } - - public JsonTypeDescriptor() { - super( Object.class, new MutableMutabilityPlan() { - @Override - protected Object deepCopyNotNull(Object value) { - return JacksonUtil.clone(value); - } - }); - } - - @Override - public boolean areEqual(Object one, Object another) { - if ( one == another ) { - return true; - } - if ( one == null || another == null ) { - return false; - } - return JacksonUtil.toJsonNode(JacksonUtil.toString(one)).equals( - JacksonUtil.toJsonNode(JacksonUtil.toString(another))); - } - - @Override - public String toString(Object value) { - return JacksonUtil.toString(value); - } - - @Override - public Object fromString(String string) { - return JacksonUtil.fromString(string, jsonObjectClass); - } - - @SuppressWarnings({ "unchecked" }) - @Override - public X unwrap(Object value, Class type, WrapperOptions options) { - if ( value == null ) { - return null; - } - if ( String.class.isAssignableFrom( type ) ) { - return (X) toString(value); - } - if ( Object.class.isAssignableFrom( type ) ) { - return (X) JacksonUtil.toJsonNode(toString(value)); - } - throw unknownUnwrap( type ); - } - - @Override - public Object wrap(X value, WrapperOptions options) { - if ( value == null ) { - return null; - } - return fromString(value.toString()); - } - -} \ No newline at end of file diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java index 092ea0b8c6..28b5133402 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/notification/channels/impl/SlackNotificationChannel.java @@ -24,7 +24,7 @@ import org.springframework.web.client.RestTemplate; import org.thingsboard.monitoring.data.notification.Notification; import org.thingsboard.monitoring.notification.channels.NotificationChannel; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.time.Duration; import java.util.Map; diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportHealthChecker.java b/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportHealthChecker.java index 0c742e7709..bc6bfb2680 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportHealthChecker.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportHealthChecker.java @@ -31,8 +31,8 @@ import org.thingsboard.monitoring.data.TransportInfo; import org.thingsboard.monitoring.service.MonitoringReporter; import org.thingsboard.monitoring.util.TbStopWatch; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import java.util.UUID; @Slf4j diff --git a/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportMonitoringService.java b/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportMonitoringService.java index d94cbc9624..18a8013e2b 100644 --- a/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportMonitoringService.java +++ b/monitoring/src/main/java/org/thingsboard/monitoring/transport/TransportMonitoringService.java @@ -54,7 +54,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.util.LinkedList; import java.util.List; import java.util.UUID; diff --git a/msa/monitoring/pom.xml b/msa/monitoring/pom.xml index 1fe43219a0..ba96ada39c 100644 --- a/msa/monitoring/pom.xml +++ b/msa/monitoring/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.5.1-SNAPSHOT + 3.6.0-SNAPSHOT msa diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index 0ae03f3980..3e09ac6b98 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -69,6 +69,10 @@ ch.qos.logback logback-classic + + jakarta.annotation + jakarta.annotation-api + org.springframework.boot spring-boot-starter-test diff --git a/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientConfig.java b/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientConfig.java index 1e20a842c3..f697f86e8e 100644 --- a/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientConfig.java +++ b/netty-mqtt/src/main/java/org/thingsboard/mqtt/MqttClientConfig.java @@ -20,8 +20,8 @@ import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.mqtt.MqttVersion; import io.netty.handler.ssl.SslContext; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import java.util.Random; @SuppressWarnings({"WeakerAccess", "unused"}) diff --git a/pom.xml b/pom.xml index 4d456b8f4e..fb667a9526 100755 --- a/pom.xml +++ b/pom.xml @@ -36,20 +36,21 @@ ${project.name} /var/log/${pkg.name} /usr/share/${pkg.name} - 1.3.2 - 2.3.2 - 2.3.2 - 2.7.10 - 2.7.10 - 5.3.26 - 5.5.17 - 5.7.7 - 2.7.10 - 3.8.0 - 0.7.0 - 1.7.32 - 2.17.1 - 1.2.10 + 2.1.1 + 4.0.0 + 2.3.1 + 4.0.2 + 3.1.0 + 3.1.0 + 6.0.9 + 6.1.0 + 6.1.0 + 3.1.0 + 4.3.2 + 0.9.1 + 2.0.7 + 2.19.0 + 1.4.7 0.10 4.15.0 4.0.5 @@ -73,8 +74,8 @@ 2.0.0-M5 2.9.0 2.3.30 - 1.6.2 - 4.2.0 + 2.0.1 + 5.5.0 3.8.1 3.21.9 1.42.1 @@ -82,8 +83,9 @@ 1.18.26 1.2.4 1.2.5 - 4.1.91.Final - 2.0.51.Final + 4.1.93.Final + 2.0.61.Final + 1.1.7 1.7.0 4.8.0 3.0.0-M9 @@ -111,25 +113,25 @@ 1.11.747 1.105.0 2.1.0 - 3.2.0 + 3.6.7 1.5.0 1.5.4 1.9.4 3.2.2 - 1.9.0 + 1.11.0 1.0.4TB 3.4.0 - 8.17.0 - 6.0.20.Final - 3.0.0 - 2.0.1.Final - 1.7.2 + 9.6.1 + 8.0.0.Final + 4.0.2 + 3.0.2 + 1.7.3 2.8.5 4.1.0 2.7.2 1.5.2 - 5.8.2 + 5.9.3 2.6.0 5.13.1 1.3.0 @@ -612,6 +614,7 @@ -Xlint:deprecation -Xlint:removal -Xlint:unchecked + -parameters @@ -663,7 +666,7 @@ ${surefire.version} - --illegal-access=permit -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=20 + -XX:+UseStringDeduplication -XX:MaxGCPauseMillis=20 --add-opens java.base/java.lang.reflect=ALL-UNNAMED @@ -1073,15 +1076,20 @@ test - javax.annotation - javax.annotation-api - ${javax-annotation.version} + jakarta.annotation + jakarta.annotation-api + ${jakarta-annotation.version} jakarta.xml.bind jakarta.xml.bind-api ${jakarta.xml.bind-api.version} + + javax.xml.bind + jaxb-api + ${javax.xml.bind-api.version} + org.glassfish.jaxb jaxb-runtime @@ -1149,6 +1157,16 @@ spring-data-commons ${spring-data.version} + + org.springframework.boot + spring-boot-starter-webflux + ${spring-boot.version} + + + io.projectreactor.netty + reactor-netty-http + ${reactor-netty.version} + org.apache.kafka kafka-clients @@ -1218,7 +1236,7 @@ com.sun.mail - javax.mail + jakarta.mail ${mail.version} @@ -1324,12 +1342,32 @@ netty-transport ${netty.version} + + io.netty + netty-transport-classes-epoll + ${netty.version} + + + io.netty + netty-transport-classes-kqueue + ${netty.version} + + + io.netty + netty-transport-native-epoll + ${netty.version} + io.netty netty-transport-native-epoll ${netty.version} linux-x86_64 + + io.netty + netty-transport-native-kqueue + ${netty.version} + io.netty netty-transport-native-kqueue @@ -1901,6 +1939,10 @@ io.jsonwebtoken jjwt-impl + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + @@ -1910,13 +1952,13 @@ org.glassfish - javax.el - ${javax.el.version} + jakarta.el + ${jakarta.el.version} - javax.validation - validation-api - ${javax.validation-api.version} + jakarta.validation + jakarta.validation-api + ${jakarta.validation-api.version} org.owasp.antisamy diff --git a/rule-engine/rule-engine-api/pom.xml b/rule-engine/rule-engine-api/pom.xml index 47d13e5658..eb57b59c3f 100644 --- a/rule-engine/rule-engine-api/pom.xml +++ b/rule-engine/rule-engine-api/pom.xml @@ -95,7 +95,7 @@ com.sun.mail - javax.mail + jakarta.mail provided diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index 34c6e315f7..c449b590fe 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -84,6 +84,14 @@ spring-web provided + + org.springframework.boot + spring-boot-starter-webflux + + + io.projectreactor.netty + reactor-netty-http + org.apache.kafka kafka-clients @@ -118,7 +126,7 @@ com.sun.mail - javax.mail + jakarta.mail provided diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java index 6f7bb7cf8d..cbb15f5854 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java @@ -39,7 +39,7 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.session.SessionMsgType; import org.thingsboard.server.common.transport.adaptor.JsonConverter; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Set; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java index 3377ac9ded..9d458fdc1c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbSaveToCustomCassandraTableNode.java @@ -43,7 +43,7 @@ import org.thingsboard.server.dao.cassandra.guava.GuavaSession; import org.thingsboard.server.dao.nosql.CassandraStatementTask; import org.thingsboard.server.dao.nosql.TbResultSetFuture; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNode.java index dcaf6698cd..add560431f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckAlarmStatusNode.java @@ -32,8 +32,7 @@ import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; -import javax.annotation.Nullable; -import java.io.IOException; +import jakarta.annotation.Nullable; @Slf4j @RuleNode( diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbNotificationNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbNotificationNodeConfiguration.java index 9508a6a848..27be78a683 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbNotificationNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbNotificationNodeConfiguration.java @@ -19,8 +19,8 @@ import lombok.Data; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.id.NotificationTemplateId; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import java.util.List; import java.util.UUID; diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java index 6e15bd834f..29b2c6029c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java @@ -20,9 +20,9 @@ import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.server.common.data.notification.targets.slack.SlackConversation; import org.thingsboard.server.common.data.notification.targets.slack.SlackConversationType; -import javax.validation.Valid; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; @Data public class TbSlackNodeConfiguration implements NodeConfiguration { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java index 6f9541f5b1..28deb5b4da 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java @@ -15,30 +15,19 @@ */ package org.thingsboard.rule.engine.rest; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.handler.ssl.SslContext; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.conn.ssl.DefaultHostnameVerifier; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; -import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; -import org.apache.http.impl.nio.client.HttpAsyncClients; -import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.HttpComponentsAsyncClientHttpRequestFactory; -import org.springframework.http.client.Netty4ClientHttpRequestFactory; -import org.springframework.util.concurrent.ListenableFuture; -import org.springframework.util.concurrent.ListenableFutureCallback; -import org.springframework.web.client.AsyncRestTemplate; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.client.RestClientResponseException; +import org.springframework.web.reactive.function.BodyInserters; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec; import org.springframework.web.util.UriComponentsBuilder; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; @@ -51,24 +40,20 @@ import org.thingsboard.rule.engine.credentials.CredentialsType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; +import reactor.netty.http.client.HttpClient; +import reactor.netty.transport.ProxyProvider; -import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; -import java.net.Authenticator; -import java.net.PasswordAuthentication; import java.net.URI; import java.nio.charset.StandardCharsets; -import java.security.NoSuchAlgorithmException; -import java.util.Deque; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; @Data @Slf4j -@SuppressWarnings("deprecation") public class TbHttpClient { private static final String STATUS = "status"; @@ -80,86 +65,58 @@ public class TbHttpClient { private final TbRestApiCallNodeConfiguration config; - private EventLoopGroup eventLoopGroup; - private AsyncRestTemplate httpClient; - private Deque>> pendingFutures; + private WebClient webClient; + private Semaphore semaphore; - TbHttpClient(TbRestApiCallNodeConfiguration config, EventLoopGroup eventLoopGroupShared) throws TbNodeException { + TbHttpClient(TbRestApiCallNodeConfiguration config) throws TbNodeException { try { this.config = config; if (config.getMaxParallelRequestsCount() > 0) { - pendingFutures = new ConcurrentLinkedDeque<>(); + semaphore = new Semaphore(config.getMaxParallelRequestsCount()); } + HttpClient httpClient = HttpClient.create(); + if (config.isEnableProxy()) { checkProxyHost(config.getProxyHost()); checkProxyPort(config.getProxyPort()); - String proxyUser; - String proxyPassword; - - CloseableHttpAsyncClient asyncClient; - HttpComponentsAsyncClientHttpRequestFactory requestFactory = new HttpComponentsAsyncClientHttpRequestFactory(); - if (config.isUseSystemProxyProperties()) { checkSystemProxyProperties(); - - asyncClient = HttpAsyncClients.createSystem(); - - proxyUser = System.getProperty("tb.proxy.user"); - proxyPassword = System.getProperty("tb.proxy.password"); - - if (useAuth(proxyUser, proxyPassword)) { - Authenticator.setDefault(new Authenticator() { - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray()); - } - }); - } + //TODO: maybe we should replace it and manually get all system props + httpClient = httpClient.proxyWithSystemProperties(); } else { - HttpAsyncClientBuilder httpAsyncClientBuilder = HttpAsyncClientBuilder.create() - .setSSLHostnameVerifier(new DefaultHostnameVerifier()) - .setSSLContext(SSLContext.getDefault()) - .setProxy(new HttpHost(config.getProxyHost(), config.getProxyPort(), config.getProxyScheme())); - - proxyUser = config.getProxyUser(); - proxyPassword = config.getProxyPassword(); - - if (useAuth(proxyUser, proxyPassword)) { - CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials( - new AuthScope(config.getProxyHost(), config.getProxyPort()), - new UsernamePasswordCredentials(proxyUser, proxyPassword) - ); - httpAsyncClientBuilder.setDefaultCredentialsProvider(credsProvider); - } - asyncClient = httpAsyncClientBuilder.build(); + checkProxyHost(config.getProxyHost()); + checkProxyPort(config.getProxyPort()); + + String proxyUser = config.getProxyUser(); + String proxyPassword = config.getProxyPassword(); + + httpClient = httpClient.proxy(options -> + options.type(ProxyProvider.Proxy.HTTP) + .host(config.getProxyHost()) + .port(config.getProxyPort()) + .username(proxyUser) + .password(u -> proxyPassword)); } - - requestFactory.setAsyncClient(asyncClient); - requestFactory.setReadTimeout(config.getReadTimeoutMs()); - httpClient = new AsyncRestTemplate(requestFactory); - } else if (config.isUseSimpleClientHttpFactory()) { + } else if (!config.isUseSimpleClientHttpFactory()) { if (CredentialsType.CERT_PEM == config.getCredentials().getType()) { throw new TbNodeException("Simple HTTP Factory does not support CERT PEM credentials!"); } - httpClient = new AsyncRestTemplate(); + + httpClient = HttpClient.create(); + } else { - Netty4ClientHttpRequestFactory nettyFactory = new Netty4ClientHttpRequestFactory(getSharedOrCreateEventLoopGroup(eventLoopGroupShared)); - nettyFactory.setSslContext(config.getCredentials().initSslContext()); - nettyFactory.setReadTimeout(config.getReadTimeoutMs()); - httpClient = new AsyncRestTemplate(nettyFactory); + SslContext sslContext = config.getCredentials().initSslContext(); + httpClient = HttpClient.create().secure(t -> t.sslContext(sslContext)); } - } catch (SSLException | NoSuchAlgorithmException e) { - throw new TbNodeException(e); - } - } - EventLoopGroup getSharedOrCreateEventLoopGroup(EventLoopGroup eventLoopGroupShared) { - if (eventLoopGroupShared != null) { - return eventLoopGroupShared; + this.webClient = WebClient.builder() + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .build(); + } catch (SSLException e) { + throw new TbNodeException(e); } - return this.eventLoopGroup = new NioEventLoopGroup(); } private void checkSystemProxyProperties() throws TbNodeException { @@ -176,48 +133,52 @@ public class TbHttpClient { return !StringUtils.isEmpty(proxyUser) && !StringUtils.isEmpty(proxyPassword); } - void destroy() { - if (this.eventLoopGroup != null) { - this.eventLoopGroup.shutdownGracefully(0, 5, TimeUnit.SECONDS); - } - } - public void processMessage(TbContext ctx, TbMsg msg) { - String endpointUrl = TbNodeUtils.processPattern(config.getRestEndpointUrlPattern(), msg); - HttpHeaders headers = prepareHeaders(msg); - HttpMethod method = HttpMethod.valueOf(config.getRequestMethod()); - HttpEntity entity; - if(HttpMethod.GET.equals(method) || HttpMethod.HEAD.equals(method) || - HttpMethod.OPTIONS.equals(method) || HttpMethod.TRACE.equals(method) || - config.isIgnoreRequestBody()) { - entity = new HttpEntity<>(headers); - } else { - entity = new HttpEntity<>(getData(msg), headers); - } - - URI uri = buildEncodedUri(endpointUrl); - ListenableFuture> future = httpClient.exchange( - uri, method, entity, String.class); - future.addCallback(new ListenableFutureCallback>() { - @Override - public void onFailure(Throwable throwable) { - TbMsg next = processException(ctx, msg, throwable); - ctx.tellFailure(next, throwable); + try { + if (semaphore != null) { + semaphore.tryAcquire(config.getReadTimeoutMs(), TimeUnit.MILLISECONDS); } - @Override - public void onSuccess(ResponseEntity responseEntity) { - if (responseEntity.getStatusCode().is2xxSuccessful()) { - TbMsg next = processResponse(ctx, msg, responseEntity); - ctx.tellSuccess(next); - } else { - TbMsg next = processFailureResponse(ctx, msg, responseEntity); - ctx.tellNext(next, TbRelationTypes.FAILURE); - } + String endpointUrl = TbNodeUtils.processPattern(config.getRestEndpointUrlPattern(), msg); + HttpMethod method = HttpMethod.valueOf(config.getRequestMethod()); + URI uri = buildEncodedUri(endpointUrl); + + RequestBodySpec request = webClient + .method(method) + .uri(uri) + .headers(headers -> prepareHeaders(headers, msg)); + + if (HttpMethod.POST.equals(method) || HttpMethod.PUT.equals(method) || + HttpMethod.PATCH.equals(method) || HttpMethod.DELETE.equals(method) || + config.isIgnoreRequestBody()) { + request.body(BodyInserters.fromValue(getData(msg))); } - }); - if (pendingFutures != null) { - processParallelRequests(future); + + request + .retrieve() + .toEntity(String.class) + .subscribe(responseEntity -> { + if (semaphore != null) { + semaphore.release(); + } + + if (responseEntity.getStatusCode().is2xxSuccessful()) { + TbMsg next = processResponse(ctx, msg, responseEntity); + ctx.tellSuccess(next); + } else { + TbMsg next = processFailureResponse(ctx, msg, responseEntity); + ctx.tellNext(next, TbRelationTypes.FAILURE); + } + }, throwable -> { + if (semaphore != null) { + semaphore.release(); // Make sure to release in case of error + } + + TbMsg next = processException(ctx, msg, throwable); + ctx.tellFailure(next, throwable); + }); + } catch (InterruptedException e) { + log.warn("Timeout during waiting for reply!", e); } } @@ -248,7 +209,7 @@ public class TbHttpClient { if (config.isTrimDoubleQuotes()) { final String dataBefore = data; - data = data.replaceAll("^\"|\"$", "");; + data = data.replaceAll("^\"|\"$", ""); log.trace("Trimming double quotes. Before trim: [{}], after trim: [{}]", dataBefore, data); } @@ -257,9 +218,10 @@ public class TbHttpClient { private TbMsg processResponse(TbContext ctx, TbMsg origMsg, ResponseEntity response) { TbMsgMetaData metaData = origMsg.getMetaData(); - metaData.putValue(STATUS, response.getStatusCode().name()); + HttpStatus httpStatus = (HttpStatus) response.getStatusCode(); + metaData.putValue(STATUS, httpStatus.name()); metaData.putValue(STATUS_CODE, response.getStatusCode().value() + ""); - metaData.putValue(STATUS_REASON, response.getStatusCode().getReasonPhrase()); + metaData.putValue(STATUS_REASON, httpStatus.getReasonPhrase()); headersToMetaData(response.getHeaders(), metaData::putValue); String body = response.getBody() == null ? "{}" : response.getBody(); return ctx.transformMsg(origMsg, origMsg.getType(), origMsg.getOriginator(), metaData, body); @@ -281,10 +243,11 @@ public class TbHttpClient { } private TbMsg processFailureResponse(TbContext ctx, TbMsg origMsg, ResponseEntity response) { + HttpStatus httpStatus = (HttpStatus) response.getStatusCode(); TbMsgMetaData metaData = origMsg.getMetaData(); - metaData.putValue(STATUS, response.getStatusCode().name()); + metaData.putValue(STATUS, httpStatus.name()); metaData.putValue(STATUS_CODE, response.getStatusCode().value() + ""); - metaData.putValue(STATUS_REASON, response.getStatusCode().getReasonPhrase()); + metaData.putValue(STATUS_REASON, httpStatus.getReasonPhrase()); metaData.putValue(ERROR_BODY, response.getBody()); headersToMetaData(response.getHeaders(), metaData::putValue); return ctx.transformMsg(origMsg, origMsg.getType(), origMsg.getOriginator(), metaData, origMsg.getData()); @@ -302,8 +265,7 @@ public class TbHttpClient { return ctx.transformMsg(origMsg, origMsg.getType(), origMsg.getOriginator(), metaData, origMsg.getData()); } - private HttpHeaders prepareHeaders(TbMsg msg) { - HttpHeaders headers = new HttpHeaders(); + private void prepareHeaders(HttpHeaders headers, TbMsg msg) { config.getHeaders().forEach((k, v) -> headers.add(TbNodeUtils.processPattern(k, msg), TbNodeUtils.processPattern(v, msg))); ClientCredentials credentials = config.getCredentials(); if (CredentialsType.BASIC == credentials.getType()) { @@ -312,26 +274,6 @@ public class TbHttpClient { String encodedAuthString = new String(Base64.encodeBase64(authString.getBytes(StandardCharsets.UTF_8))); headers.add("Authorization", "Basic " + encodedAuthString); } - return headers; - } - - private void processParallelRequests(ListenableFuture> future) { - pendingFutures.add(future); - if (pendingFutures.size() > config.getMaxParallelRequestsCount()) { - for (int i = 0; i < config.getMaxParallelRequestsCount(); i++) { - try { - ListenableFuture> pendingFuture = pendingFutures.removeFirst(); - try { - pendingFuture.get(config.getReadTimeoutMs(), TimeUnit.MILLISECONDS); - } catch (Exception e) { - log.warn("Timeout during waiting for reply!", e); - pendingFuture.cancel(true); - } - } catch (Exception e) { - log.warn("Failure during waiting for reply!", e); - } - } - } } private static void checkProxyHost(String proxyHost) throws TbNodeException { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java index d2356c69f7..8197315e6c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbRestApiCallNode.java @@ -51,7 +51,7 @@ public class TbRestApiCallNode implements TbNode { @Override public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException { TbRestApiCallNodeConfiguration config = TbNodeUtils.convert(configuration, TbRestApiCallNodeConfiguration.class); - httpClient = new TbHttpClient(config, ctx.getSharedEventLoop()); + httpClient = new TbHttpClient(config); useRedisQueueForMsgPersistence = config.isUseRedisQueueForMsgPersistence(); if (useRedisQueueForMsgPersistence) { log.warn("[{}][{}] Usage of Redis Template is deprecated starting 2.5 and will have no affect", ctx.getTenantId(), ctx.getSelfId()); @@ -63,11 +63,4 @@ public class TbRestApiCallNode implements TbNode { httpClient.processMessage(ctx, msg); } - @Override - public void destroy() { - if (this.httpClient != null) { - this.httpClient.destroy(); - } - } - } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesDeleteNodeCallback.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesDeleteNodeCallback.java index 200ab76263..a1c6b11659 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesDeleteNodeCallback.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesDeleteNodeCallback.java @@ -19,7 +19,7 @@ import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.server.common.msg.TbMsg; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.List; @Slf4j diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesUpdateNodeCallback.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesUpdateNodeCallback.java index 3696812d87..6e94b85be5 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesUpdateNodeCallback.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/AttributesUpdateNodeCallback.java @@ -19,7 +19,7 @@ import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.msg.TbMsg; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; import java.util.List; public class AttributesUpdateNodeCallback extends TelemetryNodeCallback { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TelemetryNodeCallback.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TelemetryNodeCallback.java index ce3e9d2455..9958ee106e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TelemetryNodeCallback.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TelemetryNodeCallback.java @@ -20,7 +20,7 @@ import lombok.Data; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.server.common.msg.TbMsg; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; /** * Created by ashvayka on 02.04.18. diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java index 14ab6cfbbf..46e31d0f69 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbHttpClientTest.java @@ -16,11 +16,8 @@ package org.thingsboard.rule.engine.rest; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; import org.assertj.core.api.Assertions; import org.awaitility.Awaitility; -import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -28,7 +25,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.mockserver.integration.ClientAndServer; import org.springframework.util.LinkedMultiValueMap; -import org.springframework.web.client.AsyncRestTemplate; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; @@ -41,9 +37,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.willCallRealMethod; @@ -57,32 +50,11 @@ import static org.mockserver.model.HttpResponse.response; public class TbHttpClientTest { - EventLoopGroup eventLoop; TbHttpClient client; @Before public void setUp() throws Exception { client = mock(TbHttpClient.class); - willCallRealMethod().given(client).getSharedOrCreateEventLoopGroup(any()); - } - - @After - public void tearDown() throws Exception { - if (eventLoop != null) { - eventLoop.shutdownGracefully(); - } - } - - @Test - public void givenSharedEventLoop_whenGetEventLoop_ThenReturnShared() { - eventLoop = mock(EventLoopGroup.class); - assertThat(client.getSharedOrCreateEventLoopGroup(eventLoop), is(eventLoop)); - } - - @Test - public void givenNull_whenGetEventLoop_ThenReturnShared() { - eventLoop = client.getSharedOrCreateEventLoopGroup(null); - assertThat(eventLoop, instanceOf(NioEventLoopGroup.class)); } @Test @@ -139,10 +111,7 @@ public class TbHttpClientTest { config.setRestEndpointUrlPattern(endpointUrl); config.setUseSimpleClientHttpFactory(true); - var asyncRestTemplate = new AsyncRestTemplate(); - - var httpClient = new TbHttpClient(config, eventLoop); - httpClient.setHttpClient(asyncRestTemplate); + var httpClient = new TbHttpClient(config); var msg = TbMsg.newMsg("GET", new DeviceId(EntityId.NULL_UUID), TbMsgMetaData.EMPTY, "{}"); var successMsg = TbMsg.newMsg( diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java index 9185a31118..2b6698d415 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java @@ -16,7 +16,6 @@ package org.thingsboard.rule.engine.rest; import com.datastax.oss.driver.api.core.uuid.Uuids; -import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; @@ -49,14 +48,13 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class TbRestApiCallNodeTest { - + private TbRestApiCallNode restNode; @Mock @@ -68,17 +66,17 @@ public class TbRestApiCallNodeTest { private RuleChainId ruleChainId = new RuleChainId(Uuids.timeBased()); private RuleNodeId ruleNodeId = new RuleNodeId(Uuids.timeBased()); - private HttpServer server; + private HttpServer server; public void setupServer(String pattern, HttpRequestHandler handler) throws IOException { - SocketConfig config = SocketConfig.custom().setSoReuseAddress(true).setTcpNoDelay(true).build(); - server = ServerBootstrap.bootstrap() + SocketConfig config = SocketConfig.custom().setSoReuseAddress(true).setTcpNoDelay(true).build(); + server = ServerBootstrap.bootstrap() .setSocketConfig(config) - .registerHandler(pattern, handler) - .create(); + .registerHandler(pattern, handler) + .create(); server.start(); } - + private void initWithConfig(TbRestApiCallNodeConfiguration config) { try { TbNodeConfiguration nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config)); @@ -93,19 +91,18 @@ public class TbRestApiCallNodeTest { public void teardown() { server.stop(); } - + @Test public void deleteRequestWithoutBody() throws IOException, InterruptedException { final CountDownLatch latch = new CountDownLatch(1); final String path = "/path/to/delete"; - setupServer("*", new HttpRequestHandler() { - - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) - throws HttpException, IOException { + setupServer("*", new HttpRequestHandler() { + + @Override + public void handle(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException, IOException { try { assertEquals("Request path matches", request.getRequestLine().getUri(), path); - assertFalse("Content-Type not included", request.containsHeader("Content-Type")); assertTrue("Custom header included", request.containsHeader("Foo")); assertEquals("Custom header value", "Bar", request.getFirstHeader("Foo").getValue()); response.setStatusCode(200); @@ -121,13 +118,13 @@ public class TbRestApiCallNodeTest { } } }).start(); - } catch ( Exception e ) { + } catch (Exception e) { System.out.println("Exception handling request: " + e.toString()); e.printStackTrace(); latch.countDown(); } } - }); + }); TbRestApiCallNodeConfiguration config = new TbRestApiCallNodeConfiguration().defaultConfiguration(); config.setRequestMethod("DELETE"); @@ -136,7 +133,7 @@ public class TbRestApiCallNodeTest { config.setRestEndpointUrlPattern(String.format("http://localhost:%d%s", server.getLocalPort(), path)); initWithConfig(config); - TbMsg msg = TbMsg.newMsg( "USER", originator, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); + TbMsg msg = TbMsg.newMsg("USER", originator, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); restNode.onMsg(ctx, msg); assertTrue("Server handled request", latch.await(10, TimeUnit.SECONDS)); @@ -167,7 +164,7 @@ public class TbRestApiCallNodeTest { try { assertEquals("Request path matches", path, request.getRequestLine().getUri()); assertTrue("Content-Type included", request.containsHeader("Content-Type")); - assertEquals("Content-Type value", "text/plain;charset=ISO-8859-1", + assertEquals("Content-Type value", "text/plain;charset=UTF-8", request.getFirstHeader("Content-Type").getValue()); assertTrue("Content-Length included", request.containsHeader("Content-Length")); assertEquals("Content-Length value", "2", @@ -187,7 +184,7 @@ public class TbRestApiCallNodeTest { } } }).start(); - } catch ( Exception e ) { + } catch (Exception e) { System.out.println("Exception handling request: " + e.toString()); e.printStackTrace(); latch.countDown(); @@ -202,7 +199,7 @@ public class TbRestApiCallNodeTest { config.setRestEndpointUrlPattern(String.format("http://localhost:%d%s", server.getLocalPort(), path)); initWithConfig(config); - TbMsg msg = TbMsg.newMsg( "USER", originator, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); + TbMsg msg = TbMsg.newMsg("USER", originator, metaData, TbMsgDataType.JSON, "{}", ruleChainId, ruleNodeId); restNode.onMsg(ctx, msg); assertTrue("Server handled request", latch.await(10, TimeUnit.SECONDS)); @@ -213,7 +210,7 @@ public class TbRestApiCallNodeTest { ArgumentCaptor metadataCaptor = ArgumentCaptor.forClass(TbMsgMetaData.class); ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(String.class); verify(ctx).transformMsg(msgCaptor.capture(), typeCaptor.capture(), originatorCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture()); - + assertEquals("USER", typeCaptor.getValue()); assertEquals(originator, originatorCaptor.getValue()); assertNotSame(metaData, metadataCaptor.getValue()); From ae2fd08c36d4d335da2969b105b0a442b87e8be8 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 13 Mar 2023 22:32:44 +0100 Subject: [PATCH 12/61] refactored HttpClient proxy --- .../rule/engine/rest/TbHttpClient.java | 122 +++++++++++++++--- 1 file changed, 102 insertions(+), 20 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java index 28deb5b4da..7a5ca407af 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.rest; import io.netty.handler.ssl.SslContext; +import io.netty.handler.timeout.ReadTimeoutHandler; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; @@ -48,6 +49,7 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; @@ -63,6 +65,19 @@ public class TbHttpClient { private static final String ERROR_BODY = "error_body"; private static final String ERROR_SYSTEM_PROPERTIES = "Didn't set any system proxy properties. Should be added next system proxy properties: \"http.proxyHost\" and \"http.proxyPort\" or \"https.proxyHost\" and \"https.proxyPort\" or \"socksProxyHost\" and \"socksProxyPort\""; + private static final String HTTP_PROXY_HOST = "http.proxyHost"; + private static final String HTTP_PROXY_PORT = "http.proxyPort"; + private static final String HTTPS_PROXY_HOST = "https.proxyHost"; + private static final String HTTPS_PROXY_PORT = "https.proxyPort"; + + private static final String SOCKS_PROXY_HOST = "socksProxyHost"; + private static final String SOCKS_PROXY_PORT = "socksProxyPort"; + private static final String SOCKS_VERSION = "socksProxyVersion"; + private static final String SOCKS_VERSION_5 = "5"; + private static final String SOCKS_VERSION_4 = "4"; + public static final String PROXY_USER = "tb.proxy.user"; + public static final String PROXY_PASSWORD = "tb.proxy.password"; + private final TbRestApiCallNodeConfiguration config; private WebClient webClient; @@ -75,29 +90,29 @@ public class TbHttpClient { semaphore = new Semaphore(config.getMaxParallelRequestsCount()); } - HttpClient httpClient = HttpClient.create(); + HttpClient httpClient = HttpClient.create() + .doOnConnected(c -> + c.addHandlerLast(new ReadTimeoutHandler(config.getReadTimeoutMs(), TimeUnit.MILLISECONDS))); if (config.isEnableProxy()) { - checkProxyHost(config.getProxyHost()); - checkProxyPort(config.getProxyPort()); - if (config.isUseSystemProxyProperties()) { checkSystemProxyProperties(); - //TODO: maybe we should replace it and manually get all system props - httpClient = httpClient.proxyWithSystemProperties(); + httpClient = httpClient.proxy(this::createSystemProxyProvider); } else { checkProxyHost(config.getProxyHost()); checkProxyPort(config.getProxyPort()); - String proxyUser = config.getProxyUser(); String proxyPassword = config.getProxyPassword(); - httpClient = httpClient.proxy(options -> - options.type(ProxyProvider.Proxy.HTTP) - .host(config.getProxyHost()) - .port(config.getProxyPort()) - .username(proxyUser) - .password(u -> proxyPassword)); + httpClient = httpClient.proxy(options -> { + var o = options.type(ProxyProvider.Proxy.HTTP) + .host(config.getProxyHost()) + .port(config.getProxyPort()); + + if (useAuth(proxyUser, proxyPassword)) { + o.username(proxyUser).password(u -> proxyPassword); + } + }); } } else if (!config.isUseSimpleClientHttpFactory()) { if (CredentialsType.CERT_PEM == config.getCredentials().getType()) { @@ -135,8 +150,9 @@ public class TbHttpClient { public void processMessage(TbContext ctx, TbMsg msg) { try { - if (semaphore != null) { - semaphore.tryAcquire(config.getReadTimeoutMs(), TimeUnit.MILLISECONDS); + if (semaphore != null && !semaphore.tryAcquire(config.getReadTimeoutMs(), TimeUnit.MILLISECONDS)) { + ctx.tellFailure(msg, new RuntimeException("Timeout during waiting for reply!")); + return; } String endpointUrl = TbNodeUtils.processPattern(config.getRestEndpointUrlPattern(), msg); @@ -171,7 +187,7 @@ public class TbHttpClient { } }, throwable -> { if (semaphore != null) { - semaphore.release(); // Make sure to release in case of error + semaphore.release(); } TbMsg next = processException(ctx, msg, throwable); @@ -276,15 +292,81 @@ public class TbHttpClient { } } - private static void checkProxyHost(String proxyHost) throws TbNodeException { + private static void checkProxyHost(String proxyHost) { if (StringUtils.isEmpty(proxyHost)) { - throw new TbNodeException("Proxy host can't be empty"); + throw new IllegalArgumentException("Proxy host can't be empty"); } } - private static void checkProxyPort(int proxyPort) throws TbNodeException { + private static void checkProxyPort(int proxyPort) { if (proxyPort < 0 || proxyPort > 65535) { - throw new TbNodeException("Proxy port out of range:" + proxyPort); + throw new IllegalArgumentException("Proxy port out of range:" + proxyPort); + } + } + + private void createSystemProxyProvider(ProxyProvider.TypeSpec option) { + Properties properties = System.getProperties(); + if (properties.containsKey(HTTP_PROXY_HOST) || properties.containsKey(HTTPS_PROXY_HOST)) { + createHttpProxyFrom(option, properties); + } + if (properties.containsKey(SOCKS_PROXY_HOST)) { + createSocksProxyFrom(option, properties); + } + } + + private void createHttpProxyFrom(ProxyProvider.TypeSpec option, Properties properties) { + String hostProperty; + String portProperty; + if (properties.containsKey(HTTPS_PROXY_HOST)) { + hostProperty = HTTPS_PROXY_HOST; + portProperty = HTTPS_PROXY_PORT; + } else { + hostProperty = HTTP_PROXY_HOST; + portProperty = HTTP_PROXY_PORT; + } + + String hostname = properties.getProperty(hostProperty); + int port = Integer.parseInt(properties.getProperty(portProperty)); + + checkProxyHost(config.getProxyHost()); + checkProxyPort(config.getProxyPort()); + + var proxy = option + .type(ProxyProvider.Proxy.HTTP) + .host(hostname) + .port(port); + + var proxyUser = properties.getProperty(PROXY_USER); + var proxyPassword = properties.getProperty(PROXY_PASSWORD); + + if (useAuth(proxyUser, proxyPassword)) { + proxy.username(proxyUser).password(u -> proxyPassword); + } + } + + private void createSocksProxyFrom(ProxyProvider.TypeSpec option, Properties properties) { + String hostname = properties.getProperty(SOCKS_PROXY_HOST); + String version = properties.getProperty(SOCKS_VERSION, SOCKS_VERSION_5); + if (!SOCKS_VERSION_5.equals(version) && !SOCKS_VERSION_4.equals(version)) { + throw new IllegalArgumentException(String.format("Wrong socks version %s! Supported only socks versions 4 and 5.", version)); + } + + ProxyProvider.Proxy type = SOCKS_VERSION_5.equals(version) ? ProxyProvider.Proxy.SOCKS5 : ProxyProvider.Proxy.SOCKS4; + int port = Integer.parseInt(properties.getProperty(SOCKS_PROXY_PORT)); + + checkProxyHost(config.getProxyHost()); + checkProxyPort(config.getProxyPort()); + + ProxyProvider.Builder proxy = option + .type(type) + .host(hostname) + .port(port); + + var proxyUser = properties.getProperty(PROXY_USER); + var proxyPassword = properties.getProperty(PROXY_PASSWORD); + + if (useAuth(proxyUser, proxyPassword)) { + proxy.username(proxyUser).password(u -> proxyPassword); } } From ce87bc5e13bf883d5f9e2001244000736bd51249 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 12 Jun 2023 13:25:37 +0200 Subject: [PATCH 13/61] to springdoc migration --- application/pom.xml | 4 +- .../server/ThingsboardInstallApplication.java | 3 +- .../server/config/SwaggerConfiguration.java | 506 +++++++----------- .../config/annotations/ApiOperation.java | 45 ++ .../controller/AbstractRpcController.java | 2 +- .../server/controller/AdminController.java | 24 +- .../controller/AlarmCommentController.java | 31 +- .../server/controller/AlarmController.java | 159 +++--- .../server/controller/AssetController.java | 147 ++--- .../controller/AssetProfileController.java | 57 +- .../server/controller/AuditLogController.java | 89 +-- .../server/controller/AuthController.java | 20 +- .../server/controller/BaseController.java | 6 +- .../ComponentDescriptorController.java | 15 +- .../controller/ControllerConstants.java | 35 +- .../server/controller/CustomerController.java | 29 +- .../controller/DashboardController.java | 145 +++-- .../server/controller/DeviceController.java | 155 +++--- .../controller/DeviceProfileController.java | 69 ++- .../server/controller/EdgeController.java | 139 ++--- .../controller/EdgeEventController.java | 27 +- .../EntitiesVersionControlController.java | 70 +-- .../controller/EntityQueryController.java | 18 +- .../controller/EntityRelationController.java | 98 ++-- .../controller/EntityViewController.java | 94 ++-- .../server/controller/EventController.java | 89 +-- .../server/controller/Lwm2mController.java | 11 +- .../controller/NotificationController.java | 30 +- .../NotificationRuleController.java | 16 +- .../NotificationTargetController.java | 22 +- .../NotificationTemplateController.java | 20 +- .../OAuth2ConfigTemplateController.java | 6 +- .../server/controller/OAuth2Controller.java | 16 +- .../controller/OtaPackageController.java | 69 ++- .../server/controller/QueueController.java | 30 +- .../server/controller/RpcV1Controller.java | 12 +- .../server/controller/RpcV2Controller.java | 56 +- .../controller/RuleChainController.java | 76 +-- .../controller/SystemInfoController.java | 6 +- .../controller/TbResourceController.java | 59 +- .../controller/TelemetryController.java | 253 +++++---- .../server/controller/TenantController.java | 36 +- .../controller/TenantProfileController.java | 38 +- .../TwoFactorAuthConfigController.java | 11 +- .../controller/TwoFactorAuthController.java | 4 +- .../controller/UiSettingsController.java | 2 +- .../server/controller/UserController.java | 97 ++-- .../controller/WidgetTypeController.java | 28 +- .../controller/WidgetsBundleController.java | 23 +- .../controller/plugin/TbWebSocketHandler.java | 8 +- ...ThingsboardCredentialsExpiredResponse.java | 7 +- .../exception/ThingsboardErrorResponse.java | 17 +- .../security/auth/rest/LoginRequest.java | 9 +- .../security/auth/rest/LoginResponse.java | 9 +- .../security/model/ActivateUserRequest.java | 9 +- .../security/model/ChangePasswordRequest.java | 9 +- .../model/ResetPasswordEmailRequest.java | 7 +- .../security/model/ResetPasswordRequest.java | 9 +- .../service/telemetry/AttributeData.java | 11 +- .../server/service/telemetry/TsData.java | 9 +- ...ngfoxHandlerProviderBeanPostProcessor.java | 59 -- .../src/main/resources/thingsboard.yml | 8 +- common/data/pom.xml | 4 +- .../server/common/data/AdminSettings.java | 15 +- .../server/common/data/Customer.java | 31 +- .../server/common/data/Dashboard.java | 6 +- .../server/common/data/DashboardInfo.java | 23 +- .../server/common/data/Device.java | 29 +- .../server/common/data/DeviceInfo.java | 13 +- .../server/common/data/DeviceProfile.java | 41 +- .../server/common/data/DeviceProfileInfo.java | 12 +- .../server/common/data/EntityInfo.java | 9 +- .../server/common/data/EntityView.java | 24 +- .../server/common/data/EntityViewInfo.java | 6 +- .../server/common/data/EventInfo.java | 17 +- .../server/common/data/ExportableEntity.java | 4 +- .../server/common/data/HomeDashboard.java | 7 +- .../server/common/data/HomeDashboardInfo.java | 9 +- .../server/common/data/OtaPackage.java | 7 +- .../server/common/data/OtaPackageInfo.java | 37 +- .../SaveDeviceWithCredentialsRequest.java | 9 +- .../data/SaveOtaPackageInfoRequest.java | 7 +- .../server/common/data/ShortCustomerInfo.java | 11 +- .../server/common/data/SystemInfo.java | 6 +- .../server/common/data/SystemInfoData.java | 18 +- .../server/common/data/TbResource.java | 6 +- .../server/common/data/TbResourceInfo.java | 19 +- .../server/common/data/Tenant.java | 35 +- .../server/common/data/TenantInfo.java | 7 +- .../server/common/data/TenantProfile.java | 19 +- .../server/common/data/UpdateMessage.java | 17 +- .../thingsboard/server/common/data/User.java | 27 +- .../server/common/data/UserEmailInfo.java | 13 +- .../server/common/data/alarm/Alarm.java | 49 +- .../common/data/alarm/AlarmComment.java | 19 +- .../common/data/alarm/AlarmCommentInfo.java | 11 +- .../AlarmCreateOrUpdateActiveRequest.java | 20 +- .../server/common/data/alarm/AlarmInfo.java | 11 +- .../data/alarm/AlarmPropagationInfo.java | 10 +- .../common/data/alarm/AlarmUpdateRequest.java | 16 +- .../server/common/data/asset/Asset.java | 23 +- .../server/common/data/asset/AssetInfo.java | 11 +- .../common/data/asset/AssetProfile.java | 27 +- .../common/data/asset/AssetProfileInfo.java | 8 +- .../common/data/asset/AssetSearchQuery.java | 8 +- .../server/common/data/audit/AuditLog.java | 29 +- .../common/data/device/DeviceSearchQuery.java | 11 +- .../data/DefaultDeviceConfiguration.java | 4 +- .../data/device/data/DeviceConfiguration.java | 4 +- .../common/data/device/data/DeviceData.java | 9 +- .../data/DeviceTransportConfiguration.java | 4 +- .../data/device/profile/AlarmCondition.java | 9 +- .../device/profile/AlarmConditionFilter.java | 13 +- .../profile/AlarmConditionFilterKey.java | 9 +- .../common/data/device/profile/AlarmRule.java | 13 +- .../device/profile/DeviceProfileAlarm.java | 21 +- .../device/profile/DeviceProfileData.java | 13 +- .../bootstrap/LwM2MServerSecurityConfig.java | 43 +- .../LwM2MServerSecurityConfigDefault.java | 9 +- .../server/common/data/edge/Edge.java | 25 +- .../data/edge/EdgeInstallInstructions.java | 7 +- .../common/data/edge/EdgeSearchQuery.java | 8 +- .../entityview/EntityViewSearchQuery.java | 11 +- .../common/data/event/DebugEventFilter.java | 11 +- .../common/data/event/ErrorEventFilter.java | 11 +- .../server/common/data/event/EventFilter.java | 7 +- .../data/event/LifeCycleEventFilter.java | 13 +- .../data/event/RuleChainDebugEventFilter.java | 7 +- .../data/event/RuleNodeDebugEventFilter.java | 21 +- .../data/event/StatisticsEventFilter.java | 15 +- .../server/common/data/id/AlarmCommentId.java | 4 +- .../server/common/data/id/AlarmId.java | 7 +- .../common/data/id/ApiUsageStateId.java | 7 +- .../server/common/data/id/AssetId.java | 7 +- .../server/common/data/id/AssetProfileId.java | 4 +- .../server/common/data/id/CustomerId.java | 7 +- .../server/common/data/id/DashboardId.java | 7 +- .../server/common/data/id/DeviceId.java | 7 +- .../common/data/id/DeviceProfileId.java | 4 +- .../server/common/data/id/EdgeId.java | 4 +- .../server/common/data/id/EntityId.java | 9 +- .../server/common/data/id/EntityViewId.java | 4 +- .../server/common/data/id/OtaPackageId.java | 4 +- .../server/common/data/id/RpcId.java | 4 +- .../server/common/data/id/RuleChainId.java | 4 +- .../server/common/data/id/RuleNodeId.java | 4 +- .../server/common/data/id/TbResourceId.java | 4 +- .../server/common/data/id/TenantId.java | 4 +- .../common/data/id/TenantProfileId.java | 4 +- .../server/common/data/id/UUIDBased.java | 7 +- .../server/common/data/id/UserId.java | 4 +- .../server/common/data/id/WidgetTypeId.java | 4 +- .../common/data/id/WidgetsBundleId.java | 4 +- .../common/data/lwm2m/LwM2mInstance.java | 9 +- .../server/common/data/lwm2m/LwM2mObject.java | 17 +- .../data/lwm2m/LwM2mResourceObserve.java | 17 +- .../data/oauth2/OAuth2BasicMapperConfig.java | 21 +- .../common/data/oauth2/OAuth2ClientInfo.java | 11 +- .../OAuth2ClientRegistrationTemplate.java | 31 +- .../common/data/oauth2/OAuth2DomainInfo.java | 9 +- .../server/common/data/oauth2/OAuth2Info.java | 9 +- .../data/oauth2/OAuth2MapperConfig.java | 12 +- .../common/data/oauth2/OAuth2MobileInfo.java | 9 +- .../common/data/oauth2/OAuth2ParamsInfo.java | 11 +- .../data/oauth2/OAuth2RegistrationInfo.java | 33 +- .../data/objects/AttributesEntityView.java | 11 +- .../data/objects/TelemetryEntityView.java | 9 +- .../server/common/data/page/PageData.java | 13 +- .../data/plugin/ComponentDescriptor.java | 23 +- .../common/data/query/EntityCountQuery.java | 4 +- .../server/common/data/query/EntityKey.java | 4 +- .../server/common/data/query/KeyFilter.java | 4 +- .../common/data/relation/EntityRelation.java | 15 +- .../data/relation/EntityRelationInfo.java | 6 +- .../data/relation/EntityRelationsQuery.java | 9 +- .../relation/RelationEntityTypeFilter.java | 9 +- .../relation/RelationsSearchParameters.java | 17 +- .../server/common/data/rpc/Rpc.java | 23 +- .../rule/DefaultRuleChainCreateRequest.java | 7 +- .../common/data/rule/NodeConnectionInfo.java | 11 +- .../server/common/data/rule/RuleChain.java | 23 +- .../data/rule/RuleChainConnectionInfo.java | 13 +- .../common/data/rule/RuleChainData.java | 9 +- .../common/data/rule/RuleChainMetaData.java | 15 +- .../data/rule/RuleChainOutputLabelsUsage.java | 15 +- .../server/common/data/rule/RuleNode.java | 23 +- .../data/security/DeviceCredentials.java | 17 +- .../common/data/security/model/JwtPair.java | 9 +- .../data/security/model/JwtSettings.java | 13 +- .../data/security/model/SecuritySettings.java | 11 +- .../security/model/UserPasswordPolicy.java | 21 +- .../settings/AbstractUserDashboardInfo.java | 9 +- .../settings/LastVisitedDashboardInfo.java | 9 +- .../data/settings/StarredDashboardInfo.java | 7 +- .../data/settings/UserDashboardsInfo.java | 9 +- .../common/data/settings/UserSettings.java | 11 +- .../AwsSnsSmsProviderConfiguration.java | 11 +- .../config/SmppSmsProviderConfiguration.java | 34 +- .../data/sms/config/TestSmsRequest.java | 11 +- .../TwilioSmsProviderConfiguration.java | 11 +- .../tenant/profile/TenantProfileData.java | 9 +- .../common/data/widget/BaseWidgetType.java | 14 +- .../server/common/data/widget/WidgetType.java | 4 +- .../common/data/widget/WidgetTypeDetails.java | 6 +- .../common/data/widget/WidgetTypeInfo.java | 8 +- .../common/data/widget/WidgetsBundle.java | 21 +- .../transport/http/DeviceApiController.java | 133 ++--- pom.xml | 30 +- 208 files changed, 2462 insertions(+), 2712 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java delete mode 100644 application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java diff --git a/application/pom.xml b/application/pom.xml index 1838c97c65..f473986211 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -262,8 +262,8 @@ opensmpp-core - org.thingsboard - springfox-boot-starter + org.springdoc + springdoc-openapi-starter-webmvc-ui com.sun.winsw diff --git a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java index b780f0e8cd..5b80e21fe6 100644 --- a/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java +++ b/application/src/main/java/org/thingsboard/server/ThingsboardInstallApplication.java @@ -33,8 +33,7 @@ import java.util.Arrays; "org.thingsboard.server.dao", "org.thingsboard.server.common.stats", "org.thingsboard.server.common.transport.config.ssl", - "org.thingsboard.server.cache", - "org.thingsboard.server.springfox" + "org.thingsboard.server.cache" }) public class ThingsboardInstallApplication { diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java index c7616ed865..50104e866d 100644 --- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java @@ -15,84 +15,58 @@ */ package org.thingsboard.server.config; -import com.fasterxml.classmate.TypeResolver; +import io.swagger.v3.core.converter.AnnotatedType; +import io.swagger.v3.core.converter.ModelConverters; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.examples.Example; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.tags.Tag; import lombok.extern.slf4j.Slf4j; +import org.springdoc.core.customizers.OpenApiCustomizer; +import org.springdoc.core.models.GroupedOpenApi; +import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Profile; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; -import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.exception.ThingsboardCredentialsExpiredResponse; import org.thingsboard.server.exception.ThingsboardErrorResponse; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.rest.LoginRequest; import org.thingsboard.server.service.security.auth.rest.LoginResponse; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.ExampleBuilder; -import springfox.documentation.builders.OperationBuilder; -import springfox.documentation.builders.RepresentationBuilder; -import springfox.documentation.builders.RequestParameterBuilder; -import springfox.documentation.builders.ResponseBuilder; -import springfox.documentation.schema.Example; -import springfox.documentation.service.ApiDescription; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.ApiListing; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.Contact; -import springfox.documentation.service.HttpLoginPasswordScheme; -import springfox.documentation.service.ParameterType; -import springfox.documentation.service.Response; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.service.SecurityScheme; -import springfox.documentation.service.Tag; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.ApiListingBuilderPlugin; -import springfox.documentation.spi.service.ApiListingScannerPlugin; -import springfox.documentation.spi.service.contexts.ApiListingContext; -import springfox.documentation.spi.service.contexts.DocumentationContext; -import springfox.documentation.spi.service.contexts.OperationContext; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator; -import springfox.documentation.swagger.common.SwaggerPluginSupport; -import springfox.documentation.swagger.web.DocExpansion; -import springfox.documentation.swagger.web.ModelRendering; -import springfox.documentation.swagger.web.OperationsSorter; -import springfox.documentation.swagger.web.UiConfiguration; -import springfox.documentation.swagger.web.UiConfigurationBuilder; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; + import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Predicate; +import java.util.Map; -import static com.google.common.collect.Lists.newArrayList; -import static java.util.function.Predicate.not; -import static springfox.documentation.builders.PathSelectors.any; -import static springfox.documentation.builders.PathSelectors.regex; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @Slf4j -//@Configuration +@Configuration @TbCoreComponent @Profile("!test") public class SwaggerConfiguration { - @Value("${swagger.enabled:true}") - private boolean enabled; - @Value("${swagger.api_path_regex}") - private String apiPathRegex; - @Value("${swagger.security_path_regex}") - private String securityPathRegex; + public static final String LOGIN_ENDPOINT = "/api/auth/login"; + + @Value("${swagger.api_path:/api/**}") + private String apiPath; @Value("${swagger.non_security_path_regex}") private String nonSecurityPathRegex; @Value("${swagger.title}") @@ -115,288 +89,206 @@ public class SwaggerConfiguration { private String appVersion; @Bean - public Docket thingsboardApi() { - TypeResolver typeResolver = new TypeResolver(); - return new Docket(DocumentationType.OAS_30) - .enable(enabled) - .groupName("thingsboard") - .apiInfo(apiInfo()) - .additionalModels( - typeResolver.resolve(ThingsboardErrorResponse.class), - typeResolver.resolve(ThingsboardCredentialsExpiredResponse.class), - typeResolver.resolve(LoginRequest.class), - typeResolver.resolve(LoginResponse.class) - ) - .select() - .paths(apiPaths()) - .paths(any()) - .build() - .globalResponses(HttpMethod.GET, - defaultErrorResponses(false) - ) - .globalResponses(HttpMethod.POST, - defaultErrorResponses(true) - ) - .globalResponses(HttpMethod.DELETE, - defaultErrorResponses(false) - ) - .securitySchemes(newArrayList(httpLogin())) - .securityContexts(newArrayList(securityContext())) - .ignoredParameterTypes(AuthenticationPrincipal.class) - .enableUrlTemplating(true); - } + public OpenAPI tbOpenAPI() { + Contact contact = new Contact() + .name(contactName) + .url(contactUrl) + .email(contactEmail); - @Bean - @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER) - ApiListingScannerPlugin loginEndpointListingScanner(final CachingOperationNameGenerator operationNames) { - return new ApiListingScannerPlugin() { - @Override - public List apply(DocumentationContext context) { - return List.of(loginEndpointApiDescription(operationNames)); - } - - @Override - public boolean supports(DocumentationType delimiter) { - return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter); - } - }; - } + License license = new License() + .name(licenseTitle) + .url(licenseUrl); - @Bean - @Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER) - ApiListingBuilderPlugin loginEndpointListingBuilder() { - return new ApiListingBuilderPlugin() { - @Override - public void apply(ApiListingContext apiListingContext) { - if (apiListingContext.getResourceGroup().getGroupName().equals("default")) { - ApiListing apiListing = apiListingContext.apiListingBuilder().build(); - if (apiListing.getResourcePath().equals("/api/auth/login")) { - apiListingContext.apiListingBuilder().tags(Set.of(new Tag("login-endpoint", "Login Endpoint"))); - apiListingContext.apiListingBuilder().description("Login Endpoint"); - } - } - } + String apiVersion = version; + if (StringUtils.isEmpty(apiVersion)) { + apiVersion = appVersion; + } - @Override - public boolean supports(DocumentationType delimiter) { - return DocumentationType.SWAGGER_2.equals(delimiter) || DocumentationType.OAS_30.equals(delimiter); - } - }; + Info info = new Info() + .title(title) + .description(description) + .contact(contact) + .license(license) + .version(apiVersion); + + SecurityScheme securityScheme = new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .scheme("basic") + .bearerFormat("JWT") + .in(SecurityScheme.In.HEADER) + .description("Enter Username / Password"); + + var openApi = new OpenAPI() + .components(new Components().addSecuritySchemes("HTTP login form", securityScheme)) + .info(info); + addLoginOperation(openApi); + return openApi; } - @Bean - UiConfiguration uiConfig() { - return UiConfigurationBuilder.builder() - .deepLinking(true) - .displayOperationId(false) - .defaultModelsExpandDepth(1) - .defaultModelExpandDepth(1) - .defaultModelRendering(ModelRendering.EXAMPLE) - .displayRequestDuration(false) - .docExpansion(DocExpansion.NONE) - .filter(false) - .maxDisplayedTags(null) - .operationsSorter(OperationsSorter.ALPHA) - .showExtensions(false) - .showCommonExtensions(false) - .supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS) - .validatorUrl(null) - .persistAuthorization(true) - .syntaxHighlightActivate(true) - .syntaxHighlightTheme("agate") - .build(); + public void addLoginOperation(OpenAPI openAPI) { + openAPI.getComponents() + .addSchemas("LoginRequest", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(LoginRequest.class)).schema) + .addSchemas("LoginResponse", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(LoginResponse.class)).schema) + .addSchemas("ThingsboardErrorResponse", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(ThingsboardErrorResponse.class)).schema) + .addSchemas("ThingsboardCredentialsExpiredResponse", ModelConverters.getInstance().readAllAsResolvedSchema(new AnnotatedType().type(ThingsboardCredentialsExpiredResponse.class)).schema); + + var operation = new Operation(); + operation.summary("Login method to get user JWT token data"); + operation.description("Login method used to authenticate user and get JWT token data.\n\nValue of the response **token** " + + "field can be used as **X-Authorization** header value:\n\n`X-Authorization: Bearer $JWT_TOKEN_VALUE`."); + var requestBody = new RequestBody().content(new Content().addMediaType(APPLICATION_JSON_VALUE, + new MediaType().schema(new Schema().$ref("#/components/schemas/LoginRequest")))); + operation.requestBody(requestBody); + operation.responses(getResponses()); + operation.addTagsItem("login-endpoint"); + var pathItem = new PathItem().post(operation); + openAPI.path(LOGIN_ENDPOINT, pathItem); } - private SecurityScheme httpLogin() { - return HttpLoginPasswordScheme - .X_AUTHORIZATION_BUILDER - .loginEndpoint("/api/auth/login") - .name("HTTP login form") - .description("Enter Username / Password") - .build(); - } + private ApiResponses getResponses() { + ApiResponses apiResponses = new ApiResponses(); + + apiResponses.addApiResponse("200", new ApiResponse().description("OK") + .content(new Content().addMediaType(APPLICATION_JSON_VALUE, + new MediaType().schema(new Schema().$ref("#/components/schemas/LoginResponse"))))); + + ApiResponse unauthorizedResponse = new ApiResponse().description("Unauthorized"); + Content content = new Content(); + MediaType mediaType = new MediaType().schema(new Schema().$ref("#/components/schemas/ThingsboardErrorResponse")); + + Map examples = Map.of( + "bad-credentials", errorExample("Bad credentials", + ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), + "token-expired", errorExample("JWT token expired", + ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)), + "account-disabled", errorExample("Disabled account", + ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), + "account-locked", errorExample("Locked account", + ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), + "authentication-failed", errorExample("General authentication error", + ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)) + ); - private SecurityContext securityContext() { - return SecurityContext.builder() - .securityReferences(defaultAuth()) - .operationSelector(securityPathOperationSelector()) - .build(); + mediaType.setExamples(examples); + content.addMediaType(APPLICATION_JSON_VALUE, mediaType); + unauthorizedResponse.setContent(content); + apiResponses.addApiResponse("401", unauthorizedResponse); + + ApiResponse expiredCredentialsResponse = new ApiResponse().description("Unauthorized (**Expired credentials**)"); + Content expiredContent = new Content(); + MediaType expiredMediaType = new MediaType().schema(new Schema().$ref("#/components/schemas/ThingsboardCredentialsExpiredResponse")); + expiredMediaType.addExamples("credentials-expired", errorExample("Expired credentials", + ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30)))); + expiredContent.addMediaType(APPLICATION_JSON_VALUE, expiredMediaType); + expiredCredentialsResponse.setContent(expiredContent); + apiResponses.addApiResponse("401 ", expiredCredentialsResponse); + + return apiResponses; } - private Predicate apiPaths() { - return regex(apiPathRegex); + private Example errorExample(String summary, ThingsboardErrorResponse example) { + return new Example() + .summary(summary) + .value(example); } - private Predicate securityPathOperationSelector() { - return new SecurityPathOperationSelector(securityPathRegex, nonSecurityPathRegex); + @Bean + public GroupedOpenApi thingsboardApi() { + return GroupedOpenApi.builder() + .group("thingsboard") + .pathsToMatch(apiPath) + .addOpenApiCustomizer(customOpenApiCustomizer()) + .build(); } - List defaultAuth() { - AuthorizationScope[] authorizationScopes = new AuthorizationScope[3]; - authorizationScopes[0] = new AuthorizationScope(Authority.SYS_ADMIN.name(), "System administrator"); - authorizationScopes[1] = new AuthorizationScope(Authority.TENANT_ADMIN.name(), "Tenant administrator"); - authorizationScopes[2] = new AuthorizationScope(Authority.CUSTOMER_USER.name(), "Customer"); - return newArrayList( - new SecurityReference("HTTP login form", authorizationScopes)); + @Bean + @Primary + public SwaggerUiConfigProperties swaggerUiConfig(SwaggerUiConfigProperties uiProperties) { + uiProperties.setDeepLinking(true); + uiProperties.setDisplayOperationId(false); + uiProperties.setDefaultModelsExpandDepth(1); + uiProperties.setDefaultModelExpandDepth(1); + uiProperties.setDefaultModelRendering("example"); + uiProperties.setDisplayRequestDuration(false); + uiProperties.setDocExpansion("none"); + uiProperties.setFilter("false"); + uiProperties.setMaxDisplayedTags(null); + uiProperties.setOperationsSorter("alpha"); + uiProperties.setTagsSorter("alpha"); + uiProperties.setShowExtensions(false); + uiProperties.setShowCommonExtensions(false); + uiProperties.setSupportedSubmitMethods(List.of("get", "put", "post", "delete", "options", "head", "patch", "trace")); + uiProperties.setValidatorUrl(null); + uiProperties.setPersistAuthorization(true); + + var syntaxHighLight = new SwaggerUiConfigProperties.SyntaxHighlight(); + syntaxHighLight.setActivated(true); + syntaxHighLight.setTheme("agate"); + + uiProperties.setSyntaxHighlight(syntaxHighLight); + return uiProperties; } - private ApiInfo apiInfo() { - String apiVersion = version; - if (StringUtils.isEmpty(apiVersion)) { - apiVersion = appVersion; - } - return new ApiInfoBuilder() - .title(title) - .description(description) - .contact(new Contact(contactName, contactUrl, contactEmail)) - .license(licenseTitle) - .licenseUrl(licenseUrl) - .version(apiVersion) - .build(); - } + public OpenApiCustomizer customOpenApiCustomizer() { + SecurityRequirement loginForm = new SecurityRequirement().addList("HTTP login form"); - private ApiDescription loginEndpointApiDescription(final CachingOperationNameGenerator operationNames) { - return new ApiDescription(null, "/api/auth/login", "Login method to get user JWT token data", "Login endpoint", Collections.singletonList( - new OperationBuilder(operationNames) - .summary("Login method to get user JWT token data") - .tags(Set.of("login-endpoint")) - .authorizations(new ArrayList<>()) - .position(0) - .codegenMethodNameStem("loginPost") - .method(HttpMethod.POST) - .notes("Login method used to authenticate user and get JWT token data.\n\nValue of the response **token** " + - "field can be used as **X-Authorization** header value:\n\n`X-Authorization: Bearer $JWT_TOKEN_VALUE`.") - .requestParameters( - List.of( - new RequestParameterBuilder() - .in(ParameterType.BODY) - .required(true) - .description("Login request") - .content(c -> - c.requestBody(true) - .representation(MediaType.APPLICATION_JSON) - .apply(classRepresentation(LoginRequest.class, false)) - ) - .build() - ) - ) - .responses(loginResponses()) - .build() - ), false); - } + return openAPI -> openAPI.getPaths().entrySet().stream().peek(entry -> { + if (!(entry.getKey().matches(nonSecurityPathRegex) || entry.getKey().equals(LOGIN_ENDPOINT))) { + entry.getValue() + .readOperationsMap() + .values() + .forEach(operation -> operation.addSecurityItem(loginForm)); + } - private Collection loginResponses() { - List responses = new ArrayList<>(); - responses.add( - new ResponseBuilder() - .code("200") - .description("OK") - .representation(MediaType.APPLICATION_JSON) - .apply(classRepresentation(LoginResponse.class, true)). - build() - ); - responses.addAll(loginErrorResponses()); - return responses; - } + entry.getValue().readOperationsMap().forEach(((httpMethod, operation) -> { + operation.setResponses(getResponses(operation.getResponses(), httpMethod.equals(PathItem.HttpMethod.POST))); + })); - /** Helper methods **/ - - private List defaultErrorResponses(boolean isPost) { - return List.of( - errorResponse("400", "Bad Request", - ThingsboardErrorResponse.of(isPost ? "Invalid request body" : "Invalid UUID string: 123", ThingsboardErrorCode.BAD_REQUEST_PARAMS, HttpStatus.BAD_REQUEST)), - errorResponse("401", "Unauthorized", - ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorResponse("403", "Forbidden", - ThingsboardErrorResponse.of("You don't have permission to perform this operation!", - ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)), - errorResponse("404", "Not Found", - ThingsboardErrorResponse.of("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND, HttpStatus.NOT_FOUND)), - errorResponse("429", "Too Many Requests", - ThingsboardErrorResponse.of("Too many requests for current tenant!", - ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS)) - ); + }).map(entry -> { + String tagItem = entry.getValue().readOperationsMap().values().stream().findAny().get().getTags().get(0); + return tagFromTagItem(tagItem); + }).forEach(openAPI::addTagsItem); } - private List loginErrorResponses() { - return List.of( - errorResponse("401", "Unauthorized", - List.of( - errorExample("bad-credentials", "Bad credentials", - ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorExample("token-expired", "JWT token expired", - ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)), - errorExample("account-disabled", "Disabled account", - ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorExample("account-locked", "Locked account", - ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)), - errorExample("authentication-failed", "General authentication error", - ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)) - ) - ), - errorResponse("401 ", "Unauthorized (**Expired credentials**)", - List.of( - errorExample("credentials-expired", "Expired credentials", - ThingsboardCredentialsExpiredResponse.of("User password expired!", StringUtils.randomAlphanumeric(30))) - ), ThingsboardCredentialsExpiredResponse.class - ) - ); - } + private Tag tagFromTagItem(String tagItem) { + String[] words = tagItem.split("-"); + StringBuilder sb = new StringBuilder(); - private Response errorResponse(String code, String description, ThingsboardErrorResponse example) { - return errorResponse(code, description, List.of(errorExample("error-code-" + code, description, example))); - } + for (String word : words) { + sb.append(word.substring(0, 1).toUpperCase()); + sb.append(word.substring(1).toLowerCase()); + sb.append(" "); + } - private Response errorResponse(String code, String description, List examples) { - return errorResponse(code, description, examples, ThingsboardErrorResponse.class); + return new Tag().name(tagItem).description(sb.toString().trim()); } - private Response errorResponse(String code, String description, List examples, - Class errorResponseClass) { - return new ResponseBuilder() - .code(code) - .description(description) - .examples(examples) - .representation(MediaType.APPLICATION_JSON) - .apply(classRepresentation(errorResponseClass, true)) - .build(); - } + private ApiResponses getResponses(ApiResponses apiResponses, boolean isPost) { + if (apiResponses == null) { + apiResponses = new ApiResponses(); + } - private Example errorExample(String id, String summary, ThingsboardErrorResponse example) { - return new ExampleBuilder() - .mediaType(MediaType.APPLICATION_JSON_VALUE) - .summary(summary) - .id(id) - .value(example).build(); - } + apiResponses.addApiResponse("400", new ApiResponse().description("Bad Request") + .content(getErrorContent(ThingsboardErrorResponse.of(isPost ? "Invalid request body" : "Invalid UUID string: 123", ThingsboardErrorCode.BAD_REQUEST_PARAMS, HttpStatus.BAD_REQUEST)))); - private Consumer classRepresentation(Class clazz, boolean isResponse) { - return r -> r.model( - m -> - m.referenceModel(ref -> - ref.key(k -> - k.qualifiedModelName(q -> - q.namespace(clazz.getPackageName()) - .name(clazz.getSimpleName())).isResponse(isResponse))) - ); - } + apiResponses.addApiResponse("401", new ApiResponse().description("Unauthorized") + .content(getErrorContent(ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)))); - private static class SecurityPathOperationSelector implements Predicate { + apiResponses.addApiResponse("403", new ApiResponse().description("Forbidden") + .content(getErrorContent(ThingsboardErrorResponse.of("You don't have permission to perform this operation!", ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)))); - private final Predicate securityPathSelector; + apiResponses.addApiResponse("404", new ApiResponse().description("Not Found") + .content(getErrorContent(ThingsboardErrorResponse.of("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND, HttpStatus.NOT_FOUND)))); - SecurityPathOperationSelector(String securityPathRegex, String nonSecurityPathRegex) { - this.securityPathSelector = regex(securityPathRegex).and( - not( - regex(nonSecurityPathRegex) - )); - } + apiResponses.addApiResponse("429", new ApiResponse().description("Too Many Requests") + .content(getErrorContent(ThingsboardErrorResponse.of("Too many requests for current tenant!", ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS)))); - @Override - public boolean test(OperationContext operationContext) { - return this.securityPathSelector.test(operationContext.requestMappingPattern()); - } + return apiResponses; } + private Content getErrorContent(ThingsboardErrorResponse errorResponse) { + return new Content().addMediaType(org.springframework.http.MediaType.APPLICATION_JSON_VALUE, + new MediaType().schema(new Schema().example(errorResponse))); + } } diff --git a/application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java b/application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java new file mode 100644 index 0000000000..d8710149a6 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/config/annotations/ApiOperation.java @@ -0,0 +1,45 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.config.annotations; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import org.springframework.core.annotation.AliasFor; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Operation +public @interface ApiOperation { + + @AliasFor(annotation = Operation.class, attribute = "summary") + String value(); + + @AliasFor(annotation = Operation.class, attribute = "description") + String notes() default ""; + + boolean hidden() default false; + + RequestBody requestBody() default @RequestBody; + + ApiResponse[] responses() default {}; + +} diff --git a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java index 5f33eb951e..faef8edd4a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AbstractRpcController.java @@ -17,6 +17,7 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.util.concurrent.FutureCallback; +import jakarta.annotation.Nullable; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -45,7 +46,6 @@ import org.thingsboard.server.service.security.AccessValidator; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.annotation.Nullable; import java.util.Optional; import java.util.UUID; diff --git a/application/src/main/java/org/thingsboard/server/controller/AdminController.java b/application/src/main/java/org/thingsboard/server/controller/AdminController.java index 5cf97a7cda..12c5abf47d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java @@ -19,8 +19,9 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Lazy; import org.springframework.http.HttpStatus; @@ -53,6 +54,7 @@ import org.thingsboard.server.common.data.sync.vc.AutoCommitSettings; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.RepositorySettingsInfo; import org.thingsboard.server.common.data.sync.vc.VcUtils; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -96,7 +98,7 @@ public class AdminController extends BaseController { @RequestMapping(value = "/settings/{key}", method = RequestMethod.GET) @ResponseBody public AdminSettings getAdminSettings( - @ApiParam(value = "A string value of the key (e.g. 'general' or 'mail').") + @Parameter(description = "A string value of the key (e.g. 'general' or 'mail').") @PathVariable("key") String key) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key), "No Administration settings found for key: " + key); @@ -114,7 +116,7 @@ public class AdminController extends BaseController { @RequestMapping(value = "/settings", method = RequestMethod.POST) @ResponseBody public AdminSettings saveAdminSettings( - @ApiParam(value = "A JSON value representing the Administration Settings.") + @Parameter(description = "A JSON value representing the Administration Settings.") @RequestBody AdminSettings adminSettings) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE); adminSettings.setTenantId(getTenantId()); @@ -144,7 +146,7 @@ public class AdminController extends BaseController { @RequestMapping(value = "/securitySettings", method = RequestMethod.POST) @ResponseBody public SecuritySettings saveSecuritySettings( - @ApiParam(value = "A JSON value representing the Security Settings.") + @Parameter(description = "A JSON value representing the Security Settings.") @RequestBody SecuritySettings securitySettings) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.WRITE); securitySettings = checkNotNull(systemSecurityService.saveSecuritySettings(TenantId.SYS_TENANT_ID, securitySettings)); @@ -153,7 +155,7 @@ public class AdminController extends BaseController { @ApiOperation(value = "Get the JWT Settings object (getJwtSettings)", notes = "Get the JWT Settings object that contains JWT token policy, etc. " + SYSTEM_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/jwtSettings", method = RequestMethod.GET) @ResponseBody @@ -164,12 +166,12 @@ public class AdminController extends BaseController { @ApiOperation(value = "Update JWT Settings (saveJwtSettings)", notes = "Updates the JWT Settings object that contains JWT token policy, etc. The tokenSigningKey field is a Base64 encoded string." + SYSTEM_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/jwtSettings", method = RequestMethod.POST) @ResponseBody public JwtPair saveJwtSettings( - @ApiParam(value = "A JSON value representing the JWT Settings.") + @Parameter(description = "A JSON value representing the JWT Settings.") @RequestBody JwtSettings jwtSettings) throws ThingsboardException { SecurityUser securityUser = getCurrentUser(); accessControlService.checkPermission(securityUser, Resource.ADMIN_SETTINGS, Operation.WRITE); @@ -183,7 +185,7 @@ public class AdminController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/settings/testMail", method = RequestMethod.POST) public void sendTestMail( - @ApiParam(value = "A JSON value representing the Mail Settings.") + @Parameter(description = "A JSON value representing the Mail Settings.") @RequestBody AdminSettings adminSettings) throws ThingsboardException { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); adminSettings = checkNotNull(adminSettings); @@ -203,7 +205,7 @@ public class AdminController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/settings/testSms", method = RequestMethod.POST) public void sendTestSms( - @ApiParam(value = "A JSON value representing the Test SMS request.") + @Parameter(description = "A JSON value representing the Test SMS request.") @RequestBody TestSmsRequest testSmsRequest) throws ThingsboardException { SecurityUser user = getCurrentUser(); accessControlService.checkPermission(user, Resource.ADMIN_SETTINGS, Operation.READ); @@ -286,7 +288,7 @@ public class AdminController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/repositorySettings/checkAccess", method = RequestMethod.POST) public DeferredResult checkRepositoryAccess( - @ApiParam(value = "A JSON value representing the Repository Settings.") + @Parameter(description = "A JSON value representing the Repository Settings.") @RequestBody RepositorySettings settings) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); settings = checkNotNull(settings); diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java index 92b2cb923f..529b1fe48a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmCommentController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; @@ -35,17 +37,16 @@ import org.thingsboard.server.common.data.id.AlarmCommentId; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.alarm.TbAlarmCommentService; import org.thingsboard.server.service.security.permission.Operation; import static org.thingsboard.server.controller.ControllerConstants.ALARM_COMMENT_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ALARM_COMMENT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; @@ -69,12 +70,12 @@ public class AlarmCommentController extends BaseController { "\n\n To create new Alarm comment entity it is enough to specify 'comment' json element with 'text' node, for example: {\"comment\": { \"text\": \"my comment\"}}. " + "\n\n If comment type is not specified the default value 'OTHER' will be saved. If 'alarmId' or 'userId' specified in body it will be ignored." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.POST) @ResponseBody - public AlarmComment saveAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) - @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = "A JSON value representing the comment.") @RequestBody AlarmComment alarmComment) throws ThingsboardException { + public AlarmComment saveAlarmComment(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) + @PathVariable(ALARM_ID) String strAlarmId, @Parameter(description = "A JSON value representing the comment.") @RequestBody AlarmComment alarmComment) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -83,11 +84,11 @@ public class AlarmCommentController extends BaseController { } @ApiOperation(value = "Delete Alarm comment (deleteAlarmComment)", - notes = "Deletes the Alarm comment. Referencing non-existing Alarm comment Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Deletes the Alarm comment. Referencing non-existing Alarm comment Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/comment/{commentId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteAlarmComment(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, @ApiParam(value = ALARM_COMMENT_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_COMMENT_ID) String strCommentId) throws ThingsboardException { + public void deleteAlarmComment(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, @Parameter(description = ALARM_COMMENT_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_COMMENT_ID) String strCommentId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -99,20 +100,20 @@ public class AlarmCommentController extends BaseController { @ApiOperation(value = "Get Alarm comments (getAlarmComments)", notes = "Returns a page of alarm comments for specified alarm. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/comment", method = RequestMethod.GET) @ResponseBody public PageData getAlarmComments( - @ApiParam(value = ALARM_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ALARM_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ALARM_ID) String strAlarmId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_COMMENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder ) throws Exception { checkParameter(ALARM_ID, strAlarmId); diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 44263d19bd..18ad89f1a0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -45,6 +47,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.alarm.TbAlarmService; import org.thingsboard.server.service.security.permission.Operation; @@ -59,7 +62,6 @@ import java.util.concurrent.ExecutionException; import static org.thingsboard.server.controller.ControllerConstants.ALARM_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ALARM_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ALARM_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ASSIGNEE_ID; import static org.thingsboard.server.controller.ControllerConstants.ASSIGN_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID; @@ -69,7 +71,6 @@ import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_ import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; @@ -104,11 +105,11 @@ public class AlarmController extends BaseController { "filled in the AlarmInfo object field: 'originatorName' or will returns as null."; @ApiOperation(value = "Get Alarm (getAlarmById)", - notes = "Fetch the Alarm object based on the provided Alarm Id. " + ALARM_SECURITY_CHECK, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Fetch the Alarm object based on the provided Alarm Id. " + ALARM_SECURITY_CHECK, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET) @ResponseBody - public Alarm getAlarmById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public Alarm getAlarmById(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); @@ -117,11 +118,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Alarm Info (getAlarmInfoById)", notes = "Fetch the Alarm Info object based on the provided Alarm Id. " + - ALARM_SECURITY_CHECK + ALARM_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + ALARM_SECURITY_CHECK + ALARM_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET) @ResponseBody - public AlarmInfo getAlarmInfoById(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public AlarmInfo getAlarmInfoById(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); @@ -139,11 +140,11 @@ public class AlarmController extends BaseController { "If the user clears the alarm (see 'Clear Alarm(clearAlarm)'), than new alarm with the same type and same device may be created. " + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Alarm entity. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm", method = RequestMethod.POST) @ResponseBody - public Alarm saveAlarm(@ApiParam(value = "A JSON value representing the alarm.") @RequestBody Alarm alarm) throws ThingsboardException { + public Alarm saveAlarm(@Parameter(description = "A JSON value representing the alarm.") @RequestBody Alarm alarm) throws ThingsboardException { alarm.setTenantId(getTenantId()); checkNotNull(alarm.getOriginator()); checkEntity(alarm.getId(), alarm, Resource.ALARM); @@ -155,11 +156,11 @@ public class AlarmController extends BaseController { } @ApiOperation(value = "Delete Alarm (deleteAlarm)", - notes = "Deletes the Alarm. Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Deletes the Alarm. Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.DELETE) @ResponseBody - public Boolean deleteAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { + public Boolean deleteAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.DELETE); @@ -169,11 +170,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Acknowledge Alarm (ackAlarm)", notes = "Acknowledge the Alarm. " + "Once acknowledged, the 'ack_ts' field will be set to current timestamp and special rule chain event 'ALARM_ACK' will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public AlarmInfo ackAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { + public AlarmInfo ackAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -184,11 +185,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Clear Alarm (clearAlarm)", notes = "Clear the Alarm. " + "Once cleared, the 'clear_ts' field will be set to current timestamp and special rule chain event 'ALARM_CLEAR' will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public AlarmInfo clearAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { + public AlarmInfo clearAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws Exception { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); @@ -200,13 +201,13 @@ public class AlarmController extends BaseController { notes = "Assign the Alarm. " + "Once assigned, the 'assign_ts' field will be set to current timestamp and special rule chain event 'ALARM_ASSIGNED' " + "(or ALARM_REASSIGNED in case of assigning already assigned alarm) will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/assign/{assigneeId}", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public Alarm assignAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public Alarm assignAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId, - @ApiParam(value = ASSIGN_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSIGN_ID_PARAM_DESCRIPTION) @PathVariable(ASSIGNEE_ID) String strAssigneeId ) throws Exception { checkParameter(ALARM_ID, strAlarmId); @@ -221,11 +222,11 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Unassign Alarm (unassignAlarm)", notes = "Unassign the Alarm. " + "Once unassigned, the 'assign_ts' field will be set to current timestamp and special rule chain event 'ALARM_UNASSIGNED' will be generated. " + - "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Referencing non-existing Alarm Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/assign", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public Alarm unassignAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) + public Alarm unassignAlarm(@Parameter(description = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId ) throws Exception { checkParameter(ALARM_ID, strAlarmId); @@ -236,36 +237,36 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Alarms (getAlarms)", notes = "Returns a page of alarms for the selected entity. Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public PageData getAlarms( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String searchStatus, - @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String status, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) + @Parameter(description = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) @RequestParam(required = false) Boolean fetchOriginator ) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter("EntityId", strEntityId); @@ -292,32 +293,32 @@ public class AlarmController extends BaseController { "If the user has the authority of 'Tenant Administrator', the server returns alarms that belongs to the tenant of current user. " + "If the user has the authority of 'Customer User', the server returns alarms that belongs to the customer of current user. " + "Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarms", method = RequestMethod.GET) @ResponseBody public PageData getAllAlarms( - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String searchStatus, - @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String status, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) + @Parameter(description = ALARM_QUERY_FETCH_ORIGINATOR_DESCRIPTION) @RequestParam(required = false) Boolean fetchOriginator ) throws ThingsboardException, ExecutionException, InterruptedException { AlarmSearchStatus alarmSearchStatus = StringUtils.isEmpty(searchStatus) ? null : AlarmSearchStatus.valueOf(searchStatus); @@ -341,36 +342,36 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Alarms (getAlarmsV2)", notes = "Returns a page of alarms for the selected entity. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/v2/alarm/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public PageData getAlarmsV2( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] statusList, - @ApiParam(value = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] severityList, - @ApiParam(value = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) @RequestParam(required = false) String[] typeList, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime ) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter("EntityId", strEntityId); @@ -407,32 +408,32 @@ public class AlarmController extends BaseController { notes = "Returns a page of alarms that belongs to the current user owner. " + "If the user has the authority of 'Tenant Administrator', the server returns alarms that belongs to the tenant of current user. " + "If the user has the authority of 'Customer User', the server returns alarms that belongs to the customer of current user. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/v2/alarms", method = RequestMethod.GET) @ResponseBody public PageData getAllAlarmsV2( - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] statusList, - @ApiParam(value = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)) @RequestParam(required = false) String[] severityList, - @ApiParam(value = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) @RequestParam(required = false) String[] typeList, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ALARM_QUERY_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ALARM_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "startTs", "endTs", "type", "ackTs", "clearTs", "severity", "status"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = ALARM_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = ALARM_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = ALARM_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime ) throws ThingsboardException, ExecutionException, InterruptedException { List alarmStatusList = new ArrayList<>(); @@ -468,20 +469,20 @@ public class AlarmController extends BaseController { @ApiOperation(value = "Get Highest Alarm Severity (getHighestAlarmSeverity)", notes = "Search the alarms by originator ('entityType' and entityId') and optional 'status' or 'searchStatus' filters and returns the highest AlarmSeverity(CRITICAL, MAJOR, MINOR, WARNING or INDETERMINATE). " + "Specifying both parameters 'searchStatus' and 'status' at the same time will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/highestSeverity/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public AlarmSeverity getHighestAlarmSeverity( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String searchStatus, - @ApiParam(value = ALARM_QUERY_STATUS_DESCRIPTION, allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) @RequestParam(required = false) String status, - @ApiParam(value = ALARM_QUERY_ASSIGNEE_DESCRIPTION) + @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId ) throws ThingsboardException { checkParameter("EntityId", strEntityId); diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index 510fefe305..79d8d88352 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -16,8 +16,10 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.ListenableFuture; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -49,6 +51,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportRequest; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -67,7 +70,6 @@ import static org.thingsboard.server.controller.ControllerConstants.ASSET_ID_PAR import static org.thingsboard.server.controller.ControllerConstants.ASSET_INFO_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_NAME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ASSET_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ASSET_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; @@ -79,7 +81,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -102,11 +103,11 @@ public class AssetController extends BaseController { notes = "Fetch the Asset object based on the provided Asset Id. " + "If the user has the authority of 'Tenant Administrator', the server checks that the asset is owned by the same tenant. " + "If the user has the authority of 'Customer User', the server checks that the asset is assigned to the same customer." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH - , produces = MediaType.APPLICATION_JSON_VALUE) + , responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.GET) @ResponseBody - public Asset getAssetById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) + public Asset getAssetById(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); @@ -117,11 +118,11 @@ public class AssetController extends BaseController { notes = "Fetch the Asset Info object based on the provided Asset Id. " + "If the user has the authority of 'Tenant Administrator', the server checks that the asset is owned by the same tenant. " + "If the user has the authority of 'Customer User', the server checks that the asset is assigned to the same customer. " - + ASSET_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + + ASSET_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset/info/{assetId}", method = RequestMethod.GET) @ResponseBody - public AssetInfo getAssetInfoById(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) + public AssetInfo getAssetInfoById(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); @@ -134,11 +135,11 @@ public class AssetController extends BaseController { "Specify existing Asset id to update the asset. " + "Referencing non-existing Asset Id will cause 'Not Found' error. " + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Asset entity. " - + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset", method = RequestMethod.POST) @ResponseBody - public Asset saveAsset(@ApiParam(value = "A JSON value representing the asset.") @RequestBody Asset asset) throws Exception { + public Asset saveAsset(@Parameter(description = "A JSON value representing the asset.") @RequestBody Asset asset) throws Exception { asset.setTenantId(getTenantId()); checkEntity(asset.getId(), asset, Resource.ASSET); return tbAssetService.save(asset, getCurrentUser()); @@ -149,7 +150,7 @@ public class AssetController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteAsset(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws Exception { + public void deleteAsset(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws Exception { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId, Operation.DELETE); @@ -157,12 +158,12 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Assign asset to customer (assignAssetToCustomer)", - notes = "Creates assignment of the asset to customer. Customer will be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Creates assignment of the asset to customer. Customer will be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/asset/{assetId}", method = RequestMethod.POST) @ResponseBody - public Asset assignAssetToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset assignAssetToCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, + @Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(ASSET_ID, strAssetId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -173,11 +174,11 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Unassign asset from customer (unassignAssetFromCustomer)", - notes = "Clears assignment of the asset to customer. Customer will not be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Clears assignment of the asset to customer. Customer will not be able to query asset afterwards." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/asset/{assetId}", method = RequestMethod.DELETE) @ResponseBody - public Asset unassignAssetFromCustomer(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset unassignAssetFromCustomer(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId, Operation.UNASSIGN_FROM_CUSTOMER); @@ -191,11 +192,11 @@ public class AssetController extends BaseController { @ApiOperation(value = "Make asset publicly available (assignAssetToPublicCustomer)", notes = "Asset will be available for non-authorized (not logged-in) users. " + "This is useful to create dashboards that you plan to share/embed on a publicly available website. " + - "However, users that are logged-in and belong to different tenant will not be able to access the asset." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "However, users that are logged-in and belong to different tenant will not be able to access the asset." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/asset/{assetId}", method = RequestMethod.POST) @ResponseBody - public Asset assignAssetToPublicCustomer(@ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset assignAssetToPublicCustomer(@Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(ASSET_ID, strAssetId); AssetId assetId = new AssetId(toUUID(strAssetId)); checkAssetId(assetId, Operation.ASSIGN_TO_CUSTOMER); @@ -204,22 +205,22 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Tenant Assets (getTenantAssets)", notes = "Returns a page of assets owned by tenant. " + - PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantAssets( - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -232,24 +233,24 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Tenant Asset Infos (getTenantAssetInfos)", notes = "Returns a page of assets info objects owned by tenant. " + - PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantAssetInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String assetProfileId, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -265,12 +266,12 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Tenant Asset (getTenantAsset)", notes = "Requested asset must be owned by tenant that the user belongs to. " + - "Asset name is an unique property of asset. So it can be used to identify the asset." + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + "Asset name is an unique property of asset. So it can be used to identify the asset." + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/assets", params = {"assetName"}, method = RequestMethod.GET) @ResponseBody public Asset getTenantAsset( - @ApiParam(value = ASSET_NAME_DESCRIPTION) + @Parameter(description = ASSET_NAME_DESCRIPTION) @RequestParam String assetName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(assetService.findAssetByTenantIdAndName(tenantId, assetName)); @@ -278,24 +279,24 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Customer Assets (getCustomerAssets)", notes = "Returns a page of assets objects assigned to customer. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerAssets( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -311,26 +312,26 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get Customer Asset Infos (getCustomerAssetInfos)", notes = "Returns a page of assets info objects assigned to customer. " + - PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + ASSET_INFO_DESCRIPTION, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/assetInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerAssetInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String assetProfileId, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -348,12 +349,12 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Get Assets By Ids (getAssetsByIds)", - notes = "Requested assets must be owned by tenant or assigned to customer which user is performing the request. ", produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Requested assets must be owned by tenant or assigned to customer which user is performing the request. ", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assets", params = {"assetIds"}, method = RequestMethod.GET) @ResponseBody public List getAssetsByIds( - @ApiParam(value = "A list of assets ids, separated by comma ','") + @Parameter(description = "A list of assets ids, separated by comma ','") @RequestParam("assetIds") String[] strAssetIds) throws ThingsboardException, ExecutionException, InterruptedException { checkArrayParameter("assetIds", strAssetIds); SecurityUser user = getCurrentUser(); @@ -375,7 +376,7 @@ public class AssetController extends BaseController { @ApiOperation(value = "Find related assets (findByQuery)", notes = "Returns all assets that are related to the specific entity. " + "The entity id, relation type, asset types, depth of the search, and other query parameters defined using complex 'AssetSearchQuery' object. " + - "See 'Model' tab of the Parameters for more info.", produces = MediaType.APPLICATION_JSON_VALUE) + "See 'Model' tab of the Parameters for more info.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assets", method = RequestMethod.POST) @ResponseBody @@ -397,7 +398,7 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Get Asset Types (getAssetTypes)", - notes = "Returns a set of unique asset types based on assets that are either owned by the tenant or assigned to the customer which user is performing the request.", produces = MediaType.APPLICATION_JSON_VALUE) + notes = "Returns a set of unique asset types based on assets that are either owned by the tenant or assigned to the customer which user is performing the request.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset/types", method = RequestMethod.GET) @ResponseBody @@ -414,12 +415,12 @@ public class AssetController extends BaseController { "Second, remote edge service will receive a copy of assignment asset " + EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once asset will be delivered to edge service, it's going to be available for usage on remote edge instance.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST) @ResponseBody - public Asset assignAssetToEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset assignAssetToEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, + @Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(ASSET_ID, strAssetId); @@ -438,12 +439,12 @@ public class AssetController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove asset " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove asset locally.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.DELETE) @ResponseBody - public Asset unassignAssetFromEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + public Asset unassignAssetFromEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, + @Parameter(description = ASSET_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(ASSET_ID, strAssetId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -457,28 +458,28 @@ public class AssetController extends BaseController { @ApiOperation(value = "Get assets assigned to edge (getEdgeAssets)", notes = "Returns a page of assets assigned to edge. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/{edgeId}/assets", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeAssets( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = ASSET_TYPE_DESCRIPTION) + @Parameter(description = ASSET_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = ASSET_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Timestamp. Assets with creation time before it won't be queried") + @Parameter(description = "Timestamp. Assets with creation time before it won't be queried") @RequestParam(required = false) Long startTime, - @ApiParam(value = "Timestamp. Assets with creation time after it won't be queried") + @Parameter(description = "Timestamp. Assets with creation time after it won't be queried") @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -507,7 +508,7 @@ public class AssetController extends BaseController { } @ApiOperation(value = "Import the bulk of assets (processAssetsBulkImport)", - notes = "There's an ability to import the bulk of assets using the only .csv file.", produces = MediaType.APPLICATION_JSON_VALUE) + notes = "There's an ability to import the bulk of assets using the only .csv file.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @PostMapping("/asset/bulk_import") public BulkImportResult processAssetsBulkImport(@RequestBody BulkImportRequest request) throws Exception { diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java b/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java index 47a7eede4b..0d6f652241 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetProfileController.java @@ -15,11 +15,14 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -35,6 +38,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AssetProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.asset.profile.TbAssetProfileService; import org.thingsboard.server.service.security.permission.Operation; @@ -43,13 +47,11 @@ import org.thingsboard.server.service.security.permission.Resource; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -68,12 +70,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profile (getAssetProfileById)", notes = "Fetch the Asset Profile object based on the provided Asset Profile Id. " + "The server checks that the asset profile is owned by the same tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile/{assetProfileId}", method = RequestMethod.GET) @ResponseBody public AssetProfile getAssetProfileById( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -83,12 +85,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profile Info (getAssetProfileInfoById)", notes = "Fetch the Asset Profile Info object based on the provided Asset Profile Id. " + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assetProfileInfo/{assetProfileId}", method = RequestMethod.GET) @ResponseBody public AssetProfileInfo getAssetProfileInfoById( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -98,7 +100,7 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Default Asset Profile (getDefaultAssetProfileInfo)", notes = "Fetch the Default Asset Profile Info object. " + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assetProfileInfo/default", method = RequestMethod.GET) @ResponseBody @@ -114,13 +116,12 @@ public class AssetProfileController extends BaseController { "Asset profile name is unique in the scope of tenant. Only one 'default' asset profile may exist in scope of tenant. " + "Remove 'id', 'tenantId' from the request body example (below) to create new Asset Profile entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json", - consumes = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile", method = RequestMethod.POST) @ResponseBody public AssetProfile saveAssetProfile( - @ApiParam(value = "A JSON value representing the asset profile.") + @Parameter(description = "A JSON value representing the asset profile.") @RequestBody AssetProfile assetProfile) throws Exception { assetProfile.setTenantId(getTenantId()); checkEntity(assetProfile.getId(), assetProfile, Resource.ASSET_PROFILE); @@ -130,12 +131,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Delete asset profile (deleteAssetProfile)", notes = "Deletes the asset profile. Referencing non-existing asset profile Id will cause an error. " + "Can't delete the asset profile if it is referenced by existing assets." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile/{assetProfileId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteAssetProfile( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -145,12 +146,12 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Make Asset Profile Default (setDefaultAssetProfile)", notes = "Marks asset profile as default within a tenant scope." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfile/{assetProfileId}/default", method = RequestMethod.POST) @ResponseBody public AssetProfile setDefaultAssetProfile( - @ApiParam(value = ASSET_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(ASSET_PROFILE_ID) String strAssetProfileId) throws ThingsboardException { checkParameter(ASSET_PROFILE_ID, strAssetProfileId); AssetProfileId assetProfileId = new AssetProfileId(toUUID(strAssetProfileId)); @@ -162,20 +163,20 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profiles (getAssetProfiles)", notes = "Returns a page of asset profile objects owned by tenant. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/assetProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAssetProfiles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(assetProfileService.findAssetProfiles(getTenantId(), pageLink)); @@ -184,20 +185,20 @@ public class AssetProfileController extends BaseController { @ApiOperation(value = "Get Asset Profile infos (getAssetProfileInfos)", notes = "Returns a page of asset profile info objects owned by tenant. " + PAGE_DATA_PARAMETERS + ASSET_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/assetProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAssetProfileInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ASSET_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(assetProfileService.findAssetProfileInfos(getTenantId(), pageLink)); diff --git a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java index 387f0d014b..71113d41fa 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuditLogController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -35,6 +37,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.Arrays; @@ -42,7 +45,6 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -import static org.thingsboard.server.controller.ControllerConstants.AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.AUDIT_LOG_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_ID_PARAM_DESCRIPTION; @@ -50,7 +52,6 @@ import static org.thingsboard.server.controller.ControllerConstants.ENTITY_TYPE_ import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.USER_ID_PARAM_DESCRIPTION; @@ -74,28 +75,28 @@ public class AuditLogController extends BaseController { notes = "Returns a page of audit logs related to the targeted customer entities (devices, assets, etc.), " + "and users actions (login, logout, etc.) that belong to this customer. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs/customer/{customerId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogsByCustomerId( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { checkParameter("CustomerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -108,28 +109,28 @@ public class AuditLogController extends BaseController { notes = "Returns a page of audit logs related to the actions of targeted user. " + "For example, RPC call to a particular device, or alarm acknowledgment for a specific device, etc. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs/user/{userId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogsByUserId( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable("userId") String strUserId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { checkParameter("UserId", strUserId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -143,30 +144,30 @@ public class AuditLogController extends BaseController { "Basically, this API call is used to get the full lifecycle of some specific entity. " + "For example to see when a device was created, updated, assigned to some customer, or even deleted from the system. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs/entity/{entityType}/{entityId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogsByEntityId( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String strEntityId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -179,26 +180,26 @@ public class AuditLogController extends BaseController { @ApiOperation(value = "Get all audit logs (getAuditLogs)", notes = "Returns a page of audit logs related to all entities in the scope of the current user's Tenant. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/audit/logs", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getAuditLogs( - @ApiParam(value = PAGE_SIZE_DESCRIPTION) + @Parameter(description = PAGE_SIZE_DESCRIPTION) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION) + @Parameter(description = PAGE_NUMBER_DESCRIPTION) @RequestParam int page, - @ApiParam(value = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = AUDIT_LOG_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, allowableValues = AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = AUDIT_LOG_SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "entityType", "entityName", "userName", "actionType", "actionStatus"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) + @Parameter(description = AUDIT_LOG_QUERY_ACTION_TYPES_DESCRIPTION) @RequestParam(name = "actionTypes", required = false) String actionTypesStr) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); List actionTypes = parseActionTypesStr(actionTypesStr); diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index 5357c0e2a4..86941e2b07 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -16,8 +16,8 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -48,9 +48,10 @@ import org.thingsboard.server.common.data.security.event.UserSessionInvalidation import org.thingsboard.server.common.data.security.model.JwtPair; import org.thingsboard.server.common.data.security.model.SecuritySettings; import org.thingsboard.server.common.data.security.model.UserPasswordPolicy; -import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.util.limits.LimitedApi; import org.thingsboard.server.dao.util.limits.RateLimitService; +import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.rest.RestAuthenticationDetails; import org.thingsboard.server.service.security.model.ActivateUserRequest; import org.thingsboard.server.service.security.model.ChangePasswordRequest; @@ -61,7 +62,6 @@ import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.system.SystemSecurityService; -import jakarta.servlet.http.HttpServletRequest; import java.net.URI; import java.net.URISyntaxException; @@ -107,7 +107,7 @@ public class AuthController extends BaseController { @RequestMapping(value = "/auth/changePassword", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public ObjectNode changePassword( - @ApiParam(value = "Change Password Request") + @Parameter(description = "Change Password Request") @RequestBody ChangePasswordRequest changePasswordRequest) throws ThingsboardException { String currentPassword = changePasswordRequest.getCurrentPassword(); String newPassword = changePasswordRequest.getNewPassword(); @@ -148,7 +148,7 @@ public class AuthController extends BaseController { "If token is not valid, returns '409 Conflict'.") @RequestMapping(value = "/noauth/activate", params = {"activateToken"}, method = RequestMethod.GET) public ResponseEntity checkActivateToken( - @ApiParam(value = "The activate token string.") + @Parameter(description = "The activate token string.") @RequestParam(value = "activateToken") String activateToken) { HttpHeaders headers = new HttpHeaders(); HttpStatus responseStatus; @@ -175,7 +175,7 @@ public class AuthController extends BaseController { @RequestMapping(value = "/noauth/resetPasswordByEmail", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void requestResetPasswordByEmail( - @ApiParam(value = "The JSON object representing the reset password email request.") + @Parameter(description = "The JSON object representing the reset password email request.") @RequestBody ResetPasswordEmailRequest resetPasswordByEmailRequest, HttpServletRequest request) throws ThingsboardException { try { @@ -198,7 +198,7 @@ public class AuthController extends BaseController { "If token is not valid, returns '409 Conflict'.") @RequestMapping(value = "/noauth/resetPassword", params = {"resetToken"}, method = RequestMethod.GET) public ResponseEntity checkResetToken( - @ApiParam(value = "The reset token string.") + @Parameter(description = "The reset token string.") @RequestParam(value = "resetToken") String resetToken) { HttpHeaders headers = new HttpHeaders(); HttpStatus responseStatus; @@ -234,7 +234,7 @@ public class AuthController extends BaseController { @ResponseStatus(value = HttpStatus.OK) @ResponseBody public JwtPair activateUser( - @ApiParam(value = "Activate user request.") + @Parameter(description = "Activate user request.") @RequestBody ActivateUserRequest activateRequest, @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail, HttpServletRequest request) throws ThingsboardException { @@ -272,7 +272,7 @@ public class AuthController extends BaseController { @ResponseStatus(value = HttpStatus.OK) @ResponseBody public JwtPair resetPassword( - @ApiParam(value = "Reset password request.") + @Parameter(description = "Reset password request.") @RequestBody ResetPasswordRequest resetPasswordRequest, HttpServletRequest request) throws ThingsboardException { String resetToken = resetPasswordRequest.getResetToken(); diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index da2740a3b7..13118645a8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -20,6 +20,9 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; +import jakarta.mail.MessagingException; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.ConstraintViolation; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -160,9 +163,6 @@ import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; import org.thingsboard.server.service.telemetry.AlarmSubscriptionService; import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService; -import jakarta.mail.MessagingException; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.ConstraintViolation; import java.util.List; import java.util.Objects; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java index 33a4edfbe0..b0f1786437 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java +++ b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.HashSet; @@ -54,7 +55,7 @@ public class ComponentDescriptorController extends BaseController { @RequestMapping(value = "/component/{componentDescriptorClazz:.+}", method = RequestMethod.GET) @ResponseBody public ComponentDescriptor getComponentDescriptorByClazz( - @ApiParam(value = "Component Descriptor class name", required = true) + @Parameter(description = "Component Descriptor class name", required = true) @PathVariable("componentDescriptorClazz") String strComponentDescriptorClazz) throws ThingsboardException { checkParameter("strComponentDescriptorClazz", strComponentDescriptorClazz); return checkComponentDescriptorByClazz(strComponentDescriptorClazz); @@ -67,9 +68,9 @@ public class ComponentDescriptorController extends BaseController { @RequestMapping(value = "/components/{componentType}", method = RequestMethod.GET) @ResponseBody public List getComponentDescriptorsByType( - @ApiParam(value = "Type of the Rule Node", allowableValues = "ENRICHMENT,FILTER,TRANSFORMATION,ACTION,EXTERNAL", required = true) + @Parameter(description = "Type of the Rule Node", schema = @Schema(allowableValues = "ENRICHMENT,FILTER,TRANSFORMATION,ACTION,EXTERNAL", required = true)) @PathVariable("componentType") String strComponentType, - @ApiParam(value = "Type of the Rule Chain", allowableValues = "CORE,EDGE") + @Parameter(description = "Type of the Rule Chain", schema = @Schema(allowableValues = "CORE,EDGE")) @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException { checkParameter("componentType", strComponentType); return checkComponentDescriptorsByType(ComponentType.valueOf(strComponentType), getRuleChainType(strRuleChainType)); @@ -82,9 +83,9 @@ public class ComponentDescriptorController extends BaseController { @RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET) @ResponseBody public List getComponentDescriptorsByTypes( - @ApiParam(value = "List of types of the Rule Nodes, (ENRICHMENT, FILTER, TRANSFORMATION, ACTION or EXTERNAL)", required = true) + @Parameter(description = "List of types of the Rule Nodes, (ENRICHMENT, FILTER, TRANSFORMATION, ACTION or EXTERNAL)", required = true) @RequestParam("componentTypes") String[] strComponentTypes, - @ApiParam(value = "Type of the Rule Chain", allowableValues = "CORE,EDGE") + @Parameter(description = "Type of the Rule Chain", schema = @Schema(allowableValues = "CORE,EDGE")) @RequestParam(value = "ruleChainType", required = false) String strRuleChainType) throws ThingsboardException { checkArrayParameter("componentTypes", strComponentTypes); Set componentTypes = new HashSet<>(); diff --git a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java index f425bde86c..8f95dbff35 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java +++ b/application/src/main/java/org/thingsboard/server/controller/ControllerConstants.java @@ -89,33 +89,8 @@ public class ControllerConstants { protected static final String EVENT_TEXT_SEARCH_DESCRIPTION = "The value is not used in searching."; protected static final String AUDIT_LOG_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on one of the next properties: entityType, entityName, userName, actionType, actionStatus."; protected static final String SORT_PROPERTY_DESCRIPTION = "Property of entity to sort by"; - protected static final String DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title"; - protected static final String CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, city"; - protected static final String RPC_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, expirationTime, request, response"; - protected static final String DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, deviceProfileName, label, customerTitle"; - protected static final String ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type"; - protected static final String ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, customerTitle"; - protected static final String USER_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, firstName, lastName, email"; - protected static final String TENANT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, email, country, state, city, address, address2, zip, phone, email"; - protected static final String TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, description, isDefault"; - protected static final String TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name"; - protected static final String TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, tenantProfileName, title, email, country, state, city, address, address2, zip, phone, email"; - protected static final String DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, transportType, description, isDefault"; - - protected static final String ASSET_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, description, isDefault"; - protected static final String ASSET_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle"; - protected static final String ALARM_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, startTs, endTs, type, ackTs, clearTs, severity, status"; - protected static final String ALARM_COMMENT_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, id"; - protected static final String EVENT_SORT_PROPERTY_ALLOWABLE_VALUES = "ts, id"; - protected static final String EDGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, type, label, customerTitle"; - protected static final String RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, root"; - protected static final String WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, tenantId"; - protected static final String AUDIT_LOG_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, entityType, entityName, userName, actionType, actionStatus"; + protected static final String SORT_ORDER_DESCRIPTION = "Sort order. ASC (ASCENDING) or DESC (DESCENDING)"; - protected static final String SORT_ORDER_ALLOWABLE_VALUES = "ASC, DESC"; - protected static final String RPC_STATUS_ALLOWABLE_VALUES = "QUEUED, SENT, DELIVERED, SUCCESSFUL, TIMEOUT, EXPIRED, FAILED"; - protected static final String RULE_CHAIN_TYPES_ALLOWABLE_VALUES = "CORE, EDGE"; - protected static final String TRANSPORT_TYPE_ALLOWABLE_VALUES = "DEFAULT, MQTT, COAP, LWM2M, SNMP"; protected static final String DEVICE_INFO_DESCRIPTION = "Device Info is an extension of the default Device object that contains information about the assigned customer name and device profile name. "; protected static final String ASSET_INFO_DESCRIPTION = "Asset Info is an extension of the default Asset object that contains information about the assigned customer name. "; protected static final String ALARM_INFO_DESCRIPTION = "Alarm Info is an extension of the default Alarm object that also contains name of the alarm originator."; @@ -125,23 +100,17 @@ public class ControllerConstants { protected static final String ASSET_PROFILE_INFO_DESCRIPTION = "Asset Profile Info is a lightweight object that includes main information about Asset Profile. "; protected static final String QUEUE_SERVICE_TYPE_DESCRIPTION = "Service type (implemented only for the TB-RULE-ENGINE)"; - protected static final String QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES = "TB-RULE-ENGINE, TB-CORE, TB-TRANSPORT, JS-EXECUTOR"; protected static final String QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the queue name."; - protected static final String QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, name, topic"; protected static final String QUEUE_ID_PARAM_DESCRIPTION = "A string value representing the queue id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; protected static final String QUEUE_NAME_PARAM_DESCRIPTION = "A string value representing the queue id. For example, 'Main'"; protected static final String OTA_PACKAGE_INFO_DESCRIPTION = "OTA Package Info is a lightweight object that includes main information about the OTA Package excluding the heavyweight data. "; protected static final String OTA_PACKAGE_DESCRIPTION = "OTA Package is a heavyweight object that includes main information about the OTA Package and also data. "; - protected static final String OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES = "MD5, SHA256, SHA384, SHA512, CRC32, MURMUR3_32, MURMUR3_128"; protected static final String OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the ota package title."; - protected static final String OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, type, title, version, tag, url, fileName, dataSize, checksum"; protected static final String RESOURCE_INFO_DESCRIPTION = "Resource Info is a lightweight object that includes main information about the Resource excluding the heavyweight data. "; protected static final String RESOURCE_DESCRIPTION = "Resource is a heavyweight object that includes main information about the Resource and also data. "; protected static final String RESOURCE_TEXT_SEARCH_DESCRIPTION = "The case insensitive 'substring' filter based on the resource title."; - protected static final String RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES = "createdTime, title, resourceType, tenantId"; protected static final String LWM2M_OBJECT_DESCRIPTION = "LwM2M Object is a object that includes information about the LwM2M model which can be used in transport configuration for the LwM2M device profile. "; - protected static final String LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES = "id, name"; protected static final String DEVICE_NAME_DESCRIPTION = "A string value representing the Device name."; protected static final String ASSET_NAME_DESCRIPTION = "A string value representing the Asset name."; @@ -1439,8 +1408,6 @@ public class ControllerConstants { protected static final String ATTRIBUTES_SCOPE_DESCRIPTION = "A string value representing the attributes scope. For example, 'SERVER_SCOPE'."; protected static final String ATTRIBUTES_KEYS_DESCRIPTION = "A string value representing the comma-separated list of attributes keys. For example, 'active,inactivityAlarmTime'."; - protected static final String ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES = "SERVER_SCOPE, SHARED_SCOPE"; - protected static final String ATTRIBUTES_SCOPE_ALLOWED_VALUES = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES + ", CLIENT_SCOPE"; protected static final String ATTRIBUTES_JSON_REQUEST_DESCRIPTION = "A string value representing the json object. For example, '{\"key\":\"value\"}'. See API call description for more details."; protected static final String TELEMETRY_KEYS_BASE_DESCRIPTION = "A string value representing the comma-separated list of telemetry keys."; diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index dd904add2e..7203f71392 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -17,8 +17,8 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.customer.TbCustomerService; import org.thingsboard.server.service.security.permission.Operation; @@ -44,13 +45,11 @@ import org.thingsboard.server.service.security.permission.Resource; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOARD; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -76,7 +75,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.GET) @ResponseBody public Customer getCustomerById( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -95,7 +94,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customer/{customerId}/shortInfo", method = RequestMethod.GET) @ResponseBody public JsonNode getShortCustomerInfoById( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -113,7 +112,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customer/{customerId}/title", method = RequestMethod.GET, produces = "application/text") @ResponseBody public String getCustomerTitleById( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -131,7 +130,7 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer", method = RequestMethod.POST) @ResponseBody - public Customer saveCustomer(@ApiParam(value = "A JSON value representing the customer.") @RequestBody Customer customer) throws Exception { + public Customer saveCustomer(@Parameter(description = "A JSON value representing the customer.") @RequestBody Customer customer) throws Exception { customer.setTenantId(getTenantId()); checkEntity(customer.getId(), customer, Resource.CUSTOMER); return tbCustomerService.save(customer, getCurrentUser()); @@ -144,7 +143,7 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + public void deleteCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -159,15 +158,15 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/customers", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomers( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = CUSTOMER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = CUSTOMER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = CUSTOMER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "email", "country, city"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); TenantId tenantId = getCurrentUser().getTenantId(); @@ -180,7 +179,7 @@ public class CustomerController extends BaseController { @RequestMapping(value = "/tenant/customers", params = {"customerTitle"}, method = RequestMethod.GET) @ResponseBody public Customer getTenantCustomer( - @ApiParam(value = "A string value representing the Customer title.") + @Parameter(description = "A string value representing the Customer title.") @RequestParam String customerTitle) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(customerService.findCustomerByTenantIdAndTitle(tenantId, customerTitle), "Customer with title [" + customerTitle + "] is not found"); diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index afc737ab88..c6678deffe 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -17,11 +17,11 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.Example; -import io.swagger.annotations.ExampleProperty; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; @@ -51,6 +51,7 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.dashboard.TbDashboardService; import org.thingsboard.server.service.security.model.SecurityUser; @@ -66,7 +67,6 @@ import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.DASHBOARD_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_ASYNC_FIRST_STEP_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION; @@ -77,7 +77,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; @@ -111,7 +110,7 @@ public class DashboardController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/serverTime", method = RequestMethod.GET) @ResponseBody - @ApiResponse(code = 200, message = "OK", examples = @Example(value = @ExampleProperty(value = "1636023857137", mediaType = "application/json"))) + @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "1636023857137"))) public long getServerTime() throws ThingsboardException { return System.currentTimeMillis(); } @@ -124,20 +123,20 @@ public class DashboardController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/maxDatapointsLimit", method = RequestMethod.GET) @ResponseBody - @ApiResponse(code = 200, message = "OK", examples = @Example(value = @ExampleProperty(value = "5000", mediaType = "application/json"))) + @ApiResponse(responseCode = "200", description = "OK", content = @Content(mediaType = "application/json", examples = @ExampleObject(value = "5000"))) public long getMaxDatapointsLimit() throws ThingsboardException { return maxDatapointsLimit; } @ApiOperation(value = "Get Dashboard Info (getDashboardInfoById)", notes = "Get the information about the dashboard based on 'dashboardId' parameter. " + DASHBOARD_INFO_DEFINITION, - produces = MediaType.APPLICATION_JSON_VALUE + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) ) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/info/{dashboardId}", method = RequestMethod.GET) @ResponseBody public DashboardInfo getDashboardInfoById( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -146,13 +145,13 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Dashboard (getDashboardById)", notes = "Get the dashboard based on 'dashboardId' parameter. " + DASHBOARD_DEFINITION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) ) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.GET) @ResponseBody public Dashboard getDashboardById( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -166,13 +165,12 @@ public class DashboardController extends BaseController { "Referencing non-existing dashboard Id will cause 'Not Found' error. " + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Dashboard entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard", method = RequestMethod.POST) @ResponseBody public Dashboard saveDashboard( - @ApiParam(value = "A JSON value representing the dashboard.") + @Parameter(description = "A JSON value representing the dashboard.") @RequestBody Dashboard dashboard) throws Exception { dashboard.setTenantId(getTenantId()); checkEntity(dashboard.getId(), dashboard, Resource.DASHBOARD); @@ -185,7 +183,7 @@ public class DashboardController extends BaseController { @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteDashboard( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -196,14 +194,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Assign the Dashboard (assignDashboardToCustomer)", notes = "Assign the Dashboard to specified Customer or do nothing if the Dashboard is already assigned to that Customer. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody public Dashboard assignDashboardToCustomer( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); checkParameter(DASHBOARD_ID, strDashboardId); @@ -219,14 +217,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Unassign the Dashboard (unassignDashboardFromCustomer)", notes = "Unassign the Dashboard from specified Customer or do nothing if the Dashboard is already assigned to that Customer. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseBody public Dashboard unassignDashboardFromCustomer( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(DASHBOARD_ID, strDashboardId); @@ -240,16 +238,15 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Update the Dashboard Customers (updateDashboardCustomers)", notes = "Updates the list of Customers that this Dashboard is assigned to. Removes previous assignments to customers that are not in the provided list. " + "Returns the Dashboard object. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard/{dashboardId}/customers", method = RequestMethod.POST) @ResponseBody public Dashboard updateDashboardCustomers( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "JSON array with the list of customer ids, or empty to remove all customers") + @Parameter(description = "JSON array with the list of customer ids, or empty to remove all customers") @RequestBody(required = false) String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -261,15 +258,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Adds the Dashboard Customers (addDashboardCustomers)", notes = "Adds the list of Customers to the existing list of assignments for the Dashboard. Keeps previous assignments to customers that are not in the provided list. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard/{dashboardId}/customers/add", method = RequestMethod.POST) @ResponseBody public Dashboard addDashboardCustomers( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "JSON array with the list of customer ids") + @Parameter(description = "JSON array with the list of customer ids") @RequestBody String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -281,15 +277,14 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Remove the Dashboard Customers (removeDashboardCustomers)", notes = "Removes the list of Customers from the existing list of assignments for the Dashboard. Keeps other assignments to customers that are not in the provided list. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE, - consumes = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard/{dashboardId}/customers/remove", method = RequestMethod.POST) @ResponseBody public Dashboard removeDashboardCustomers( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "JSON array with the list of customer ids") + @Parameter(description = "JSON array with the list of customer ids") @RequestBody String[] strCustomerIds) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -305,12 +300,12 @@ public class DashboardController extends BaseController { "Use [assign Asset to Public Customer](#!/asset-controller/assignAssetToPublicCustomerUsingPOST) and " + "[assign Device to Public Customer](#!/device-controller/assignDeviceToPublicCustomerUsingPOST) for this purpose. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody public Dashboard assignDashboardToPublicCustomer( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -321,12 +316,12 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Unassign the Dashboard from Public Customer (unassignDashboardFromPublicCustomer)", notes = "Unassigns the dashboard from a special, auto-generated 'Public' Customer. Once unassigned, unauthenticated users may no longer browse the dashboard. " + "Returns the Dashboard object." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseBody public Dashboard unassignDashboardFromPublicCustomer( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter(DASHBOARD_ID, strDashboardId); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); @@ -337,22 +332,22 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Tenant Dashboards by System Administrator (getTenantDashboards)", notes = "Returns a page of dashboard info objects owned by tenant. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + SYSTEM_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenant/{tenantId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDashboards( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @PathVariable(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); checkTenantId(tenantId, Operation.READ); @@ -363,22 +358,22 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Tenant Dashboards (getTenantDashboards)", notes = "Returns a page of dashboard info objects owned by the tenant of a current user. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDashboards( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = HIDDEN_FOR_MOBILE) + @Parameter(description = HIDDEN_FOR_MOBILE) @RequestParam(required = false) Boolean mobile, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -392,24 +387,24 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Customer Dashboards (getCustomerDashboards)", notes = "Returns a page of dashboard info objects owned by the specified customer. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerDashboards( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = HIDDEN_FOR_MOBILE) + @Parameter(description = HIDDEN_FOR_MOBILE) @RequestParam(required = false) Boolean mobile, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -428,7 +423,7 @@ public class DashboardController extends BaseController { "If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. " + "If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. " + DASHBOARD_DEFINITION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/home", method = RequestMethod.GET) @ResponseBody @@ -461,7 +456,7 @@ public class DashboardController extends BaseController { "If 'homeDashboardId' parameter is not set on the User level and the User has authority 'CUSTOMER_USER', check the same parameter for the corresponding Customer. " + "If 'homeDashboardId' parameter is not set on the User and Customer levels then checks the same parameter for the Tenant that owns the user. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/home/info", method = RequestMethod.GET) @ResponseBody @@ -492,7 +487,7 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Tenant Home Dashboard Info (getTenantHomeDashboardInfo)", notes = "Returns the home dashboard info object that is configured as 'homeDashboardId' parameter in the 'additionalInfo' of the corresponding tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.GET) @ResponseBody @@ -514,12 +509,12 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Update Tenant Home Dashboard Info (getTenantHomeDashboardInfo)", notes = "Update the home dashboard assignment for the current tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/dashboard/home/info", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void setTenantHomeDashboardInfo( - @ApiParam(value = "A JSON object that represents home dashboard id and other parameters", required = true) + @Parameter(description = "A JSON object that represents home dashboard id and other parameters", required = true) @RequestBody HomeDashboardInfo homeDashboardInfo) throws ThingsboardException { if (homeDashboardInfo.getDashboardId() != null) { @@ -582,7 +577,7 @@ public class DashboardController extends BaseController { EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once dashboard will be delivered to edge service, it's going to be available for usage on remote edge instance." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody @@ -606,7 +601,7 @@ public class DashboardController extends BaseController { EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove dashboard locally." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseBody @@ -627,22 +622,22 @@ public class DashboardController extends BaseController { @ApiOperation(value = "Get Edge Dashboards (getEdgeDashboards)", notes = "Returns a page of dashboard info objects assigned to the specified edge. " + DASHBOARD_INFO_DEFINITION + " " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/{edgeId}/dashboards", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeDashboards( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DASHBOARD_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DASHBOARD_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DASHBOARD_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("edgeId", strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 9de6a66041..603409bba0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -19,8 +19,11 @@ import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.annotation.Nullable; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -62,6 +65,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportRequest; import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.device.claim.ClaimResponse; import org.thingsboard.server.dao.device.claim.ClaimResult; import org.thingsboard.server.dao.device.claim.ReclaimResult; @@ -74,7 +78,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -90,7 +93,6 @@ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID_PA import static org.thingsboard.server.controller.ControllerConstants.DEVICE_INFO_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_NAME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_WITH_DEVICE_CREDENTIALS_PARAM_DESCRIPTION_MARKDOWN; @@ -102,7 +104,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -133,7 +134,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.GET) @ResponseBody - public Device getDeviceById(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public Device getDeviceById(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -148,7 +149,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/info/{deviceId}", method = RequestMethod.GET) @ResponseBody - public DeviceInfo getDeviceInfoById(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public DeviceInfo getDeviceInfoById(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -167,8 +168,8 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device", method = RequestMethod.POST) @ResponseBody - public Device saveDevice(@ApiParam(value = "A JSON value representing the device.") @RequestBody Device device, - @ApiParam(value = "Optional value of the device credentials to be used during device creation. " + + public Device saveDevice(@Parameter(description = "A JSON value representing the device.") @RequestBody Device device, + @Parameter(description = "Optional value of the device credentials to be used during device creation. " + "If omitted, access token will be auto-generated.") @RequestParam(name = "accessToken", required = false) String accessToken) throws Exception { device.setTenantId(getCurrentUser().getTenantId()); Device oldDevice = null; @@ -190,7 +191,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device-with-credentials", method = RequestMethod.POST) @ResponseBody - public Device saveDeviceWithCredentials(@ApiParam(value = "The JSON object with device and credentials. See method description above for example.") + public Device saveDeviceWithCredentials(@Parameter(description = "The JSON object with device and credentials. See method description above for example.") @RequestBody SaveDeviceWithCredentialsRequest deviceAndCredentials) throws ThingsboardException { Device device = checkNotNull(deviceAndCredentials.getDevice()); DeviceCredentials credentials = checkNotNull(deviceAndCredentials.getCredentials()); @@ -204,7 +205,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteDevice(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public void deleteDevice(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws Exception { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -217,9 +218,9 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + public Device assignDeviceToCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(DEVICE_ID, strDeviceId); @@ -235,7 +236,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/device/{deviceId}", method = RequestMethod.DELETE) @ResponseBody - public Device unassignDeviceFromCustomer(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public Device unassignDeviceFromCustomer(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -256,7 +257,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToPublicCustomer(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public Device assignDeviceToPublicCustomer(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -269,7 +270,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/{deviceId}/credentials", method = RequestMethod.GET) @ResponseBody - public DeviceCredentials getDeviceCredentialsByDeviceId(@ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + public DeviceCredentials getDeviceCredentialsByDeviceId(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); @@ -285,7 +286,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/device/credentials", method = RequestMethod.POST) @ResponseBody public DeviceCredentials updateDeviceCredentials( - @ApiParam(value = "A JSON value representing the device credentials.") + @Parameter(description = "A JSON value representing the device credentials.") @RequestBody DeviceCredentials deviceCredentials) throws ThingsboardException { checkNotNull(deviceCredentials); Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE_CREDENTIALS); @@ -299,17 +300,17 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/tenant/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDevices( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -327,21 +328,21 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/tenant/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantDeviceInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String deviceProfileId, - @ApiParam(value = DEVICE_ACTIVE_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ACTIVE_PARAM_DESCRIPTION) @RequestParam(required = false) Boolean active, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder ) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); @@ -364,7 +365,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/tenant/devices", params = {"deviceName"}, method = RequestMethod.GET) @ResponseBody public Device getTenantDevice( - @ApiParam(value = DEVICE_NAME_DESCRIPTION) + @Parameter(description = DEVICE_NAME_DESCRIPTION) @RequestParam String deviceName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(deviceService.findDeviceByTenantIdAndName(tenantId, deviceName)); @@ -377,19 +378,19 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/customer/{customerId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerDevices( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -410,23 +411,23 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/customer/{customerId}/deviceInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerDeviceInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String deviceProfileId, - @ApiParam(value = DEVICE_ACTIVE_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ACTIVE_PARAM_DESCRIPTION) @RequestParam(required = false) Boolean active, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -451,7 +452,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/devices", params = {"deviceIds"}, method = RequestMethod.GET) @ResponseBody public List getDevicesByIds( - @ApiParam(value = "A list of devices ids, separated by comma ','") + @Parameter(description = "A list of devices ids, separated by comma ','") @RequestParam("deviceIds") String[] strDeviceIds) throws ThingsboardException, ExecutionException, InterruptedException { checkArrayParameter("deviceIds", strDeviceIds); SecurityUser user = getCurrentUser(); @@ -478,7 +479,7 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/devices", method = RequestMethod.POST) @ResponseBody public List findByQuery( - @ApiParam(value = "The device search query JSON") + @Parameter(description = "The device search query JSON") @RequestBody DeviceSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); @@ -519,9 +520,9 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('CUSTOMER_USER')") @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.POST) @ResponseBody - public DeferredResult claimDevice(@ApiParam(value = "Unique name of the device which is going to be claimed") + public DeferredResult claimDevice(@Parameter(description = "Unique name of the device which is going to be claimed") @PathVariable(DEVICE_NAME) String deviceName, - @ApiParam(value = "Claiming request which can optionally contain secret key") + @Parameter(description = "Claiming request which can optionally contain secret key") @RequestBody(required = false) ClaimRequest claimRequest) throws ThingsboardException { checkParameter(DEVICE_NAME, deviceName); final DeferredResult deferredResult = new DeferredResult<>(); @@ -568,7 +569,7 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/device/{deviceName}/claim", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public DeferredResult reClaimDevice(@ApiParam(value = "Unique name of the device which is going to be reclaimed") + public DeferredResult reClaimDevice(@Parameter(description = "Unique name of the device which is going to be reclaimed") @PathVariable(DEVICE_NAME) String deviceName) throws ThingsboardException { checkParameter(DEVICE_NAME, deviceName); final DeferredResult deferredResult = new DeferredResult<>(); @@ -608,9 +609,9 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/{tenantId}/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToTenant(@ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + public Device assignDeviceToTenant(@Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(TENANT_ID, strTenantId); checkParameter(DEVICE_ID, strDeviceId); @@ -631,13 +632,13 @@ public class DeviceController extends BaseController { "Second, remote edge service will receive a copy of assignment device " + EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once device will be delivered to edge service, it's going to be available for usage on remote edge instance." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) + public Device assignDeviceToEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(DEVICE_ID, strDeviceId); @@ -656,13 +657,13 @@ public class DeviceController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove device " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove device locally." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.DELETE) @ResponseBody - public Device unassignDeviceFromEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION) + public Device unassignDeviceFromEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); checkParameter(DEVICE_ID, strDeviceId); @@ -681,27 +682,27 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/edge/{edgeId}/devices", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeDevices( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_TYPE_DESCRIPTION) + @Parameter(description = DEVICE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(required = false) String deviceProfileId, - @ApiParam(value = DEVICE_ACTIVE_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ACTIVE_PARAM_DESCRIPTION) @RequestParam(required = false) Boolean active, - @ApiParam(value = DEVICE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "deviceProfileName", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Timestamp. Devices with creation time before it won't be queried") + @Parameter(description = "Timestamp. Devices with creation time before it won't be queried") @RequestParam(required = false) Long startTime, - @ApiParam(value = "Timestamp. Devices with creation time after it won't be queried") + @Parameter(description = "Timestamp. Devices with creation time after it won't be queried") @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -728,11 +729,11 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/devices/count/{otaPackageType}/{deviceProfileId}", method = RequestMethod.GET) @ResponseBody - public Long countByDeviceProfileAndEmptyOtaPackage - (@ApiParam(value = "OTA package type", allowableValues = "FIRMWARE, SOFTWARE") - @PathVariable("otaPackageType") String otaPackageType, - @ApiParam(value = "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'") - @PathVariable("deviceProfileId") String deviceProfileId) throws ThingsboardException { + public Long countByDeviceProfileAndEmptyOtaPackage( + @Parameter(description = "OTA package type", schema = @Schema(allowableValues = {"FIRMWARE", "SOFTWARE"})) + @PathVariable("otaPackageType") String otaPackageType, + @Parameter(description = "Device Profile Id. I.g. '784f394c-42b6-435a-983c-b7beff2784f9'") + @PathVariable("deviceProfileId") String deviceProfileId) throws ThingsboardException { checkParameter("OtaPackageType", otaPackageType); checkParameter("DeviceProfileId", deviceProfileId); return deviceService.countDevicesByTenantIdAndDeviceProfileIdAndEmptyOtaPackage( diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java index c888d67252..093f44dcfd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceProfileController.java @@ -15,12 +15,15 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -37,6 +40,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.device.profile.TbDeviceProfileService; @@ -50,18 +54,15 @@ import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFI import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; -import static org.thingsboard.server.controller.ControllerConstants.TRANSPORT_TYPE_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @RestController @@ -79,12 +80,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profile (getDeviceProfileById)", notes = "Fetch the Device Profile object based on the provided Device Profile Id. " + "The server checks that the device profile is owned by the same tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/{deviceProfileId}", method = RequestMethod.GET) @ResponseBody public DeviceProfile getDeviceProfileById( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -94,12 +95,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profile Info (getDeviceProfileInfoById)", notes = "Fetch the Device Profile Info object based on the provided Device Profile Id. " + DEVICE_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/deviceProfileInfo/{deviceProfileId}", method = RequestMethod.GET) @ResponseBody public DeviceProfileInfo getDeviceProfileInfoById( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -109,7 +110,7 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Default Device Profile (getDefaultDeviceProfileInfo)", notes = "Fetch the Default Device Profile Info object. " + DEVICE_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/deviceProfileInfo/default", method = RequestMethod.GET) @ResponseBody @@ -123,12 +124,12 @@ public class DeviceProfileController extends BaseController { "The call is used for auto-complete in the UI forms. " + "The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/devices/keys/timeseries", method = RequestMethod.GET) @ResponseBody public List getTimeseriesKeys( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(name = DEVICE_PROFILE_ID, required = false) String deviceProfileIdStr) throws ThingsboardException { DeviceProfileId deviceProfileId; if (StringUtils.isNotEmpty(deviceProfileIdStr)) { @@ -147,12 +148,12 @@ public class DeviceProfileController extends BaseController { "The call is used for auto-complete in the UI forms. " + "The implementation limits the number of devices that participate in search to 100 as a trade of between accurate results and time-consuming queries. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/devices/keys/attributes", method = RequestMethod.GET) @ResponseBody public List getAttributesKeys( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @RequestParam(name = DEVICE_PROFILE_ID, required = false) String deviceProfileIdStr) throws ThingsboardException { DeviceProfileId deviceProfileId; if (StringUtils.isNotEmpty(deviceProfileIdStr)) { @@ -173,13 +174,12 @@ public class DeviceProfileController extends BaseController { "Device profile name is unique in the scope of tenant. Only one 'default' device profile may exist in scope of tenant." + DEVICE_PROFILE_DATA + "Remove 'id', 'tenantId' from the request body example (below) to create new Device Profile entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json", - consumes = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile", method = RequestMethod.POST) @ResponseBody public DeviceProfile saveDeviceProfile( - @ApiParam(value = "A JSON value representing the device profile.") + @Parameter(description = "A JSON value representing the device profile.") @RequestBody DeviceProfile deviceProfile) throws Exception { deviceProfile.setTenantId(getTenantId()); checkEntity(deviceProfile.getId(), deviceProfile, Resource.DEVICE_PROFILE); @@ -188,13 +188,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Delete device profile (deleteDeviceProfile)", notes = "Deletes the device profile. Referencing non-existing device profile Id will cause an error. " + - "Can't delete the device profile if it is referenced by existing devices." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + "Can't delete the device profile if it is referenced by existing devices." + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/{deviceProfileId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteDeviceProfile( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -204,12 +203,12 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Make Device Profile Default (setDefaultDeviceProfile)", notes = "Marks device profile as default within a tenant scope." + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfile/{deviceProfileId}/default", method = RequestMethod.POST) @ResponseBody public DeviceProfile setDefaultDeviceProfile( - @ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_PROFILE_ID) String strDeviceProfileId) throws ThingsboardException { checkParameter(DEVICE_PROFILE_ID, strDeviceProfileId); DeviceProfileId deviceProfileId = new DeviceProfileId(toUUID(strDeviceProfileId)); @@ -221,20 +220,20 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profiles (getDeviceProfiles)", notes = "Returns a page of devices profile objects owned by tenant. " + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/deviceProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getDeviceProfiles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "transportType", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(deviceProfileService.findDeviceProfiles(getTenantId(), pageLink)); @@ -243,22 +242,22 @@ public class DeviceProfileController extends BaseController { @ApiOperation(value = "Get Device Profiles for transport type (getDeviceProfileInfos)", notes = "Returns a page of devices profile info objects owned by tenant. " + PAGE_DATA_PARAMETERS + DEVICE_PROFILE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/deviceProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getDeviceProfileInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = DEVICE_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = DEVICE_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "transportType", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Type of the transport", allowableValues = TRANSPORT_TYPE_ALLOWABLE_VALUES) + @Parameter(description = "Type of the transport", schema = @Schema(allowableValues = {"DEFAULT", "MQTT", "COAP", "LWM2M", "SNMP"})) @RequestParam(required = false) String transportType) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(deviceProfileService.findDeviceProfileInfos(getTenantId(), pageLink, transportType)); diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java index 0213ae5686..153b760531 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeController.java @@ -16,8 +16,11 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.ListenableFuture; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -54,6 +57,7 @@ import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportReques import org.thingsboard.server.common.data.sync.ie.importing.csv.BulkImportResult; import org.thingsboard.server.common.msg.edge.FromEdgeSyncResponse; import org.thingsboard.server.common.msg.edge.ToEdgeSyncRequest; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; @@ -64,7 +68,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -74,14 +77,12 @@ import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.EDGE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.EDGE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EDGE_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -112,11 +113,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge (getEdgeById)", notes = "Get the Edge object based on the provided Edge Id. " + EDGE_SECURITY_CHECK + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.GET) @ResponseBody - public Edge getEdgeById(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge getEdgeById(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -125,11 +126,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge Info (getEdgeInfoById)", notes = "Get the Edge Info object based on the provided Edge Id. " + EDGE_SECURITY_CHECK + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/info/{edgeId}", method = RequestMethod.GET) @ResponseBody - public EdgeInfo getEdgeInfoById(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public EdgeInfo getEdgeInfoById(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -144,11 +145,11 @@ public class EdgeController extends BaseController { "\n\nEdge name is unique in the scope of tenant. Use unique identifiers like MAC or IMEI for the edge names and non-unique 'label' field for user-friendly visualization purposes." + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Edge entity. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge", method = RequestMethod.POST) @ResponseBody - public Edge saveEdge(@ApiParam(value = "A JSON value representing the edge.", required = true) + public Edge saveEdge(@Parameter(description = "A JSON value representing the edge.", required = true) @RequestBody Edge edge) throws Exception { TenantId tenantId = getTenantId(); edge.setTenantId(tenantId); @@ -174,7 +175,7 @@ public class EdgeController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public void deleteEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -184,19 +185,19 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edges (getEdges)", notes = "Returns a page of edges owned by tenant. " + - PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edges", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody - public PageData getEdges(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getEdges(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); TenantId tenantId = getCurrentUser().getTenantId(); @@ -205,13 +206,13 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Assign edge to customer (assignEdgeToCustomer)", notes = "Creates assignment of the edge to customer. Customer will be able to query edge afterwards." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}/edge/{edgeId}", method = RequestMethod.POST) @ResponseBody - public Edge assignEdgeToCustomer(@ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + public Edge assignEdgeToCustomer(@Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter("customerId", strCustomerId); checkParameter(EDGE_ID, strEdgeId); @@ -224,11 +225,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Unassign edge from customer (unassignEdgeFromCustomer)", notes = "Clears assignment of the edge to customer. Customer will not be able to query edge afterwards." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/edge/{edgeId}", method = RequestMethod.DELETE) @ResponseBody - public Edge unassignEdgeFromCustomer(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge unassignEdgeFromCustomer(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -245,11 +246,11 @@ public class EdgeController extends BaseController { notes = "Edge will be available for non-authorized (not logged-in) users. " + "This is useful to create dashboards that you plan to share/embed on a publicly available website. " + "However, users that are logged-in and belong to different tenant will not be able to access the edge." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/edge/{edgeId}", method = RequestMethod.POST) @ResponseBody - public Edge assignEdgeToPublicCustomer(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge assignEdgeToPublicCustomer(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); @@ -259,22 +260,22 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edges (getTenantEdges)", notes = "Returns a page of edges owned by tenant. " + - PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/edges", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEdges( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -288,22 +289,22 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edge Infos (getTenantEdgeInfos)", notes = "Returns a page of edges info objects owned by tenant. " + PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/edgeInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEdgeInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -317,11 +318,11 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Tenant Edge (getTenantEdge)", notes = "Requested edge must be owned by tenant or customer that the user belongs to. " + "Edge name is an unique property of edge. So it can be used to identify the edge." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/edges", params = {"edgeName"}, method = RequestMethod.GET) @ResponseBody - public Edge getTenantEdge(@ApiParam(value = "Unique name of the edge", required = true) + public Edge getTenantEdge(@Parameter(description = "Unique name of the edge", required = true) @RequestParam String edgeName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(edgeService.findEdgeByTenantIdAndName(tenantId, edgeName)); @@ -330,13 +331,13 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Set root rule chain for provided edge (setEdgeRootRuleChain)", notes = "Change root rule chain of the edge to the new provided rule chain. \n" + "This operation will send a notification to update root rule chain on remote edge service." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/{ruleChainId}/root", method = RequestMethod.POST) @ResponseBody - public Edge setEdgeRootRuleChain(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public Edge setEdgeRootRuleChain(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION, required = true) @PathVariable("ruleChainId") String strRuleChainId) throws Exception { checkParameter(EDGE_ID, strEdgeId); checkParameter("ruleChainId", strRuleChainId); @@ -350,24 +351,24 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Customer Edges (getCustomerEdges)", notes = "Returns a page of edges objects assigned to customer. " + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/edges", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEdges( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); SecurityUser user = getCurrentUser(); @@ -386,24 +387,24 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Customer Edge Infos (getCustomerEdgeInfos)", notes = "Returns a page of edges info objects assigned to customer. " + - PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS + EDGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/edgeInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEdgeInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable("customerId") String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EDGE_TYPE_DESCRIPTION) + @Parameter(description = EDGE_TYPE_DESCRIPTION) @RequestParam(required = false) String type, - @ApiParam(value = EDGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EDGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); SecurityUser user = getCurrentUser(); @@ -422,12 +423,12 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edges By Ids (getEdgesByIds)", notes = "Requested edges must be owned by tenant or assigned to customer which user is performing the request." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edges", params = {"edgeIds"}, method = RequestMethod.GET) @ResponseBody public List getEdgesByIds( - @ApiParam(value = "A list of edges ids, separated by comma ','", required = true) + @Parameter(description = "A list of edges ids, separated by comma ','", required = true) @RequestParam("edgeIds") String[] strEdgeIds) throws ThingsboardException, ExecutionException, InterruptedException { checkArrayParameter("edgeIds", strEdgeIds); SecurityUser user = getCurrentUser(); @@ -451,7 +452,7 @@ public class EdgeController extends BaseController { notes = "Returns all edges that are related to the specific entity. " + "The entity id, relation type, edge types, depth of the search, and other query parameters defined using complex 'EdgeSearchQuery' object. " + "See 'Model' tab of the Parameters for more info." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edges", method = RequestMethod.POST) @ResponseBody @@ -477,7 +478,7 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge Types (getEdgeTypes)", notes = "Returns a set of unique edge types based on edges that are either owned by the tenant or assigned to the customer which user is performing the request." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/edge/types", method = RequestMethod.GET) @ResponseBody @@ -493,7 +494,7 @@ public class EdgeController extends BaseController { "All entities that are assigned to particular edge are going to be send to remote edge service." + TENANT_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/sync/{edgeId}", method = RequestMethod.POST) - public DeferredResult syncEdge(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public DeferredResult syncEdge(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("edgeId") String strEdgeId) throws ThingsboardException { checkParameter("edgeId", strEdgeId); final DeferredResult response = new DeferredResult<>(); @@ -523,7 +524,7 @@ public class EdgeController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/missingToRelatedRuleChains/{edgeId}", method = RequestMethod.GET) @ResponseBody - public String findMissingToRelatedRuleChains(@ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + public String findMissingToRelatedRuleChains(@Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("edgeId") String strEdgeId) throws ThingsboardException { EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); edgeId = checkNotNull(edgeId); @@ -534,7 +535,7 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Import the bulk of edges (processEdgesBulkImport)", notes = "There's an ability to import the bulk of edges using the only .csv file." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @PostMapping("/edge/bulk_import") public BulkImportResult processEdgesBulkImport(@RequestBody BulkImportRequest request) throws Exception { @@ -549,12 +550,12 @@ public class EdgeController extends BaseController { @ApiOperation(value = "Get Edge Docker Install Instructions (getEdgeDockerInstallInstructions)", notes = "Get a docker install instructions for provided edge id." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/instructions/{edgeId}", method = RequestMethod.GET) @ResponseBody public EdgeInstallInstructions getEdgeDockerInstallInstructions( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("edgeId") String strEdgeId, HttpServletRequest request) throws ThingsboardException { EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java index fc85f439e0..fc95c02217 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EdgeEventController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -33,16 +35,15 @@ import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.edge.EdgeEventService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; import static org.thingsboard.server.controller.ControllerConstants.EDGE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.EDGE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; @@ -59,26 +60,26 @@ public class EdgeEventController extends BaseController { @ApiOperation(value = "Get Edge Events (getEdgeEvents)", notes = "Returns a page of edge events for the requested edge. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/events", method = RequestMethod.GET) @ResponseBody public PageData getEdgeEvents( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "The case insensitive 'substring' filter based on the edge event type name.") + @Parameter(description = "The case insensitive 'substring' filter based on the edge event type name.") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EDGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "label", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Timestamp. Edge events with creation time before it won't be queried") + @Parameter(description = "Timestamp. Edge events with creation time before it won't be queried") @RequestParam(required = false) Long startTime, - @ApiParam(value = "Timestamp. Edge events with creation time after it won't be queried") + @Parameter(description = "Timestamp. Edge events with creation time after it won't be queried") @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java b/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java index b5c8e18ed2..b501771a3e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntitiesVersionControlController.java @@ -18,8 +18,8 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; @@ -46,6 +46,7 @@ import org.thingsboard.server.common.data.sync.vc.VersionLoadResult; import org.thingsboard.server.common.data.sync.vc.VersionedEntityInfo; import org.thingsboard.server.common.data.sync.vc.request.create.VersionCreateRequest; import org.thingsboard.server.common.data.sync.vc.request.load.VersionLoadRequest; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; @@ -67,7 +68,6 @@ import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -189,7 +189,7 @@ public class EntitiesVersionControlController extends BaseController { MARKDOWN_CODE_BLOCK_END + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version/{requestId}/status") - public VersionCreationResult getVersionCreateRequestStatus(@ApiParam(value = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) + public VersionCreationResult getVersionCreateRequestStatus(@Parameter(description = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) @PathVariable UUID requestId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.WRITE); return versionControlService.getVersionCreateStatus(getCurrentUser(), requestId); @@ -232,21 +232,21 @@ public class EntitiesVersionControlController extends BaseController { MARKDOWN_CODE_BLOCK_END + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version/{entityType}/{externalEntityUuid}", params = {"branch", "pageSize", "page"}) - public DeferredResult> listEntityVersions(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult> listEntityVersions(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = "A string value representing external entity id. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity.") + @Parameter(description = "A string value representing external entity id. This is `externalId` property of an entity, or otherwise if not set - simply id of this entity.") @PathVariable UUID externalEntityUuid, - @ApiParam(value = BRANCH_PARAM_DESCRIPTION) + @Parameter(description = BRANCH_PARAM_DESCRIPTION) @RequestParam String branch, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = "timestamp") + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = "timestamp")) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); EntityId externalEntityId = EntityIdFactory.getByTypeAndUuid(entityType, externalEntityUuid); @@ -261,19 +261,19 @@ public class EntitiesVersionControlController extends BaseController { "The response structure is the same as for `listEntityVersions` API method." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version/{entityType}", params = {"branch", "pageSize", "page"}) - public DeferredResult> listEntityTypeVersions(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult> listEntityTypeVersions(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = BRANCH_PARAM_DESCRIPTION, required = true) + @Parameter(description = BRANCH_PARAM_DESCRIPTION, required = true) @RequestParam String branch, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = "timestamp") + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = "timestamp")) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -286,17 +286,17 @@ public class EntitiesVersionControlController extends BaseController { "The response format is the same as for `listEntityVersions` API method." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/version", params = {"branch", "pageSize", "page"}) - public DeferredResult> listVersions(@ApiParam(value = BRANCH_PARAM_DESCRIPTION, required = true) + public DeferredResult> listVersions(@Parameter(description = BRANCH_PARAM_DESCRIPTION, required = true) @RequestParam String branch, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VERSION_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = "timestamp") + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = "timestamp")) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -310,9 +310,9 @@ public class EntitiesVersionControlController extends BaseController { "Entities order will be the same as in the repository." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/entity/{entityType}/{versionId}") - public DeferredResult> listEntitiesAtVersion(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult> listEntitiesAtVersion(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @PathVariable String versionId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); return wrapFuture(versionControlService.listEntitiesAtVersion(getTenantId(), versionId, entityType)); @@ -324,7 +324,7 @@ public class EntitiesVersionControlController extends BaseController { "Returned entities order will be the same as in the repository." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/entity/{versionId}") - public DeferredResult> listAllEntitiesAtVersion(@ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + public DeferredResult> listAllEntitiesAtVersion(@Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @PathVariable String versionId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); return wrapFuture(versionControlService.listAllEntitiesAtVersion(getTenantId(), versionId)); @@ -337,11 +337,11 @@ public class EntitiesVersionControlController extends BaseController { "`hasCredentials` (whether stored device data has credentials)." + TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/info/{versionId}/{entityType}/{externalEntityUuid}") - public DeferredResult getEntityDataInfo(@ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + public DeferredResult getEntityDataInfo(@Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @PathVariable String versionId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = "A string value representing external entity id", required = true) + @Parameter(description = "A string value representing external entity id", required = true) @PathVariable UUID externalEntityUuid) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, externalEntityUuid); @@ -353,11 +353,11 @@ public class EntitiesVersionControlController extends BaseController { "Entity data structure is the same as stored in a repository. " + TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/diff/{entityType}/{internalEntityUuid}", params = {"versionId"}) - public DeferredResult compareEntityDataToVersion(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public DeferredResult compareEntityDataToVersion(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable EntityType entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable UUID internalEntityUuid, - @ApiParam(value = VERSION_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = VERSION_ID_PARAM_DESCRIPTION, required = true) @RequestParam String versionId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.READ); EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, internalEntityUuid); @@ -466,7 +466,7 @@ public class EntitiesVersionControlController extends BaseController { TENANT_AUTHORITY_PARAGRAPH ) @GetMapping(value = "/entity/{requestId}/status") - public VersionLoadResult getVersionLoadRequestStatus(@ApiParam(value = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) + public VersionLoadResult getVersionLoadRequestStatus(@Parameter(description = VC_REQUEST_ID_PARAM_DESCRIPTION, required = true) @PathVariable UUID requestId) throws Exception { accessControlService.checkPermission(getCurrentUser(), Resource.VERSION_CONTROL, Operation.WRITE); return versionControlService.getVersionLoadStatus(getCurrentUser(), requestId); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java b/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java index fbb8901ca9..539d6a81f4 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityQueryController.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; @@ -38,6 +37,7 @@ import org.thingsboard.server.common.data.query.EntityCountQuery; import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataQuery; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.query.EntityQueryService; import org.thingsboard.server.service.security.permission.Operation; @@ -61,7 +61,7 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/entitiesQuery/count", method = RequestMethod.POST) @ResponseBody public long countEntitiesByQuery( - @ApiParam(value = "A JSON value representing the entity count query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the entity count query. See API call notes above for more details.") @RequestBody EntityCountQuery query) throws ThingsboardException { checkNotNull(query); return this.entityQueryService.countEntitiesByQuery(getCurrentUser(), query); @@ -72,7 +72,7 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/entitiesQuery/find", method = RequestMethod.POST) @ResponseBody public PageData findEntityDataByQuery( - @ApiParam(value = "A JSON value representing the entity data query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the entity data query. See API call notes above for more details.") @RequestBody EntityDataQuery query) throws ThingsboardException { checkNotNull(query); return this.entityQueryService.findEntityDataByQuery(getCurrentUser(), query); @@ -83,7 +83,7 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/alarmsQuery/find", method = RequestMethod.POST) @ResponseBody public PageData findAlarmDataByQuery( - @ApiParam(value = "A JSON value representing the alarm data query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the alarm data query. See API call notes above for more details.") @RequestBody AlarmDataQuery query) throws ThingsboardException { checkNotNull(query); checkNotNull(query.getPageLink()); @@ -98,7 +98,7 @@ public class EntityQueryController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarmsQuery/count", method = RequestMethod.POST) @ResponseBody - public long countAlarmsByQuery(@ApiParam(value = "A JSON value representing the alarm count query.") + public long countAlarmsByQuery(@Parameter(description = "A JSON value representing the alarm count query.") @RequestBody AlarmCountQuery query) throws ThingsboardException { checkNotNull(query); UserId assigneeId = query.getAssigneeId(); @@ -114,11 +114,11 @@ public class EntityQueryController extends BaseController { @RequestMapping(value = "/entitiesQuery/find/keys", method = RequestMethod.POST) @ResponseBody public DeferredResult findEntityTimeseriesAndAttributesKeysByQuery( - @ApiParam(value = "A JSON value representing the entity data query. See API call notes above for more details.") + @Parameter(description = "A JSON value representing the entity data query. See API call notes above for more details.") @RequestBody EntityDataQuery query, - @ApiParam(value = "Include all unique time-series keys to the result.") + @Parameter(description = "Include all unique time-series keys to the result.") @RequestParam("timeseries") boolean isTimeseries, - @ApiParam(value = "Include all unique attribute keys to the result.") + @Parameter(description = "Include all unique attribute keys to the result.") @RequestParam("attributes") boolean isAttributes) throws ThingsboardException { TenantId tenantId = getTenantId(); checkNotNull(query); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index 08448f1d28..cb17661e4a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -15,8 +15,9 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -35,6 +36,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelationInfo; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.RelationTypeGroup; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.entity.relation.TbEntityRelationService; import org.thingsboard.server.service.security.model.SecurityUser; @@ -79,7 +81,7 @@ public class EntityRelationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relation", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void saveRelation(@ApiParam(value = "A JSON value representing the relation.", required = true) + public void saveRelation(@Parameter(description = "A JSON value representing the relation.", required = true) @RequestBody EntityRelation relation) throws ThingsboardException { checkNotNull(relation); checkCanCreateRelation(relation.getFrom()); @@ -96,12 +98,12 @@ public class EntityRelationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relation", method = RequestMethod.DELETE, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) @ResponseStatus(value = HttpStatus.OK) - public void deleteRelation(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { + public void deleteRelation(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); checkParameter(RELATION_TYPE, strRelationType); @@ -123,8 +125,8 @@ public class EntityRelationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.DELETE, params = {"entityId", "entityType"}) @ResponseStatus(value = HttpStatus.OK) - public void deleteRelations(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam("entityId") String strId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam("entityType") String strType) throws ThingsboardException { + public void deleteRelations(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam("entityId") String strId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam("entityType") String strType) throws ThingsboardException { checkParameter("entityId", strId); checkParameter("entityType", strType); EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId); @@ -134,16 +136,16 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get Relation (getRelation)", notes = "Returns relation object between two specified entities if present. Otherwise throws exception. " + SECURITY_CHECKS_ENTITIES_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relation", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) @ResponseBody - public EntityRelation getRelation(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { + public EntityRelation getRelation(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); checkParameter(RELATION_TYPE, strRelationType); @@ -160,13 +162,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByFrom)", notes = "Returns list of relation objects for the specified entity by the 'from' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) @ResponseBody - public List findByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByFrom(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); @@ -179,13 +181,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relation Infos (findInfoByFrom)", notes = "Returns list of relation info objects for the specified entity by the 'from' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION + " " + RELATION_INFO_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) @ResponseBody - public List findInfoByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findInfoByFrom(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); @@ -198,14 +200,14 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByFrom)", notes = "Returns list of relation objects for the specified entity by the 'from' direction and relation type. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE}) @ResponseBody - public List findByFrom(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByFrom(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_ID) String strFromId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(FROM_TYPE) String strFromType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(FROM_ID, strFromId); checkParameter(FROM_TYPE, strFromType); @@ -219,13 +221,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByTo)", notes = "Returns list of relation objects for the specified entity by the 'to' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) @ResponseBody - public List findByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); @@ -238,13 +240,13 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relation Infos (findInfoByTo)", notes = "Returns list of relation info objects for the specified entity by the 'to' direction. " + SECURITY_CHECKS_ENTITY_DESCRIPTION + " " + RELATION_INFO_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) @ResponseBody - public List findInfoByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findInfoByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException, ExecutionException, InterruptedException { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); @@ -257,14 +259,14 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Get List of Relations (findByTo)", notes = "Returns list of relation objects for the specified entity by the 'to' direction and relation type. " + SECURITY_CHECKS_ENTITY_DESCRIPTION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE, RELATION_TYPE}) @ResponseBody - public List findByTo(@ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, - @ApiParam(value = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, - @ApiParam(value = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) + public List findByTo(@Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TO_ID) String strToId, + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(TO_TYPE) String strToType, + @Parameter(description = RELATION_TYPE_PARAM_DESCRIPTION, required = true) @RequestParam(RELATION_TYPE) String strRelationType, + @Parameter(description = RELATION_TYPE_GROUP_PARAM_DESCRIPTION) @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { checkParameter(TO_ID, strToId); checkParameter(TO_TYPE, strToType); @@ -278,11 +280,11 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Find related entities (findByQuery)", notes = "Returns all entities that are related to the specific entity. " + "The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. " + - "See 'Model' tab of the Parameters for more info.", produces = MediaType.APPLICATION_JSON_VALUE) + "See 'Model' tab of the Parameters for more info.", responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations", method = RequestMethod.POST) @ResponseBody - public List findByQuery(@ApiParam(value = "A JSON value representing the entity relations query object.", required = true) + public List findByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true) @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); @@ -294,11 +296,11 @@ public class EntityRelationController extends BaseController { @ApiOperation(value = "Find related entity infos (findInfoByQuery)", notes = "Returns all entity infos that are related to the specific entity. " + "The entity id, relation type, entity types, depth of the search, and other query parameters defined using complex 'EntityRelationsQuery' object. " + - "See 'Model' tab of the Parameters for more info. " + RELATION_INFO_DESCRIPTION, produces = MediaType.APPLICATION_JSON_VALUE) + "See 'Model' tab of the Parameters for more info. " + RELATION_INFO_DESCRIPTION, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relations/info", method = RequestMethod.POST) @ResponseBody - public List findInfoByQuery(@ApiParam(value = "A JSON value representing the entity relations query object.", required = true) + public List findInfoByQuery(@Parameter(description = "A JSON value representing the entity relations query object.", required = true) @RequestBody EntityRelationsQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index b2904a0989..bff71bb43b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -16,8 +16,10 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.ListenableFuture; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -45,6 +47,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -66,15 +69,12 @@ import static org.thingsboard.server.controller.ControllerConstants.EDGE_UNASSIG import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ENTITY_VIEW_TYPE; import static org.thingsboard.server.controller.ControllerConstants.MODEL_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -98,12 +98,12 @@ public class EntityViewController extends BaseController { @ApiOperation(value = "Get entity view (getEntityViewById)", notes = "Fetch the EntityView object based on the provided entity view id. " + ENTITY_VIEW_DESCRIPTION + MODEL_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/entityView/{entityViewId}", method = RequestMethod.GET) @ResponseBody public EntityView getEntityViewById( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); return checkEntityViewId(new EntityViewId(toUUID(strEntityViewId)), Operation.READ); @@ -112,12 +112,12 @@ public class EntityViewController extends BaseController { @ApiOperation(value = "Get Entity View info (getEntityViewInfoById)", notes = "Fetch the Entity View info object based on the provided Entity View Id. " + ENTITY_VIEW_INFO_DESCRIPTION + MODEL_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/entityView/info/{entityViewId}", method = RequestMethod.GET) @ResponseBody public EntityViewInfo getEntityViewInfoById( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -128,12 +128,12 @@ public class EntityViewController extends BaseController { notes = ENTITY_VIEW_DESCRIPTION + MODEL_DESCRIPTION + "Remove 'id', 'tenantId' and optionally 'customerId' from the request body example (below) to create new Entity View entity." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/entityView", method = RequestMethod.POST) @ResponseBody public EntityView saveEntityView( - @ApiParam(value = "A JSON object representing the entity view.") + @Parameter(description = "A JSON object representing the entity view.") @RequestBody EntityView entityView) throws Exception { entityView.setTenantId(getCurrentUser().getTenantId()); EntityView existingEntityView = null; @@ -153,7 +153,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/entityView/{entityViewId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteEntityView( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -163,12 +163,12 @@ public class EntityViewController extends BaseController { @ApiOperation(value = "Get Entity View by name (getTenantEntityView)", notes = "Fetch the Entity View object based on the tenant id and entity view name. " + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/entityViews", params = {"entityViewName"}, method = RequestMethod.GET) @ResponseBody public EntityView getTenantEntityView( - @ApiParam(value = "Entity View name") + @Parameter(description = "Entity View name") @RequestParam String entityViewName) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); return checkNotNull(entityViewService.findEntityViewByTenantIdAndName(tenantId, entityViewName)); @@ -180,9 +180,9 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/{customerId}/entityView/{entityViewId}", method = RequestMethod.POST) @ResponseBody public EntityView assignEntityViewToCustomer( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); checkParameter(ENTITY_VIEW_ID, strEntityViewId); @@ -202,7 +202,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/entityView/{entityViewId}", method = RequestMethod.DELETE) @ResponseBody public EntityView unassignEntityViewFromCustomer( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -223,19 +223,19 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/{customerId}/entityViews", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEntityViews( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name, type"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter(CUSTOMER_ID, strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -256,19 +256,19 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/{customerId}/entityViewInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerEntityViewInfos( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -289,17 +289,17 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/tenant/entityViews", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEntityViews( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name, type"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -318,17 +318,17 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/tenant/entityViewInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantEntityViewInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = ENTITY_VIEW_TYPE) + @Parameter(description = ENTITY_VIEW_TYPE) @RequestParam(required = false) String type, - @ApiParam(value = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = ENTITY_VIEW_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type", "customerTitle"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -347,7 +347,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/entityViews", method = RequestMethod.POST) @ResponseBody public List findByQuery( - @ApiParam(value = "The entity view search query JSON") + @Parameter(description = "The entity view search query JSON") @RequestBody EntityViewSearchQuery query) throws ThingsboardException, ExecutionException, InterruptedException { checkNotNull(query); checkNotNull(query.getParameters()); @@ -386,7 +386,7 @@ public class EntityViewController extends BaseController { @RequestMapping(value = "/customer/public/entityView/{entityViewId}", method = RequestMethod.POST) @ResponseBody public EntityView assignEntityViewToPublicCustomer( - @ApiParam(value = ENTITY_VIEW_ID_PARAM_DESCRIPTION) + @Parameter(description = ENTITY_VIEW_ID_PARAM_DESCRIPTION) @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { checkParameter(ENTITY_VIEW_ID, strEntityViewId); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); @@ -400,7 +400,7 @@ public class EntityViewController extends BaseController { "Second, remote edge service will receive a copy of assignment entity view " + EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once entity view will be delivered to edge service, it's going to be available for usage on remote edge instance.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/entityView/{entityViewId}", method = RequestMethod.POST) @ResponseBody @@ -425,7 +425,7 @@ public class EntityViewController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove entity view " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove entity view locally.", - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/entityView/{entityViewId}", method = RequestMethod.DELETE) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/controller/EventController.java b/application/src/main/java/org/thingsboard/server/controller/EventController.java index ec75f981a7..09ef2e9d05 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EventController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EventController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -39,6 +41,7 @@ import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.TimePageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; @@ -52,7 +55,6 @@ import static org.thingsboard.server.controller.ControllerConstants.EVENT_DEBUG_ import static org.thingsboard.server.controller.ControllerConstants.EVENT_END_TIME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EVENT_ERROR_FILTER_OBJ; import static org.thingsboard.server.controller.ControllerConstants.EVENT_LC_EVENT_FILTER_OBJ; -import static org.thingsboard.server.controller.ControllerConstants.EVENT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.EVENT_START_TIME_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.EVENT_STATS_FILTER_OBJ; import static org.thingsboard.server.controller.ControllerConstants.EVENT_TEXT_SEARCH_DESCRIPTION; @@ -60,7 +62,6 @@ import static org.thingsboard.server.controller.ControllerConstants.NEW_LINE; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID; @@ -107,32 +108,32 @@ public class EventController extends BaseController { @ApiOperation(value = "Get Events by type (getEvents)", notes = "Returns a page of events for specified entity by specifying event type. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}/{eventType}", method = RequestMethod.GET) @ResponseBody public PageData getEvents( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = "A string value representing event type", example = "STATS", required = true) + @Parameter(description = "A string value representing event type", example = "STATS", required = true) @PathVariable("eventType") String eventType, - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EVENT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"ts", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -149,30 +150,30 @@ public class EventController extends BaseController { "The call was deprecated to improve the performance of the system. " + "Current implementation will return 'Lifecycle' events only. " + "Use 'Get events by type' or 'Get events by filter' instead. " + - PAGE_DATA_PARAMETERS, produces = MediaType.APPLICATION_JSON_VALUE) + PAGE_DATA_PARAMETERS, responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.GET) @ResponseBody public PageData getEvents( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @RequestParam("tenantId") String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EVENT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"ts", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -190,32 +191,32 @@ public class EventController extends BaseController { notes = "Returns a page of events for the chosen entity by specifying the event filter. " + PAGE_DATA_PARAMETERS + NEW_LINE + EVENT_FILTER_DEFINITION, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}", method = RequestMethod.POST) @ResponseBody public PageData getEvents( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @RequestParam(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "A JSON value representing the event filter.", required = true) + @Parameter(description = "A JSON value representing the event filter.", required = true) @RequestBody EventFilter eventFilter, - @ApiParam(value = EVENT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = EVENT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = EVENT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"ts", "id"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); @@ -232,15 +233,15 @@ public class EventController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/events/{entityType}/{entityId}/clear", method = RequestMethod.POST) @ResponseStatus(HttpStatus.OK) - public void clearEvents(@ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) + public void clearEvents(@Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_TYPE) String strEntityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @ApiParam(value = EVENT_START_TIME_DESCRIPTION) + @Parameter(description = EVENT_START_TIME_DESCRIPTION) @RequestParam(required = false) Long startTime, - @ApiParam(value = EVENT_END_TIME_DESCRIPTION) + @Parameter(description = EVENT_END_TIME_DESCRIPTION) @RequestParam(required = false) Long endTime, - @ApiParam(value = EVENT_FILTER_DEFINITION) + @Parameter(description = EVENT_FILTER_DEFINITION) @RequestBody EventFilter eventFilter) throws ThingsboardException { checkParameter("EntityId", strEntityId); checkParameter("EntityType", strEntityType); diff --git a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java index 8949cd95dd..433eea639e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java +++ b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java @@ -15,11 +15,13 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; @@ -33,6 +35,7 @@ import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MServerSecurityConfigDefault; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.service.lwm2m.LwM2MService; import java.util.Map; @@ -57,12 +60,12 @@ public class Lwm2mController extends BaseController { @ApiOperation(value = "Get Lwm2m Bootstrap SecurityInfo (getLwm2mBootstrapSecurityInfo)", notes = "Get the Lwm2m Bootstrap SecurityInfo object (of the current server) based on the provided isBootstrapServer parameter. If isBootstrapServer == true, get the parameters of the current Bootstrap Server. If isBootstrapServer == false, get the parameters of the current Lwm2m Server. Used for client settings when starting the client in Bootstrap mode. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{isBootstrapServer}", method = RequestMethod.GET) @ResponseBody public LwM2MServerSecurityConfigDefault getLwm2mBootstrapSecurityInfo( - @ApiParam(value = IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION) + @Parameter(description = IS_BOOTSTRAP_SERVER_PARAM_DESCRIPTION) @PathVariable(IS_BOOTSTRAP_SERVER) boolean bootstrapServer) throws ThingsboardException { return lwM2MService.getServerSecurityInfo(bootstrapServer); } diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java index 5893410b2a..e2a1f1a417 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; @@ -55,6 +55,7 @@ import org.thingsboard.server.common.data.notification.template.NotificationTemp import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.SortOrder; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationRequestService; import org.thingsboard.server.dao.notification.NotificationService; import org.thingsboard.server.dao.notification.NotificationSettingsService; @@ -66,7 +67,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; -import jakarta.validation.Valid; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; @@ -158,17 +158,17 @@ public class NotificationController extends BaseController { "}\n```") @GetMapping("/notifications") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - public PageData getNotifications(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotifications(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filter based on notification subject or text") + @Parameter(description = "Case-insensitive 'substring' filter based on notification subject or text") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "To search for unread notifications only") + @Parameter(description = "To search for unread notifications only") @RequestParam(defaultValue = "false") boolean unreadOnly, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // no permissions @@ -266,7 +266,7 @@ public class NotificationController extends BaseController { @PostMapping("/notification/request/preview") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationRequestPreview getNotificationRequestPreview(@RequestBody @Valid NotificationRequest request, - @ApiParam(value = "Amount of the recipients to show in preview") + @Parameter(description = "Amount of the recipients to show in preview") @RequestParam(defaultValue = "20") int recipientsPreviewSize, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { NotificationTemplate template; @@ -361,15 +361,15 @@ public class NotificationController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/notification/requests") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationRequests(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationRequests(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filed based on the used template name") + @Parameter(description = "Case-insensitive 'substring' filed based on the used template name") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java index 06eabbc215..457fac9304 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; @@ -38,12 +38,12 @@ import org.thingsboard.server.common.data.notification.rule.trigger.Notification import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationRuleService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.validation.Valid; import java.util.UUID; import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_CODE_BLOCK_END; @@ -150,15 +150,15 @@ public class NotificationRuleController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/rules") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationRules(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationRules(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filter based on rule's name") + @Parameter(description = "Case-insensitive 'substring' filter based on rule's name") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java index 6b13e9de9d..1dd16ea462 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -48,12 +48,12 @@ import org.thingsboard.server.common.data.notification.targets.platform.UserList import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationTargetService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.validation.Valid; import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -134,9 +134,9 @@ public class NotificationTargetController extends BaseController { @PostMapping("/target/recipients") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public PageData getRecipientsForNotificationTargetConfig(@RequestBody NotificationTarget notificationTarget, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission @@ -156,7 +156,7 @@ public class NotificationTargetController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping(value = "/targets", params = {"ids"}) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public List getNotificationTargetsByIds(@ApiParam(value = "Comma-separated list of uuids representing targets ids", required = true) + public List getNotificationTargetsByIds(@Parameter(description = "Comma-separated list of uuids representing targets ids", required = true) @RequestParam("ids") UUID[] ids, @AuthenticationPrincipal SecurityUser user) { // generic permission @@ -170,15 +170,15 @@ public class NotificationTargetController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/targets") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationTargets(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationTargets(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filed based on the target's name") + @Parameter(description = "Case-insensitive 'substring' filed based on the target's name") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java index fef919d710..a28e218809 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.security.access.prepost.PreAuthorize; @@ -42,13 +42,13 @@ import org.thingsboard.server.common.data.notification.targets.slack.SlackConver import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.notification.NotificationSettingsService; import org.thingsboard.server.dao.notification.NotificationTemplateService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.validation.Valid; import java.util.List; import java.util.UUID; @@ -137,17 +137,17 @@ public class NotificationTemplateController extends BaseController { SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @GetMapping("/templates") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") - public PageData getNotificationTemplates(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getNotificationTemplates(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Case-insensitive 'substring' filter based on template's name and notification type") + @Parameter(description = "Case-insensitive 'substring' filter based on template's name and notification type") @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION) + @Parameter(description = SORT_PROPERTY_DESCRIPTION) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION) + @Parameter(description = SORT_ORDER_DESCRIPTION) @RequestParam(required = false) String sortOrder, - @ApiParam(value = "Comma-separated list of notification types to filter the templates") + @Parameter(description = "Comma-separated list of notification types to filter the templates") @RequestParam(required = false) NotificationType[] notificationTypes, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { // generic permission @@ -177,7 +177,7 @@ public class NotificationTemplateController extends BaseController { @GetMapping("/slack/conversations") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public List listSlackConversations(@RequestParam SlackConversationType type, - @ApiParam(value = "Slack bot token. If absent - system Slack settings will be used") + @Parameter(description = "Slack bot token. If absent - system Slack settings will be used") @RequestParam(required = false) String token, @AuthenticationPrincipal SecurityUser user) { // generic permission diff --git a/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java index f547a5f0ad..63258c5196 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2ConfigTemplateController.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.OAuth2ClientRegistrationTemplateId; import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplate; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -63,7 +63,7 @@ public class OAuth2ConfigTemplateController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @RequestMapping(value = "/{clientRegistrationTemplateId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteClientRegistrationTemplate(@ApiParam(value = "String representation of client registration template id to delete", example = "139b1f81-2f5d-11ec-9dbe-9b627e1a88f4") + public void deleteClientRegistrationTemplate(@Parameter(description = "String representation of client registration template id to delete", example = "139b1f81-2f5d-11ec-9dbe-9b627e1a88f4") @PathVariable(CLIENT_REGISTRATION_TEMPLATE_ID) String strClientRegistrationTemplateId) throws ThingsboardException { checkParameter(CLIENT_REGISTRATION_TEMPLATE_ID, strClientRegistrationTemplateId); accessControlService.checkPermission(getCurrentUser(), Resource.OAUTH2_CONFIGURATION_TEMPLATE, Operation.DELETE); diff --git a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java index 519629fbc3..1688f08b52 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/OAuth2Controller.java @@ -15,8 +15,9 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -33,13 +34,13 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.oauth2.OAuth2ClientInfo; import org.thingsboard.server.common.data.oauth2.OAuth2Info; import org.thingsboard.server.common.data.oauth2.PlatformType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.oauth2.OAuth2Configuration; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.utils.MiscUtils; -import jakarta.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.List; @@ -61,13 +62,13 @@ public class OAuth2Controller extends BaseController { @RequestMapping(value = "/noauth/oauth2Clients", method = RequestMethod.POST) @ResponseBody public List getOAuth2Clients(HttpServletRequest request, - @ApiParam(value = "Mobile application package name, to find OAuth2 clients " + + @Parameter(description = "Mobile application package name, to find OAuth2 clients " + "where there is configured mobile application with such package name") @RequestParam(required = false) String pkgName, - @ApiParam(value = "Platform type to search OAuth2 clients for which " + + @Parameter(description = "Platform type to search OAuth2 clients for which " + "the usage with this platform type is allowed in the settings. " + "If platform type is not one of allowable values - it will just be ignored", - allowableValues = "WEB, ANDROID, IOS") + schema = @Schema(allowableValues = "WEB, ANDROID, IOS")) @RequestParam(required = false) String platform) throws ThingsboardException { if (log.isDebugEnabled()) { log.debug("Executing getOAuth2Clients: [{}][{}][{}]", request.getScheme(), request.getServerName(), request.getServerPort()); @@ -81,7 +82,8 @@ public class OAuth2Controller extends BaseController { if (StringUtils.isNotEmpty(platform)) { try { platformType = PlatformType.valueOf(platform); - } catch (Exception e) {} + } catch (Exception e) { + } } return oAuth2Service.getOAuth2Clients(MiscUtils.getScheme(request), MiscUtils.getDomainNameAndPort(request), pkgName, platformType); } diff --git a/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java index 9b923e01dc..2ee07ce196 100644 --- a/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java +++ b/application/src/main/java/org/thingsboard/server/controller/OtaPackageController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; @@ -42,6 +44,7 @@ import org.thingsboard.server.common.data.ota.ChecksumAlgorithm; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.ota.TbOtaPackageService; import org.thingsboard.server.service.security.permission.Operation; @@ -52,16 +55,13 @@ import java.io.IOException; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -84,7 +84,7 @@ public class OtaPackageController extends BaseController { @PreAuthorize("hasAnyAuthority( 'TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}/download", method = RequestMethod.GET) @ResponseBody - public ResponseEntity downloadOtaPackage(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public ResponseEntity downloadOtaPackage(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); @@ -106,11 +106,11 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package Info (getOtaPackageInfoById)", notes = "Fetch the OTA Package Info object based on the provided OTA Package Id. " + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/otaPackage/info/{otaPackageId}", method = RequestMethod.GET) @ResponseBody - public OtaPackageInfo getOtaPackageInfoById(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public OtaPackageInfo getOtaPackageInfoById(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); @@ -120,11 +120,11 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package (getOtaPackageById)", notes = "Fetch the OTA Package object based on the provided OTA Package Id. " + "The server checks that the OTA Package is owned by the same tenant. " + OTA_PACKAGE_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.GET) @ResponseBody - public OtaPackage getOtaPackageById(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public OtaPackage getOtaPackageById(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); @@ -137,12 +137,11 @@ public class OtaPackageController extends BaseController { "Specify existing OTA Package id to update the OTA Package Info. " + "Referencing non-existing OTA Package Id will cause 'Not Found' error. " + "\n\nOTA Package combination of the title with the version is unique in the scope of tenant. " + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE, - consumes = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage", method = RequestMethod.POST) @ResponseBody - public OtaPackageInfo saveOtaPackageInfo(@ApiParam(value = "A JSON value representing the OTA Package.") + public OtaPackageInfo saveOtaPackageInfo(@Parameter(description = "A JSON value representing the OTA Package.") @RequestBody SaveOtaPackageInfoRequest otaPackageInfo) throws ThingsboardException { otaPackageInfo.setTenantId(getTenantId()); checkEntity(otaPackageInfo.getId(), otaPackageInfo, Resource.OTA_PACKAGE); @@ -152,18 +151,18 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Save OTA Package data (saveOtaPackageData)", notes = "Update the OTA Package. Adds the date to the existing OTA Package Info" + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE, - consumes = MULTIPART_FORM_DATA_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE)), + requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(mediaType = MULTIPART_FORM_DATA_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.POST, consumes = MULTIPART_FORM_DATA_VALUE) @ResponseBody - public OtaPackageInfo saveOtaPackageData(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public OtaPackageInfo saveOtaPackageData(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable(OTA_PACKAGE_ID) String strOtaPackageId, - @ApiParam(value = "OTA Package checksum. For example, '0xd87f7e0c'") + @Parameter(description = "OTA Package checksum. For example, '0xd87f7e0c'") @RequestParam(required = false) String checksum, - @ApiParam(value = "OTA Package checksum algorithm.", allowableValues = OTA_PACKAGE_CHECKSUM_ALGORITHM_ALLOWABLE_VALUES) + @Parameter(description = "OTA Package checksum algorithm.", schema = @Schema(allowableValues = {"MD5", "SHA256", "SHA384", "SHA512", "CRC32", "MURMUR3_32", "MURMUR3_128"})) @RequestParam(CHECKSUM_ALGORITHM) String checksumAlgorithmStr, - @ApiParam(value = "OTA Package data.") + @Parameter(description = "OTA Package data.") @RequestPart MultipartFile file) throws ThingsboardException, IOException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); checkParameter(CHECKSUM_ALGORITHM, checksumAlgorithmStr); @@ -178,19 +177,19 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package Infos (getOtaPackages)", notes = "Returns a page of OTA Package Info objects owned by tenant. " + PAGE_DATA_PARAMETERS + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/otaPackages", method = RequestMethod.GET) @ResponseBody - public PageData getOtaPackages(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getOtaPackages(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "type", "title", "version", "tag", "url", "fileName", "dataSize", "checksum"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(otaPackageService.findTenantOtaPackagesByTenantId(getTenantId(), pageLink)); @@ -199,23 +198,23 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Get OTA Package Infos (getOtaPackages)", notes = "Returns a page of OTA Package Info objects owned by tenant. " + PAGE_DATA_PARAMETERS + OTA_PACKAGE_INFO_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/otaPackages/{deviceProfileId}/{type}", method = RequestMethod.GET) @ResponseBody - public PageData getOtaPackages(@ApiParam(value = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) + public PageData getOtaPackages(@Parameter(description = DEVICE_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("deviceProfileId") String strDeviceProfileId, - @ApiParam(value = "OTA Package type.", allowableValues = "FIRMWARE, SOFTWARE") + @Parameter(description = "OTA Package type.", schema = @Schema(allowableValues = "FIRMWARE, SOFTWARE")) @PathVariable("type") String strType, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = OTA_PACKAGE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = OTA_PACKAGE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "type", "title", "version", "tag", "url", "fileName", "dataSize", "checksum"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("deviceProfileId", strDeviceProfileId); checkParameter("type", strType); @@ -227,11 +226,11 @@ public class OtaPackageController extends BaseController { @ApiOperation(value = "Delete OTA Package (deleteOtaPackage)", notes = "Deletes the OTA Package. Referencing non-existing OTA Package Id will cause an error. " + "Can't delete the OTA Package if it is referenced by existing devices or device profile." + TENANT_AUTHORITY_PARAGRAPH, - produces = APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/otaPackage/{otaPackageId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteOtaPackage(@ApiParam(value = OTA_PACKAGE_ID_PARAM_DESCRIPTION) + public void deleteOtaPackage(@Parameter(description = OTA_PACKAGE_ID_PARAM_DESCRIPTION) @PathVariable("otaPackageId") String strOtaPackageId) throws ThingsboardException { checkParameter(OTA_PACKAGE_ID, strOtaPackageId); OtaPackageId otaPackageId = new OtaPackageId(toUUID(strOtaPackageId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/QueueController.java b/application/src/main/java/org/thingsboard/server/controller/QueueController.java index 0e79ae7955..774c991f94 100644 --- a/application/src/main/java/org/thingsboard/server/controller/QueueController.java +++ b/application/src/main/java/org/thingsboard/server/controller/QueueController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.msg.queue.ServiceType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.queue.TbQueueService; import org.thingsboard.server.service.security.permission.Operation; @@ -45,10 +46,7 @@ import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DE import static org.thingsboard.server.controller.ControllerConstants.QUEUE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.QUEUE_NAME_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SERVICE_TYPE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; @@ -69,17 +67,17 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues", params = {"serviceType", "pageSize", "page"}, method = RequestMethod.GET) @ResponseBody - public PageData getTenantQueuesByServiceType(@ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES, required = true) + public PageData getTenantQueuesByServiceType(@Parameter(description = QUEUE_SERVICE_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"TB-RULE-ENGINE", "TB-CORE", "TB-TRANSPORT", "JS-EXECUTOR"}, required = true)) @RequestParam String serviceType, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = QUEUE_QUEUE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = QUEUE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "topic"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("serviceType", serviceType); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -97,7 +95,7 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.GET) @ResponseBody - public Queue getQueueById(@ApiParam(value = QUEUE_ID_PARAM_DESCRIPTION) + public Queue getQueueById(@Parameter(description = QUEUE_ID_PARAM_DESCRIPTION) @PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); QueueId queueId = new QueueId(UUID.fromString(queueIdStr)); @@ -110,7 +108,7 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/queues/name/{queueName}", method = RequestMethod.GET) @ResponseBody - public Queue getQueueByName(@ApiParam(value = QUEUE_NAME_PARAM_DESCRIPTION) + public Queue getQueueByName(@Parameter(description = QUEUE_NAME_PARAM_DESCRIPTION) @PathVariable("queueName") String queueName) throws ThingsboardException { checkParameter("queueName", queueName); return checkNotNull(queueService.findQueueByTenantIdAndName(getTenantId(), queueName)); @@ -127,9 +125,9 @@ public class QueueController extends BaseController { @RequestMapping(value = "/queues", params = {"serviceType"}, method = RequestMethod.POST) @ResponseBody - public Queue saveQueue(@ApiParam(value = "A JSON value representing the queue.") + public Queue saveQueue(@Parameter(description = "A JSON value representing the queue.") @RequestBody Queue queue, - @ApiParam(value = QUEUE_SERVICE_TYPE_DESCRIPTION, allowableValues = QUEUE_SERVICE_TYPE_ALLOWABLE_VALUES, required = true) + @Parameter(description = QUEUE_SERVICE_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"TB-RULE-ENGINE", "TB-CORE", "TB-TRANSPORT", "JS-EXECUTOR"}, required = true)) @RequestParam String serviceType) throws ThingsboardException { checkParameter("serviceType", serviceType); queue.setTenantId(getCurrentUser().getTenantId()); @@ -152,7 +150,7 @@ public class QueueController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") @RequestMapping(value = "/queues/{queueId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteQueue(@ApiParam(value = QUEUE_ID_PARAM_DESCRIPTION) + public void deleteQueue(@Parameter(description = QUEUE_ID_PARAM_DESCRIPTION) @PathVariable("queueId") String queueIdStr) throws ThingsboardException { checkParameter("queueId", queueIdStr); QueueId queueId = new QueueId(toUUID(queueIdStr)); diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java b/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java index 509e91e546..fd207dcc34 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/RpcV1Controller.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -30,6 +29,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.UUID; @@ -48,9 +48,9 @@ public class RpcV1Controller extends AbstractRpcController { @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleOneWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT, HttpStatus.CONFLICT); } @@ -60,9 +60,9 @@ public class RpcV1Controller extends AbstractRpcController { @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleTwoWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.REQUEST_TIMEOUT, HttpStatus.CONFLICT); } diff --git a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java index c611cfda54..eb7481c6e2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java +++ b/application/src/main/java/org/thingsboard/server/controller/RpcV2Controller.java @@ -16,10 +16,11 @@ package org.thingsboard.server.controller; import com.google.common.util.concurrent.FutureCallback; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.annotation.Nullable; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -44,12 +45,12 @@ import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.exception.ToErrorResponseEntity; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rpc.RemoveRpcActorMsg; import org.thingsboard.server.service.security.permission.Operation; -import jakarta.annotation.Nullable; import java.util.UUID; import static org.thingsboard.server.common.data.DataConstants.RPC_DELETED; @@ -61,10 +62,7 @@ import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_ import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RPC_ID; import static org.thingsboard.server.controller.ControllerConstants.RPC_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RPC_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.RPC_STATUS_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RPC_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -117,36 +115,36 @@ public class RpcV2Controller extends AbstractRpcController { @ApiOperation(value = "Send one-way RPC request", notes = ONE_WAY_RPC_REQUEST_DESCRIPTION) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Persistent RPC request was saved to the database or lightweight RPC request was sent to the device."), - @ApiResponse(code = 400, message = "Invalid structure of the request."), - @ApiResponse(code = 401, message = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 504, message = "Timeout to process the RPC call. Most likely, device is offline."), + @ApiResponse(responseCode = "200", description = "Persistent RPC request was saved to the database or lightweight RPC request was sent to the device."), + @ApiResponse(responseCode = "400", description = "Invalid structure of the request."), + @ApiResponse(responseCode = "401", description = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "504", description = "Timeout to process the RPC call. Most likely, device is offline."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/oneway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleOneWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(true, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT, HttpStatus.GATEWAY_TIMEOUT); } @ApiOperation(value = "Send two-way RPC request", notes = TWO_WAY_RPC_REQUEST_DESCRIPTION) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Persistent RPC request was saved to the database or lightweight RPC response received."), - @ApiResponse(code = 400, message = "Invalid structure of the request."), - @ApiResponse(code = 401, message = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 504, message = "Timeout to process the RPC call. Most likely, device is offline."), + @ApiResponse(responseCode = "200", description = "Persistent RPC request was saved to the database or lightweight RPC response received."), + @ApiResponse(responseCode = "400", description = "Invalid structure of the request."), + @ApiResponse(responseCode = "401", description = "User is not authorized to send the RPC request. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "504", description = "Timeout to process the RPC call. Most likely, device is offline."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/twoway/{deviceId}", method = RequestMethod.POST) @ResponseBody public DeferredResult handleTwoWayDeviceRPCRequest( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) @PathVariable(DEVICE_ID) String deviceIdStr, - @ApiParam(value = "A JSON value representing the RPC request.") + @Parameter(description = "A JSON value representing the RPC request.") @RequestBody String requestBody) throws ThingsboardException { return handleDeviceRPCRequest(false, new DeviceId(UUID.fromString(deviceIdStr)), requestBody, HttpStatus.GATEWAY_TIMEOUT, HttpStatus.GATEWAY_TIMEOUT); } @@ -156,7 +154,7 @@ public class RpcV2Controller extends AbstractRpcController { @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.GET) @ResponseBody public Rpc getPersistedRpc( - @ApiParam(value = RPC_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = RPC_ID_PARAM_DESCRIPTION, required = true) @PathVariable(RPC_ID) String strRpc) throws ThingsboardException { checkParameter("RpcId", strRpc); RpcId rpcId = new RpcId(UUID.fromString(strRpc)); @@ -168,19 +166,19 @@ public class RpcV2Controller extends AbstractRpcController { @RequestMapping(value = "/persistent/device/{deviceId}", method = RequestMethod.GET) @ResponseBody public DeferredResult getPersistedRpcByDevice( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(DEVICE_ID) String strDeviceId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = "Status of the RPC", allowableValues = RPC_STATUS_ALLOWABLE_VALUES) + @Parameter(description = "Status of the RPC", schema = @Schema(allowableValues = {"QUEUED", "SENT", "DELIVERED", "SUCCESSFUL", "TIMEOUT", "EXPIRED", "FAILED"})) @RequestParam(required = false) RpcStatus rpcStatus, - @ApiParam(value = RPC_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RPC_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RPC_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "expirationTime", "request", "response"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("DeviceId", strDeviceId); if (rpcStatus != null && rpcStatus.equals(RpcStatus.DELETED)) { @@ -223,7 +221,7 @@ public class RpcV2Controller extends AbstractRpcController { @RequestMapping(value = "/persistent/{rpcId}", method = RequestMethod.DELETE) @ResponseBody public void deleteRpc( - @ApiParam(value = RPC_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = RPC_ID_PARAM_DESCRIPTION, required = true) @PathVariable(RPC_ID) String strRpc) throws ThingsboardException { checkParameter("RpcId", strRpc); RpcId rpcId = new RpcId(UUID.fromString(strRpc)); diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 50abb3de1d..64606968b5 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -20,8 +20,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -66,6 +68,7 @@ import org.thingsboard.server.common.data.script.ScriptLanguage; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgMetaData; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.event.EventService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.rule.TbRuleChainService; @@ -93,12 +96,9 @@ import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PA import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPES_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RULE_CHAIN_TYPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RULE_NODE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHORITY_PARAGRAPH; @@ -163,7 +163,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.GET) @ResponseBody public RuleChain getRuleChainById( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -177,7 +177,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/output/labels", method = RequestMethod.GET) @ResponseBody public Set getRuleChainOutputLabels( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -192,7 +192,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/output/labels/usage", method = RequestMethod.GET) @ResponseBody public List getRuleChainOutputLabelsUsage( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -206,7 +206,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/metadata", method = RequestMethod.GET) @ResponseBody public RuleChainMetaData getRuleChainMetaData( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -226,7 +226,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain", method = RequestMethod.POST) @ResponseBody public RuleChain saveRuleChain( - @ApiParam(value = "A JSON value representing the rule chain.") + @Parameter(description = "A JSON value representing the rule chain.") @RequestBody RuleChain ruleChain) throws Exception { ruleChain.setTenantId(getCurrentUser().getTenantId()); checkEntity(ruleChain.getId(), ruleChain, Resource.RULE_CHAIN); @@ -240,7 +240,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/device/default", method = RequestMethod.POST) @ResponseBody public RuleChain saveRuleChain( - @ApiParam(value = "A JSON value representing the request.") + @Parameter(description = "A JSON value representing the request.") @RequestBody DefaultRuleChainCreateRequest request) throws Exception { checkNotNull(request); checkParameter(request.getName(), "name"); @@ -253,7 +253,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}/root", method = RequestMethod.POST) @ResponseBody public RuleChain setRootRuleChain( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -267,9 +267,9 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/metadata", method = RequestMethod.POST) @ResponseBody public RuleChainMetaData saveRuleChainMetaData( - @ApiParam(value = "A JSON value representing the rule chain metadata.") + @Parameter(description = "A JSON value representing the rule chain metadata.") @RequestBody RuleChainMetaData ruleChainMetaData, - @ApiParam(value = "Update related rule nodes.") + @Parameter(description = "Update related rule nodes.") @RequestParam(value = "updateRelated", required = false, defaultValue = "true") boolean updateRelated ) throws Exception { TenantId tenantId = getTenantId(); @@ -291,17 +291,17 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChains", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getRuleChains( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RULE_CHAIN_TYPE_DESCRIPTION, allowableValues = RULE_CHAIN_TYPES_ALLOWABLE_VALUES) + @Parameter(description = RULE_CHAIN_TYPE_DESCRIPTION, schema = @Schema(allowableValues = {"CORE", "EDGE"})) @RequestParam(value = "type", required = false) String typeStr, - @ApiParam(value = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "root"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); @@ -319,7 +319,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteRuleChain( - @ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -334,7 +334,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleNode/{ruleNodeId}/debugIn", method = RequestMethod.GET) @ResponseBody public JsonNode getLatestRuleNodeDebugInput( - @ApiParam(value = RULE_NODE_ID_PARAM_DESCRIPTION) + @Parameter(description = RULE_NODE_ID_PARAM_DESCRIPTION) @PathVariable(RULE_NODE_ID) String strRuleNodeId) throws ThingsboardException { checkParameter(RULE_NODE_ID, strRuleNodeId); RuleNodeId ruleNodeId = new RuleNodeId(toUUID(strRuleNodeId)); @@ -369,9 +369,9 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChain/testScript", method = RequestMethod.POST) @ResponseBody public JsonNode testScript( - @ApiParam(value = "Script language: JS or TBEL") + @Parameter(description = "Script language: JS or TBEL") @RequestParam(required = false) ScriptLanguage scriptLang, - @ApiParam(value = "Test JS request. See API call description above.") + @Parameter(description = "Test JS request. See API call description above.") @RequestBody JsonNode inputParams) throws ThingsboardException, JsonProcessingException { String script = inputParams.get("script").asText(); String scriptType = inputParams.get("scriptType").asText(); @@ -443,7 +443,7 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChains/export", params = {"limit"}, method = RequestMethod.GET) @ResponseBody public RuleChainData exportRuleChains( - @ApiParam(value = "A limit of rule chains to export.", required = true) + @Parameter(description = "A limit of rule chains to export.", required = true) @RequestParam("limit") int limit) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); PageLink pageLink = new PageLink(limit); @@ -455,9 +455,9 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/ruleChains/import", method = RequestMethod.POST) @ResponseBody public List importRuleChains( - @ApiParam(value = "A JSON value representing the rule chains.") + @Parameter(description = "A JSON value representing the rule chains.") @RequestBody RuleChainData ruleChainData, - @ApiParam(value = "Enables overwrite for existing rule chains with the same name.") + @Parameter(description = "Enables overwrite for existing rule chains with the same name.") @RequestParam(required = false, defaultValue = "false") boolean overwrite) throws ThingsboardException { TenantId tenantId = getCurrentUser().getTenantId(); List importResults = ruleChainService.importTenantRuleChains(tenantId, ruleChainData, overwrite); @@ -507,7 +507,7 @@ public class RuleChainController extends BaseController { EDGE_ASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once rule chain will be delivered to edge service, it's going to start processing messages locally. " + "\n\nOnly rule chain with type 'EDGE' can be assigned to edge." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/ruleChain/{ruleChainId}", method = RequestMethod.POST) @ResponseBody @@ -530,7 +530,7 @@ public class RuleChainController extends BaseController { "Second, remote edge service will receive an 'unassign' command to remove rule chain " + EDGE_UNASSIGN_RECEIVE_STEP_DESCRIPTION + "Third, once 'unassign' command will be delivered to edge service, it's going to remove rule chain locally." + TENANT_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/edge/{edgeId}/ruleChain/{ruleChainId}", method = RequestMethod.DELETE) @ResponseBody @@ -552,17 +552,17 @@ public class RuleChainController extends BaseController { @RequestMapping(value = "/edge/{edgeId}/ruleChains", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getEdgeRuleChains( - @ApiParam(value = EDGE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = EDGE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(EDGE_ID) String strEdgeId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RULE_CHAIN_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RULE_CHAIN_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "root"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter(EDGE_ID, strEdgeId); TenantId tenantId = getCurrentUser().getTenantId(); @@ -578,7 +578,7 @@ public class RuleChainController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/{ruleChainId}/edgeTemplateRoot", method = RequestMethod.POST) @ResponseBody - public RuleChain setEdgeTemplateRootRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + public RuleChain setEdgeTemplateRootRuleChain(@Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -592,7 +592,7 @@ public class RuleChainController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/{ruleChainId}/autoAssignToEdge", method = RequestMethod.POST) @ResponseBody - public RuleChain setAutoAssignToEdgeRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + public RuleChain setAutoAssignToEdgeRuleChain(@Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); @@ -606,7 +606,7 @@ public class RuleChainController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/ruleChain/{ruleChainId}/autoAssignToEdge", method = RequestMethod.DELETE) @ResponseBody - public RuleChain unsetAutoAssignToEdgeRuleChain(@ApiParam(value = RULE_CHAIN_ID_PARAM_DESCRIPTION) + public RuleChain unsetAutoAssignToEdgeRuleChain(@Parameter(description = RULE_CHAIN_ID_PARAM_DESCRIPTION) @PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { checkParameter(RULE_CHAIN_ID, strRuleChainId); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java index 724cb59b73..07d8fa04d3 100644 --- a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java +++ b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java @@ -17,6 +17,8 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -39,14 +41,12 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; -import springfox.documentation.annotations.ApiIgnore; -import jakarta.annotation.PostConstruct; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; -@ApiIgnore +@Hidden @RestController @TbCoreComponent @RequestMapping("/api") diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index d94dc31fa1..387d31d40d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ByteArrayResource; @@ -39,6 +41,7 @@ import org.thingsboard.server.common.data.lwm2m.LwM2mObject; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.resource.TbResourceService; import org.thingsboard.server.service.security.permission.Operation; @@ -48,16 +51,13 @@ import java.util.Base64; import java.util.List; import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_INFO_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.RESOURCE_TEXT_SEARCH_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; @@ -79,7 +79,7 @@ public class TbResourceController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/{resourceId}/download", method = RequestMethod.GET) @ResponseBody - public ResponseEntity downloadResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public ResponseEntity downloadResource(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); @@ -97,11 +97,11 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get Resource Info (getResourceInfoById)", notes = "Fetch the Resource Info object based on the provided Resource Id. " + RESOURCE_INFO_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/info/{resourceId}", method = RequestMethod.GET) @ResponseBody - public TbResourceInfo getResourceInfoById(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public TbResourceInfo getResourceInfoById(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); @@ -111,11 +111,11 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get Resource (getResourceById)", notes = "Fetch the Resource object based on the provided Resource Id. " + RESOURCE_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.GET) @ResponseBody - public TbResource getResourceById(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public TbResource getResourceById(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable(RESOURCE_ID) String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); @@ -130,12 +130,11 @@ public class TbResourceController extends BaseController { "\n\nResource combination of the title with the key is unique in the scope of tenant. " + "Remove 'id', 'tenantId' from the request body example (below) to create new Resource entity." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json", - consumes = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource", method = RequestMethod.POST) @ResponseBody - public TbResource saveResource(@ApiParam(value = "A JSON value representing the Resource.") + public TbResource saveResource(@Parameter(description = "A JSON value representing the Resource.") @RequestBody TbResource resource) throws Exception { resource.setTenantId(getTenantId()); checkEntity(resource.getId(), resource, Resource.TB_RESOURCE); @@ -145,19 +144,19 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get Resource Infos (getResources)", notes = "Returns a page of Resource Info objects owned by tenant or sysadmin. " + PAGE_DATA_PARAMETERS + RESOURCE_INFO_DESCRIPTION + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource", method = RequestMethod.GET) @ResponseBody - public PageData getResources(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public PageData getResources(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RESOURCE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = RESOURCE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "resourceType", "tenantId"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { @@ -170,19 +169,19 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get LwM2M Objects (getLwm2mListObjectsPage)", notes = "Returns a page of LwM2M objects parsed from Resources with type 'LWM2M_MODEL' owned by tenant or sysadmin. " + PAGE_DATA_PARAMETERS + LWM2M_OBJECT_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/resource/lwm2m/page", method = RequestMethod.GET) @ResponseBody - public List getLwm2mListObjectsPage(@ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + public List getLwm2mListObjectsPage(@Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = RESOURCE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = RESOURCE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"id", "name"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = new PageLink(pageSize, page, textSearch); return checkNotNull(resourceService.findLwM2mObjectPage(getTenantId(), sortProperty, sortOrder, pageLink)); @@ -191,15 +190,15 @@ public class TbResourceController extends BaseController { @ApiOperation(value = "Get LwM2M Objects (getLwm2mListObjects)", notes = "Returns a page of LwM2M objects parsed from Resources with type 'LWM2M_MODEL' owned by tenant or sysadmin. " + "You can specify parameters to filter the results. " + LWM2M_OBJECT_DESCRIPTION + TENANT_AUTHORITY_PARAGRAPH, - produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/resource/lwm2m", method = RequestMethod.GET) @ResponseBody - public List getLwm2mListObjects(@ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES, required = true) + public List getLwm2mListObjects(@Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"}, required = true)) @RequestParam String sortOrder, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = LWM2M_OBJECT_SORT_PROPERTY_ALLOWABLE_VALUES, required = true) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"id", "name"}, required = true)) @RequestParam String sortProperty, - @ApiParam(value = "LwM2M Object ids.", required = true) + @Parameter(description = "LwM2M Object ids.", required = true) @RequestParam(required = false) String[] objectIds) throws ThingsboardException { return checkNotNull(resourceService.findLwM2mObject(getTenantId(), sortOrder, sortProperty, objectIds)); } @@ -209,7 +208,7 @@ public class TbResourceController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/resource/{resourceId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteResource(@ApiParam(value = RESOURCE_ID_PARAM_DESCRIPTION) + public void deleteResource(@Parameter(description = RESOURCE_ID_PARAM_DESCRIPTION) @PathVariable("resourceId") String strResourceId) throws ThingsboardException { checkParameter(RESOURCE_ID, strResourceId); TbResourceId resourceId = new TbResourceId(toUUID(strResourceId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 262cd38629..1e72d70cbb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -24,10 +24,14 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.annotations.ApiResponse; -import io.swagger.annotations.ApiResponses; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.annotation.Nullable; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -46,6 +50,7 @@ import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; +import org.thingsboard.server.common.adaptor.JsonConverter; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; @@ -74,7 +79,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; -import org.thingsboard.server.common.adaptor.JsonConverter; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.timeseries.TimeseriesService; import org.thingsboard.server.exception.InvalidParametersException; import org.thingsboard.server.exception.UncheckedApiException; @@ -85,9 +90,6 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.telemetry.AttributeData; import org.thingsboard.server.service.telemetry.TsData; -import jakarta.annotation.Nullable; -import jakarta.annotation.PostConstruct; -import jakarta.annotation.PreDestroy; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; @@ -100,8 +102,6 @@ import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_JSON_REQUEST_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_KEYS_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SCOPE_ALLOWED_VALUES; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTES_SCOPE_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.ATTRIBUTE_DATA_EXAMPLE; import static org.thingsboard.server.controller.ControllerConstants.DEVICE_ID; @@ -126,7 +126,6 @@ import static org.thingsboard.server.controller.ControllerConstants.SAVE_ENTITY_ import static org.thingsboard.server.controller.ControllerConstants.SAVE_ENTITY_TIMESERIES_STATUS_OK; import static org.thingsboard.server.controller.ControllerConstants.SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED; import static org.thingsboard.server.controller.ControllerConstants.SAVE_TIMESERIES_REQUEST_PAYLOAD; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.STRICT_DATA_TYPES_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TELEMETRY_JSON_REQUEST_DESCRIPTION; @@ -176,13 +175,13 @@ public class TelemetryController extends BaseController { "\n * CLIENT_SCOPE - supported for devices;" + "\n * SHARED_SCOPE - supported for devices. " + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributeKeys( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, this::getAttributeKeysCallback); } @@ -192,16 +191,16 @@ public class TelemetryController extends BaseController { "\n * CLIENT_SCOPE - supported for devices;" + "\n * SHARED_SCOPE - supported for devices. " + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/keys/attributes/{scope}", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributeKeysByScope( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope") String scope) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, - (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); + (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); } @ApiOperation(value = "Get attributes (getAttributes)", @@ -211,17 +210,17 @@ public class TelemetryController extends BaseController { + ATTRIBUTE_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/attributes", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributes( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { - SecurityUser user = getCurrentUser(); + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { + SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, - (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); + (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); } @@ -234,32 +233,32 @@ public class TelemetryController extends BaseController { + ATTRIBUTE_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/attributes/{scope}", method = RequestMethod.GET) @ResponseBody public DeferredResult getAttributesByScope( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope") String scope, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, - (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); + (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); } @ApiOperation(value = "Get time-series keys (getTimeseriesKeys)", notes = "Returns a set of unique time-series key names for the selected entity. " + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/keys/timeseries", method = RequestMethod.GET) @ResponseBody public DeferredResult getTimeseriesKeys( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, - (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result), MoreExecutors.directExecutor())); + (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result), MoreExecutors.directExecutor())); } @ApiOperation(value = "Get latest time-series value (getLatestTimeseries)", @@ -274,15 +273,15 @@ public class TelemetryController extends BaseController { + LATEST_TS_STRICT_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET) @ResponseBody public DeferredResult getLatestTimeseries( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr, - @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION) + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr, + @Parameter(description = STRICT_DATA_TYPES_DESCRIPTION) @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, @@ -298,30 +297,30 @@ public class TelemetryController extends BaseController { + TS_STRICT_DATA_EXAMPLE + MARKDOWN_CODE_BLOCK_END + "\n\n" + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/values/timeseries", method = RequestMethod.GET, params = {"keys", "startTs", "endTs"}) @ResponseBody public DeferredResult getTimeseries( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_KEYS_BASE_DESCRIPTION, required = true) @RequestParam(name = "keys") String keys, - @ApiParam(value = "A long value representing the start timestamp of the time range in milliseconds, UTC.") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_KEYS_BASE_DESCRIPTION, required = true) @RequestParam(name = "keys") String keys, + @Parameter(description = "A long value representing the start timestamp of the time range in milliseconds, UTC.") @RequestParam(name = "startTs") Long startTs, - @ApiParam(value = "A long value representing the end timestamp of the time range in milliseconds, UTC.") + @Parameter(description = "A long value representing the end timestamp of the time range in milliseconds, UTC.") @RequestParam(name = "endTs") Long endTs, - @ApiParam(value = "A long value representing the aggregation interval range in milliseconds.") + @Parameter(description = "A long value representing the aggregation interval range in milliseconds.") @RequestParam(name = "interval", defaultValue = "0") Long interval, - @ApiParam(value = "An integer value that represents a max number of timeseries data points to fetch." + - " This parameter is used only in the case if 'agg' parameter is set to 'NONE'.", defaultValue = "100") + @Parameter(description = "An integer value that represents a max number of timeseries data points to fetch." + + " This parameter is used only in the case if 'agg' parameter is set to 'NONE'.", schema = @Schema(defaultValue = "100")) @RequestParam(name = "limit", defaultValue = "100") Integer limit, - @ApiParam(value = "A string value representing the aggregation function. " + + @Parameter(description = "A string value representing the aggregation function. " + "If the interval is not specified, 'agg' parameter will use 'NONE' value.", - allowableValues = "MIN, MAX, AVG, SUM, COUNT, NONE") + schema = @Schema(allowableValues = "MIN, MAX, AVG, SUM, COUNT, NONE")) @RequestParam(name = "agg", defaultValue = "NONE") String aggStr, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(name = "orderBy", defaultValue = "DESC") String orderBy, - @ApiParam(value = STRICT_DATA_TYPES_DESCRIPTION) + @Parameter(description = STRICT_DATA_TYPES_DESCRIPTION) @RequestParam(name = "useStrictDataTypes", required = false, defaultValue = "false") Boolean useStrictDataTypes) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_TELEMETRY, entityType, entityIdStr, (result, tenantId, entityId) -> { @@ -338,23 +337,23 @@ public class TelemetryController extends BaseController { notes = "Creates or updates the device attributes based on device id and specified attribute scope. " + SAVE_ATTRIBUTES_REQUEST_PAYLOAD + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + + @ApiResponse(responseCode = "200", description = SAVE_ATTIRIBUTES_STATUS_OK + "Platform creates an audit log event about device attributes updates with action type 'ATTRIBUTES_UPDATED', " + "and also sends event msg to the rule engine with msg type 'ATTRIBUTES_UPDATED'."), - @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), - @ApiResponse(code = 401, message = "User is not authorized to save device attributes for selected device. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), + @ApiResponse(responseCode = "401", description = "User is not authorized to save device attributes for selected device. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about device attributes updates with action type 'ATTRIBUTES_UPDATED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveDeviceAttributes( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("deviceId") String deviceIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("deviceId") String deviceIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope") String scope, + @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); return saveAttributes(getTenantId(), entityId, scope, request); } @@ -364,21 +363,21 @@ public class TelemetryController extends BaseController { ENTITY_SAVE_ATTRIBUTE_SCOPES + SAVE_ATTRIBUTES_REQUEST_PAYLOAD + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), - @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), + @ApiResponse(responseCode = "400", description = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityAttributesV1( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"})) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveAttributes(getTenantId(), entityId, scope, request); } @@ -388,21 +387,21 @@ public class TelemetryController extends BaseController { ENTITY_SAVE_ATTRIBUTE_SCOPES + SAVE_ATTRIBUTES_REQUEST_PAYLOAD + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), - @ApiResponse(code = 400, message = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ATTIRIBUTES_STATUS_OK + SAVE_ENTITY_ATTRIBUTES_STATUS_OK), + @ApiResponse(responseCode = "400", description = SAVE_ATTIRIBUTES_STATUS_BAD_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_ATTRIBUTES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_ATTRIBUTES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/attributes/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityAttributesV2( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SAVE_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveAttributes(getTenantId(), entityId, scope, request); } @@ -413,21 +412,21 @@ public class TelemetryController extends BaseController { SAVE_TIMESERIES_REQUEST_PAYLOAD + "\n\n The scope parameter is not used in the API call implementation but should be specified whatever value because it is used as a path variable. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ENTITY_TIMESERIES_STATUS_OK), - @ApiResponse(code = 400, message = INVALID_STRUCTURE_OF_THE_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ENTITY_TIMESERIES_STATUS_OK), + @ApiResponse(responseCode = "400", description = INVALID_STRUCTURE_OF_THE_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityTelemetry( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_SCOPE_DESCRIPTION, required = true, allowableValues = "ANY") @PathVariable("scope") String scope, - @ApiParam(value = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody String requestBody) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")String scope, + @Parameter(description = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody String requestBody) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveTelemetry(getTenantId(), entityId, requestBody, 0L); } @@ -438,22 +437,22 @@ public class TelemetryController extends BaseController { "\n\n The scope parameter is not used in the API call implementation but should be specified whatever value because it is used as a path variable. " + "\n\nThe ttl parameter takes affect only in case of Cassandra DB." + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = SAVE_ENTITY_TIMESERIES_STATUS_OK), - @ApiResponse(code = 400, message = INVALID_STRUCTURE_OF_THE_REQUEST), - @ApiResponse(code = 401, message = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), - @ApiResponse(code = 500, message = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), + @ApiResponse(responseCode = "200", description = SAVE_ENTITY_TIMESERIES_STATUS_OK), + @ApiResponse(responseCode = "400", description = INVALID_STRUCTURE_OF_THE_REQUEST), + @ApiResponse(responseCode = "401", description = SAVE_ENTITY_TIMESERIES_STATUS_UNAUTHORIZED), + @ApiResponse(responseCode = "500", description = SAVE_ENTITY_TIMESERIES_STATUS_INTERNAL_SERVER_ERROR), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/timeseries/{scope}/{ttl}", method = RequestMethod.POST) @ResponseBody public DeferredResult saveEntityTelemetryWithTTL( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_SCOPE_DESCRIPTION, required = true, allowableValues = "ANY") @PathVariable("scope") String scope, - @ApiParam(value = "A long value representing TTL (Time to Live) parameter.", required = true) @PathVariable("ttl") Long ttl, - @ApiParam(value = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody String requestBody) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")String scope, + @Parameter(description = "A long value representing TTL (Time to Live) parameter.", required = true)@PathVariable("ttl")Long ttl, + @Parameter(description = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody String requestBody) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveTelemetry(getTenantId(), entityId, requestBody, ttl); } @@ -464,29 +463,29 @@ public class TelemetryController extends BaseController { " Use 'startTs' and 'endTs' to specify time-range instead. " + " Use 'rewriteLatestIfDeleted' to rewrite latest value (stored in separate table for performance) after deletion of the time range. " + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Timeseries for the selected keys in the request was removed. " + + @ApiResponse(responseCode = "200", description = "Timeseries for the selected keys in the request was removed. " + "Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED'."), - @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys list is empty or start and end timestamp values is empty when deleteAllDataForKeys is set to false."), - @ApiResponse(code = 401, message = "User is not authorized to delete entity timeseries for selected entity. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = "Platform returns a bad request in case if keys list is empty or start and end timestamp values is empty when deleteAllDataForKeys is set to false."), + @ApiResponse(responseCode = "401", description = "User is not authorized to delete entity timeseries for selected entity. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about entity timeseries removal with action type 'TIMESERIES_DELETED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/timeseries/delete", method = RequestMethod.DELETE) @ResponseBody public DeferredResult deleteEntityTimeseries( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = TELEMETRY_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr, - @ApiParam(value = "A boolean value to specify if should be deleted all data for selected keys or only data that are in the selected time range.") + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = TELEMETRY_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr, + @Parameter(description = "A boolean value to specify if should be deleted all data for selected keys or only data that are in the selected time range.") @RequestParam(name = "deleteAllDataForKeys", defaultValue = "false") boolean deleteAllDataForKeys, - @ApiParam(value = "A long value representing the start timestamp of removal time range in milliseconds.") + @Parameter(description = "A long value representing the start timestamp of removal time range in milliseconds.") @RequestParam(name = "startTs", required = false) Long startTs, - @ApiParam(value = "A long value representing the end timestamp of removal time range in milliseconds.") + @Parameter(description = "A long value representing the end timestamp of removal time range in milliseconds.") @RequestParam(name = "endTs", required = false) Long endTs, - @ApiParam(value = "If the parameter is set to true, the latest telemetry will be rewritten in case that current latest value was removed, otherwise, in case that parameter is set to false the new latest value will not set.") + @Parameter(description = "If the parameter is set to true, the latest telemetry will be rewritten in case that current latest value was removed, otherwise, in case that parameter is set to false the new latest value will not set.") @RequestParam(name = "rewriteLatestIfDeleted", defaultValue = "false") boolean rewriteLatestIfDeleted) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return deleteTimeseries(entityId, keysStr, deleteAllDataForKeys, startTs, endTs, rewriteLatestIfDeleted); @@ -538,22 +537,22 @@ public class TelemetryController extends BaseController { @ApiOperation(value = "Delete device attributes (deleteDeviceAttributes)", notes = "Delete device attributes using provided Device Id, scope and a list of keys. " + "Referencing a non-existing Device Id will cause an error" + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Device attributes was removed for the selected keys in the request. " + + @ApiResponse(responseCode = "200", description = "Device attributes was removed for the selected keys in the request. " + "Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED'."), - @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys or scope are not specified."), - @ApiResponse(code = 401, message = "User is not authorized to delete device attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = "Platform returns a bad request in case if keys or scope are not specified."), + @ApiResponse(responseCode = "401", description = "User is not authorized to delete device attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about device attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{deviceId}/{scope}", method = RequestMethod.DELETE) @ResponseBody public DeferredResult deleteDeviceAttributes( - @ApiParam(value = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(DEVICE_ID) String deviceIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES, required = true) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr) throws ThingsboardException { + @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(DEVICE_ID) String deviceIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION, required = true)@RequestParam(name = "keys")String keysStr) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); return deleteAttributes(entityId, scope, keysStr); } @@ -561,23 +560,23 @@ public class TelemetryController extends BaseController { @ApiOperation(value = "Delete entity attributes (deleteEntityAttributes)", notes = "Delete entity attributes using provided Entity Id, scope and a list of keys. " + INVALID_ENTITY_ID_OR_ENTITY_TYPE_DESCRIPTION + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @ApiResponses(value = { - @ApiResponse(code = 200, message = "Entity attributes was removed for the selected keys in the request. " + + @ApiResponse(responseCode = "200", description = "Entity attributes was removed for the selected keys in the request. " + "Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED'."), - @ApiResponse(code = 400, message = "Platform returns a bad request in case if keys or scope are not specified."), - @ApiResponse(code = 401, message = "User is not authorized to delete entity attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), - @ApiResponse(code = 500, message = "The exception was thrown during processing the request. " + + @ApiResponse(responseCode = "400", description = "Platform returns a bad request in case if keys or scope are not specified."), + @ApiResponse(responseCode = "401", description = "User is not authorized to delete entity attributes for selected entity. Most likely, User belongs to different Customer or Tenant."), + @ApiResponse(responseCode = "500", description = "The exception was thrown during processing the request. " + "Platform creates an audit log event about entity attributes removal with action type 'ATTRIBUTES_DELETED' that includes an error stacktrace."), }) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{entityType}/{entityId}/{scope}", method = RequestMethod.DELETE) @ResponseBody public DeferredResult deleteEntityAttributes( - @ApiParam(value = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, defaultValue = "DEVICE") @PathVariable("entityType") String entityType, - @ApiParam(value = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @ApiParam(value = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, allowableValues = ATTRIBUTES_SCOPE_ALLOWED_VALUES) @PathVariable("scope") String scope, - @ApiParam(value = ATTRIBUTES_KEYS_DESCRIPTION, required = true) @RequestParam(name = "keys") String keysStr) throws ThingsboardException { + @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, + @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION, required = true)@RequestParam(name = "keys")String keysStr) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return deleteAttributes(entityId, scope, keysStr); } diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantController.java b/application/src/main/java/org/thingsboard/server/controller/TenantController.java index 6574969e15..6fb58207bf 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantController.java @@ -16,8 +16,8 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.tenant.TbTenantService; @@ -46,15 +47,12 @@ import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOA import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.TENANT_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @@ -76,7 +74,7 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenant/{tenantId}", method = RequestMethod.GET) @ResponseBody public Tenant getTenantById( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId) throws ThingsboardException { checkParameter(TENANT_ID, strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -94,7 +92,7 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenant/info/{tenantId}", method = RequestMethod.GET) @ResponseBody public TenantInfo getTenantInfoById( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId) throws ThingsboardException { checkParameter(TENANT_ID, strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -112,7 +110,7 @@ public class TenantController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenant", method = RequestMethod.POST) @ResponseBody - public Tenant saveTenant(@ApiParam(value = "A JSON value representing the tenant.") + public Tenant saveTenant(@Parameter(description = "A JSON value representing the tenant.") @RequestBody Tenant tenant) throws Exception { checkEntity(tenant.getId(), tenant, Resource.TENANT); return tbTenantService.save(tenant); @@ -123,7 +121,7 @@ public class TenantController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenant/{tenantId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteTenant(@ApiParam(value = TENANT_ID_PARAM_DESCRIPTION) + public void deleteTenant(@Parameter(description = TENANT_ID_PARAM_DESCRIPTION) @PathVariable(TENANT_ID) String strTenantId) throws Exception { checkParameter(TENANT_ID, strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -136,15 +134,15 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenants", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenants( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "email", "country", "state", "city", "address", "address2", "zip", "phone", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(tenantService.findTenants(pageLink)); @@ -156,15 +154,15 @@ public class TenantController extends BaseController { @RequestMapping(value = "/tenantInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "tenantProfileName", "title", "email", "country", "state", "city", "address", "address2", "zip", "phone", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder ) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); diff --git a/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java b/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java index a7fe973ec0..8f667ec184 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TenantProfileController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.tenant.profile.TbTenantProfileService; import org.thingsboard.server.service.security.permission.Operation; @@ -50,13 +51,10 @@ import static org.thingsboard.server.controller.ControllerConstants.MARKDOWN_COD import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES; -import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @@ -77,7 +75,7 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfile/{tenantProfileId}", method = RequestMethod.GET) @ResponseBody public TenantProfile getTenantProfileById( - @ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -90,7 +88,7 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfileInfo/{tenantProfileId}", method = RequestMethod.GET) @ResponseBody public EntityInfo getTenantProfileInfoById( - @ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -162,7 +160,7 @@ public class TenantProfileController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenantProfile", method = RequestMethod.POST) @ResponseBody - public TenantProfile saveTenantProfile(@ApiParam(value = "A JSON value representing the tenant profile.") + public TenantProfile saveTenantProfile(@Parameter(description = "A JSON value representing the tenant profile.") @RequestBody TenantProfile tenantProfile) throws ThingsboardException { TenantProfile oldProfile; if (tenantProfile.getId() == null) { @@ -180,7 +178,7 @@ public class TenantProfileController extends BaseController { @PreAuthorize("hasAuthority('SYS_ADMIN')") @RequestMapping(value = "/tenantProfile/{tenantProfileId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteTenantProfile(@ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + public void deleteTenantProfile(@Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -194,7 +192,7 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfile/{tenantProfileId}/default", method = RequestMethod.POST) @ResponseBody public TenantProfile setDefaultTenantProfile( - @ApiParam(value = TENANT_PROFILE_ID_PARAM_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_ID_PARAM_DESCRIPTION) @PathVariable("tenantProfileId") String strTenantProfileId) throws ThingsboardException { checkParameter("tenantProfileId", strTenantProfileId); TenantProfileId tenantProfileId = new TenantProfileId(toUUID(strTenantProfileId)); @@ -208,15 +206,15 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfiles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantProfiles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_PROFILE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "description", "isDefault"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(tenantProfileService.findTenantProfiles(getTenantId(), pageLink)); @@ -228,15 +226,15 @@ public class TenantProfileController extends BaseController { @RequestMapping(value = "/tenantProfileInfos", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantProfileInfos( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = TENANT_PROFILE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = TENANT_PROFILE_INFO_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"id", "name"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return checkNotNull(tenantProfileService.findTenantProfileInfos(getTenantId(), pageLink)); diff --git a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java index a809f5280c..f674ed0ca8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthConfigController.java @@ -15,8 +15,9 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; import lombok.Data; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; @@ -34,12 +35,12 @@ import org.thingsboard.server.common.data.security.model.mfa.account.AccountTwoF import org.thingsboard.server.common.data.security.model.mfa.account.TwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService; import org.thingsboard.server.service.security.auth.mfa.config.TwoFaConfigManager; import org.thingsboard.server.service.security.model.SecurityUser; -import jakarta.validation.Valid; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -99,7 +100,7 @@ public class TwoFactorAuthConfigController extends BaseController { ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER) @PostMapping("/account/config/generate") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - public TwoFaAccountConfig generateTwoFaAccountConfig(@ApiParam(value = "2FA provider type to generate new account config for", defaultValue = "TOTP", required = true) + public TwoFaAccountConfig generateTwoFaAccountConfig(@Parameter(description = "2FA provider type to generate new account config for", schema = @Schema(defaultValue = "TOTP", required = true)) @RequestParam TwoFaProviderType providerType) throws Exception { SecurityUser user = getCurrentUser(); return twoFactorAuthService.generateNewAccountConfig(user, providerType); @@ -258,7 +259,7 @@ public class TwoFactorAuthConfigController extends BaseController { ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PostMapping("/settings") @PreAuthorize("hasAnyAuthority('SYS_ADMIN')") - public PlatformTwoFaSettings savePlatformTwoFaSettings(@ApiParam(value = "Settings value", required = true) + public PlatformTwoFaSettings savePlatformTwoFaSettings(@Parameter(description = "Settings value", required = true) @RequestBody PlatformTwoFaSettings twoFaSettings) throws ThingsboardException { return twoFaConfigManager.savePlatformTwoFaSettings(getTenantId(), twoFaSettings); } diff --git a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java index ee1db6868a..1478e21c76 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TwoFactorAuthController.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; +import jakarta.servlet.http.HttpServletRequest; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.security.model.mfa.PlatformTwoFaSettin import org.thingsboard.server.common.data.security.model.mfa.account.EmailTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.account.SmsTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.mfa.TwoFactorAuthService; @@ -44,7 +45,6 @@ import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; import org.thingsboard.server.service.security.system.SystemSecurityService; -import jakarta.servlet.http.HttpServletRequest; import java.util.Collections; import java.util.List; import java.util.Optional; diff --git a/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java b/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java index a40d3b85af..11bd0e8364 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UiSettingsController.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestMapping; @@ -23,6 +22,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; @RestController diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 5bf6a86307..b05d5feb83 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -17,8 +17,9 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -64,6 +65,7 @@ import org.thingsboard.server.common.data.settings.UserDashboardAction; import org.thingsboard.server.common.data.settings.UserDashboardsInfo; import org.thingsboard.server.common.data.settings.UserSettings; import org.thingsboard.server.common.data.settings.UserSettingsType; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.user.TbUserService; @@ -75,7 +77,6 @@ import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; import org.thingsboard.server.service.security.system.SystemSecurityService; -import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -92,7 +93,6 @@ import static org.thingsboard.server.controller.ControllerConstants.HOME_DASHBOA import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; @@ -102,7 +102,6 @@ import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID; import static org.thingsboard.server.controller.ControllerConstants.TENANT_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.USER_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.USER_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.USER_TEXT_SEARCH_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; @@ -141,7 +140,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}", method = RequestMethod.GET) @ResponseBody public User getUserById( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); UserId userId = new UserId(toUUID(strUserId)); @@ -177,7 +176,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}/token", method = RequestMethod.GET) @ResponseBody public JwtPair getUserToken( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); if (!userTokenAccessEnabled) { @@ -205,9 +204,9 @@ public class UserController extends BaseController { @RequestMapping(value = "/user", method = RequestMethod.POST) @ResponseBody public User saveUser( - @ApiParam(value = "A JSON value representing the User.", required = true) + @Parameter(description = "A JSON value representing the User.", required = true) @RequestBody User user, - @ApiParam(value = "Send activation email (or use activation link)", defaultValue = "true") + @Parameter(description = "Send activation email (or use activation link)" , schema = @Schema(defaultValue = "true")) @RequestParam(required = false, defaultValue = "true") boolean sendActivationMail, HttpServletRequest request) throws ThingsboardException { if (!Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { user.setTenantId(getCurrentUser().getTenantId()); @@ -222,7 +221,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/sendActivationMail", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public void sendActivationEmail( - @ApiParam(value = "Email of the user", required = true) + @Parameter(description = "Email of the user", required = true) @RequestParam(value = "email") String email, HttpServletRequest request) throws ThingsboardException { User user = checkNotNull(userService.findUserByEmail(getCurrentUser().getTenantId(), email)); @@ -248,7 +247,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}/activationLink", method = RequestMethod.GET, produces = "text/plain") @ResponseBody public String getActivationLink( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId, HttpServletRequest request) throws ThingsboardException { checkParameter(USER_ID, strUserId); @@ -273,7 +272,7 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteUser( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId) throws ThingsboardException { checkParameter(USER_ID, strUserId); UserId userId = new UserId(toUUID(strUserId)); @@ -291,15 +290,15 @@ public class UserController extends BaseController { @RequestMapping(value = "/users", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getUsers( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); SecurityUser currentUser = getCurrentUser(); @@ -317,15 +316,15 @@ public class UserController extends BaseController { @RequestMapping(value = "/users/info", method = RequestMethod.GET) @ResponseBody public PageData findUsersByQuery( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { SecurityUser securityUser = getCurrentUser(); @@ -354,17 +353,17 @@ public class UserController extends BaseController { @RequestMapping(value = "/tenant/{tenantId}/users", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getTenantAdmins( - @ApiParam(value = TENANT_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = TENANT_ID_PARAM_DESCRIPTION, required = true) @PathVariable(TENANT_ID) String strTenantId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("tenantId", strTenantId); TenantId tenantId = TenantId.fromUUID(toUUID(strTenantId)); @@ -378,17 +377,17 @@ public class UserController extends BaseController { @RequestMapping(value = "/customer/{customerId}/users", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getCustomerUsers( - @ApiParam(value = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true) @PathVariable(CUSTOMER_ID) String strCustomerId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { checkParameter("customerId", strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); @@ -404,9 +403,9 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}/userCredentialsEnabled", method = RequestMethod.POST) @ResponseBody public void setUserCredentialsEnabled( - @ApiParam(value = USER_ID_PARAM_DESCRIPTION) + @Parameter(description = USER_ID_PARAM_DESCRIPTION) @PathVariable(USER_ID) String strUserId, - @ApiParam(value = "Enable (\"true\") or disable (\"false\") the credentials.", defaultValue = "true") + @Parameter(description = "Enable (\"true\") or disable (\"false\") the credentials." , schema = @Schema(defaultValue = "true")) @RequestParam(required = false, defaultValue = "true") boolean userCredentialsEnabled) throws ThingsboardException { checkParameter(USER_ID, strUserId); UserId userId = new UserId(toUUID(strUserId)); @@ -427,17 +426,17 @@ public class UserController extends BaseController { @RequestMapping(value = "/users/assign/{alarmId}", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getUsersForAssign( - @ApiParam(value = ALARM_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = ALARM_ID_PARAM_DESCRIPTION, required = true) @PathVariable("alarmId") String strAlarmId, - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = USER_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "firstName", "lastName", "email"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { try { checkParameter("alarmId", strAlarmId); @@ -508,7 +507,7 @@ public class UserController extends BaseController { "Example: to delete B and C element in { \"A\": {\"B\": 5}, \"C\": 15} send A.B,C in jsonPaths request parameter") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/user/settings/{paths}", method = RequestMethod.DELETE) - public void deleteUserSettings(@ApiParam(value = PATHS) + public void deleteUserSettings(@Parameter(description = PATHS) @PathVariable(PATHS) String paths) throws ThingsboardException { checkParameter(USER_ID, paths); @@ -522,7 +521,7 @@ public class UserController extends BaseController { "{A:5, B:{C:10, D:30}}. The same could be achieved by putting {B.D:30}") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PutMapping(value = "/user/settings/{type}") - public void putUserSettings(@ApiParam(value = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") + public void putUserSettings(@Parameter(description = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") @PathVariable("type") String strType, @RequestBody JsonNode settings) throws ThingsboardException { SecurityUser currentUser = getCurrentUser(); UserSettingsType type = checkEnumParameter("Settings type", strType, UserSettingsType::valueOf); @@ -534,7 +533,7 @@ public class UserController extends BaseController { notes = "Fetch the User settings based on authorized user. ") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @GetMapping(value = "/user/settings/{type}") - public JsonNode getUserSettings(@ApiParam(value = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") + public JsonNode getUserSettings(@Parameter(description = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") @PathVariable("type") String strType) throws ThingsboardException { SecurityUser currentUser = getCurrentUser(); UserSettingsType type = checkEnumParameter("Settings type", strType, UserSettingsType::valueOf); @@ -548,9 +547,9 @@ public class UserController extends BaseController { "Example: to delete B and C element in { \"A\": {\"B\": 5}, \"C\": 15} send A.B,C in jsonPaths request parameter") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/user/settings/{type}/{paths}", method = RequestMethod.DELETE) - public void deleteUserSettings(@ApiParam(value = PATHS) + public void deleteUserSettings(@Parameter(description = PATHS) @PathVariable(PATHS) String paths, - @ApiParam(value = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") + @Parameter(description = "Settings type, case insensitive, one of: \"general\", \"quick_links\", \"doc_links\" or \"dashboards\".") @PathVariable("type") String strType) throws ThingsboardException { checkParameter(USER_ID, paths); UserSettingsType type = checkEnumParameter("Settings type", strType, UserSettingsType::valueOf); @@ -574,9 +573,9 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/dashboards/{dashboardId}/{action}", method = RequestMethod.GET) @ResponseBody public UserDashboardsInfo reportUserDashboardAction( - @ApiParam(value = DASHBOARD_ID_PARAM_DESCRIPTION) + @Parameter(description = DASHBOARD_ID_PARAM_DESCRIPTION) @PathVariable(DashboardController.DASHBOARD_ID) String strDashboardId, - @ApiParam(value = "Dashboard action, one of: \"visit\", \"star\" or \"unstar\".") + @Parameter(description = "Dashboard action, one of: \"visit\", \"star\" or \"unstar\".") @PathVariable("action") String strAction) throws ThingsboardException { checkParameter(DashboardController.DASHBOARD_ID, strDashboardId); checkParameter("action", strAction); diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java index d1ecd0441a..9f71890e70 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -37,6 +36,7 @@ import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeInfo; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; @@ -67,7 +67,7 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType/{widgetTypeId}", method = RequestMethod.GET) @ResponseBody public WidgetTypeDetails getWidgetTypeById( - @ApiParam(value = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetTypeId") String strWidgetTypeId) throws ThingsboardException { checkParameter("widgetTypeId", strWidgetTypeId); WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); @@ -88,7 +88,7 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType", method = RequestMethod.POST) @ResponseBody public WidgetTypeDetails saveWidgetType( - @ApiParam(value = "A JSON value representing the Widget Type Details.", required = true) + @Parameter(description = "A JSON value representing the Widget Type Details.", required = true) @RequestBody WidgetTypeDetails widgetTypeDetails) throws Exception { var currentUser = getCurrentUser(); if (Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { @@ -119,7 +119,7 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType/{widgetTypeId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteWidgetType( - @ApiParam(value = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_TYPE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetTypeId") String strWidgetTypeId) throws Exception { checkParameter("widgetTypeId", strWidgetTypeId); var currentUser = getCurrentUser(); @@ -143,9 +143,9 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetTypes", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET) @ResponseBody public List getBundleWidgetTypes( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias) throws ThingsboardException { TenantId tenantId; if (isSystem) { @@ -162,9 +162,9 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetTypesDetails", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET) @ResponseBody public List getBundleWidgetTypesDetails( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias) throws ThingsboardException { TenantId tenantId; if (isSystem) { @@ -181,9 +181,9 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetTypesInfos", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET) @ResponseBody public List getBundleWidgetTypesInfos( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias) throws ThingsboardException { TenantId tenantId; if (isSystem) { @@ -200,11 +200,11 @@ public class WidgetTypeController extends AutoCommitController { @RequestMapping(value = "/widgetType", params = {"isSystem", "bundleAlias", "alias"}, method = RequestMethod.GET) @ResponseBody public WidgetType getWidgetType( - @ApiParam(value = "System or Tenant", required = true) + @Parameter(description = "System or Tenant", required = true) @RequestParam boolean isSystem, - @ApiParam(value = "Widget Bundle alias", required = true) + @Parameter(description = "Widget Bundle alias", required = true) @RequestParam String bundleAlias, - @ApiParam(value = "Widget Type alias", required = true) + @Parameter(description = "Widget Type alias", required = true) @RequestParam String alias) throws ThingsboardException { TenantId tenantId; if (isSystem) { diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 737e6d54d5..9e36015ee1 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -15,8 +15,8 @@ */ package org.thingsboard.server.controller; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.widgets.bundle.TbWidgetsBundleService; import org.thingsboard.server.service.security.permission.Operation; @@ -46,13 +47,11 @@ import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FO import static org.thingsboard.server.controller.ControllerConstants.PAGE_DATA_PARAMETERS; import static org.thingsboard.server.controller.ControllerConstants.PAGE_NUMBER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.PAGE_SIZE_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.SORT_ORDER_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SORT_PROPERTY_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; import static org.thingsboard.server.controller.ControllerConstants.UUID_WIKI_LINK; import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_ID_PARAM_DESCRIPTION; -import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES; import static org.thingsboard.server.controller.ControllerConstants.WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION; @RestController @@ -71,7 +70,7 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundle/{widgetsBundleId}", method = RequestMethod.GET) @ResponseBody public WidgetsBundle getWidgetsBundleById( - @ApiParam(value = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException { checkParameter("widgetsBundleId", strWidgetsBundleId); WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); @@ -92,7 +91,7 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundle", method = RequestMethod.POST) @ResponseBody public WidgetsBundle saveWidgetsBundle( - @ApiParam(value = "A JSON value representing the Widget Bundle.", required = true) + @Parameter(description = "A JSON value representing the Widget Bundle.", required = true) @RequestBody WidgetsBundle widgetsBundle) throws Exception { var currentUser = getCurrentUser(); if (Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { @@ -112,7 +111,7 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundle/{widgetsBundleId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) public void deleteWidgetsBundle( - @ApiParam(value = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) + @Parameter(description = WIDGET_BUNDLE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("widgetsBundleId") String strWidgetsBundleId) throws ThingsboardException { checkParameter("widgetsBundleId", strWidgetsBundleId); WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); @@ -127,15 +126,15 @@ public class WidgetsBundleController extends BaseController { @RequestMapping(value = "/widgetsBundles", params = {"pageSize", "page"}, method = RequestMethod.GET) @ResponseBody public PageData getWidgetsBundles( - @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, - @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true) @RequestParam int page, - @ApiParam(value = WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION) + @Parameter(description = WIDGET_BUNDLE_TEXT_SEARCH_DESCRIPTION) @RequestParam(required = false) String textSearch, - @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = WIDGET_BUNDLE_SORT_PROPERTY_ALLOWABLE_VALUES) + @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "title", "tenantId"})) @RequestParam(required = false) String sortProperty, - @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"})) @RequestParam(required = false) String sortOrder) throws ThingsboardException { PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java index 73d763af34..c436461c65 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java @@ -15,6 +15,10 @@ */ package org.thingsboard.server.controller.plugin; +import jakarta.websocket.RemoteEndpoint; +import jakarta.websocket.SendHandler; +import jakarta.websocket.SendResult; +import jakarta.websocket.Session; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.BeanCreationNotAllowedException; import org.springframework.beans.factory.annotation.Autowired; @@ -47,10 +51,6 @@ import org.thingsboard.server.service.ws.WebSocketService; import org.thingsboard.server.service.ws.WebSocketSessionRef; import org.thingsboard.server.service.ws.WebSocketSessionType; -import jakarta.websocket.RemoteEndpoint; -import jakarta.websocket.SendHandler; -import jakarta.websocket.SendResult; -import jakarta.websocket.Session; import java.io.IOException; import java.net.URI; import java.security.InvalidParameterException; diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java index 46e7205824..a055d4c94a 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardCredentialsExpiredResponse.java @@ -15,12 +15,11 @@ */ package org.thingsboard.server.exception; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.http.HttpStatus; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; -@ApiModel +@Schema public class ThingsboardCredentialsExpiredResponse extends ThingsboardErrorResponse { private final String resetToken; @@ -34,7 +33,7 @@ public class ThingsboardCredentialsExpiredResponse extends ThingsboardErrorRespo return new ThingsboardCredentialsExpiredResponse(message, resetToken); } - @ApiModelProperty(position = 5, value = "Password reset token", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Password reset token", accessMode = Schema.AccessMode.READ_ONLY) public String getResetToken() { return resetToken; } diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java index 73cc5b0902..e1a76bbcac 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponse.java @@ -15,14 +15,13 @@ */ package org.thingsboard.server.exception; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.http.HttpStatus; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import java.util.Date; -@ApiModel +@Schema public class ThingsboardErrorResponse { // HTTP Response Status Code private final HttpStatus status; @@ -46,17 +45,17 @@ public class ThingsboardErrorResponse { return new ThingsboardErrorResponse(message, errorCode, status); } - @ApiModelProperty(position = 1, value = "HTTP Response Status Code", example = "401", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "HTTP Response Status Code", example = "401", accessMode = Schema.AccessMode.READ_ONLY) public Integer getStatus() { return status.value(); } - @ApiModelProperty(position = 2, value = "Error message", example = "Authentication failed", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Error message", example = "Authentication failed", accessMode = Schema.AccessMode.READ_ONLY) public String getMessage() { return message; } - @ApiModelProperty(position = 3, value = "Platform error code:" + + @Schema(description = "Platform error code:" + "\n* `2` - General error (HTTP: 500 - Internal Server Error)" + "\n\n* `10` - Authentication failed (HTTP: 401 - Unauthorized)" + "\n\n* `11` - JWT token expired (HTTP: 401 - Unauthorized)" + @@ -68,13 +67,13 @@ public class ThingsboardErrorResponse { "\n\n* `33` - Too many requests (HTTP: 429 - Too Many Requests)" + "\n\n* `34` - Too many updates (Too many updates over Websocket session)" + "\n\n* `40` - Subscription violation (HTTP: 403 - Forbidden)", - example = "10", dataType = "integer", - accessMode = ApiModelProperty.AccessMode.READ_ONLY) + example = "10", type = "integer", + accessMode = Schema.AccessMode.READ_ONLY) public ThingsboardErrorCode getErrorCode() { return errorCode; } - @ApiModelProperty(position = 4, value = "Timestamp", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp", accessMode = Schema.AccessMode.READ_ONLY) public Date getTimestamp() { return timestamp; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java index 78cf6b1f98..6065466a62 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginRequest.java @@ -17,10 +17,9 @@ package org.thingsboard.server.service.security.auth.rest; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class LoginRequest { private String username; @@ -33,12 +32,12 @@ public class LoginRequest { this.password = password; } - @ApiModelProperty(position = 1, required = true, value = "User email", example = "tenant@thingsboard.org") + @Schema(required = true, description = "User email", example = "tenant@thingsboard.org") public String getUsername() { return username; } - @ApiModelProperty(position = 2, required = true, value = "User password", example = "tenant") + @Schema(required = true, description = "User password", example = "tenant") public String getPassword() { return password; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java index 8fdd443fe8..91113a4caa 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/LoginResponse.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.service.security.auth.rest; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LoginResponse { - @ApiModelProperty(position = 1, required = true, value = "JWT token", + @Schema(required = true, description = "JWT token", example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...") private String token; - @ApiModelProperty(position = 2, required = true, value = "Refresh token", + @Schema(required = true, description = "Refresh token", example = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZW5hbnRAdGhpbmdzYm9hcmQub3JnIi...") private String refreshToken; diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java index aff95ea246..a3f6057d61 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ActivateUserRequest.java @@ -15,16 +15,15 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ActivateUserRequest { - @ApiModelProperty(position = 1, value = "The activate token to verify", example = "AAB254FF67D..") + @Schema(description = "The activate token to verify", example = "AAB254FF67D..") private String activateToken; - @ApiModelProperty(position = 2, value = "The new password to set", example = "secret") + @Schema(description = "The new password to set", example = "secret") private String password; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java index 4b21acef5e..0596f8f43a 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ChangePasswordRequest.java @@ -15,17 +15,16 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ChangePasswordRequest { - @ApiModelProperty(position = 1, value = "The old password", example = "OldPassword") + @Schema(description = "The old password", example = "OldPassword") private String currentPassword; - @ApiModelProperty(position = 1, value = "The new password", example = "NewPassword") + @Schema(description = "The new password", example = "NewPassword") private String newPassword; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java index 93f9541986..fb4832a264 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordEmailRequest.java @@ -15,14 +15,13 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ResetPasswordEmailRequest { - @ApiModelProperty(position = 1, value = "The email of the user", example = "user@example.com") + @Schema(description = "The email of the user", example = "user@example.com") private String email; } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java index 3869da9b02..6afeff730b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/ResetPasswordRequest.java @@ -15,16 +15,15 @@ */ package org.thingsboard.server.service.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class ResetPasswordRequest { - @ApiModelProperty(position = 1, value = "The reset token to verify", example = "AAB254FF67D..") + @Schema(description = "The reset token to verify", example = "AAB254FF67D..") private String resetToken; - @ApiModelProperty(position = 2, value = "The new password to set", example = "secret") + @Schema(description = "The new password to set", example = "secret") private String password; } diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java b/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java index b7c7b281ca..58a56e05c1 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/AttributeData.java @@ -15,10 +15,9 @@ */ package org.thingsboard.server.service.telemetry; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class AttributeData implements Comparable{ private final long lastUpdateTs; @@ -32,17 +31,17 @@ public class AttributeData implements Comparable{ this.value = value; } - @ApiModelProperty(position = 1, value = "Timestamp last updated attribute, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp last updated attribute, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) public long getLastUpdateTs() { return lastUpdateTs; } - @ApiModelProperty(position = 2, value = "String representing attribute key", example = "active", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "String representing attribute key", example = "active", accessMode = Schema.AccessMode.READ_ONLY) public String getKey() { return key; } - @ApiModelProperty(position = 3, value = "Object representing value of attribute key", example = "false", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Object representing value of attribute key", example = "false", accessMode = Schema.AccessMode.READ_ONLY) public Object getValue() { return value; } diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java b/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java index d0af1080d3..d0f07ac094 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/TsData.java @@ -15,10 +15,9 @@ */ package org.thingsboard.server.service.telemetry; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema public class TsData implements Comparable{ private final long ts; @@ -30,12 +29,12 @@ public class TsData implements Comparable{ this.value = value; } - @ApiModelProperty(position = 1, value = "Timestamp last updated timeseries, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp last updated timeseries, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) public long getTs() { return ts; } - @ApiModelProperty(position = 2, value = "Object representing value of timeseries key", example = "20", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Object representing value of timeseries key", example = "20", accessMode = Schema.AccessMode.READ_ONLY) public Object getValue() { return value; } diff --git a/application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java b/application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java deleted file mode 100644 index 6a222870b0..0000000000 --- a/application/src/main/java/org/thingsboard/server/springfox/SpringfoxHandlerProviderBeanPostProcessor.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.springfox; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.stereotype.Component; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; -import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; - -import java.lang.reflect.Field; -import java.util.List; -import java.util.stream.Collectors; - -@Component -//TODO: remove after fixing issue https://github.com/springfox/springfox/issues/3462 or after migration from springfox to springdoc -public class SpringfoxHandlerProviderBeanPostProcessor implements BeanPostProcessor { - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof WebMvcRequestHandlerProvider) { - customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); - } - return bean; - } - - private void customizeSpringfoxHandlerMappings(List mappings) { - List copy = mappings.stream() - .filter(mapping -> mapping.getPatternParser() == null) - .collect(Collectors.toList()); - mappings.clear(); - mappings.addAll(copy); - } - - @SuppressWarnings("unchecked") - private List getHandlerMappings(Object bean) { - try { - Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); - field.setAccessible(true); - return (List) field.get(bean); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new IllegalStateException(e); - } - } -} diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 6e68e1066f..7473121866 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -988,10 +988,12 @@ edges: state: persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}" +springdoc: + api-docs.enabled: "${SWAGGER_ENABLED:true}" + default-produces-media-type: "${SWAGGER_DEFAULT_PRODUCES_MEDIA_TYPE:application/json}" + swagger: - enabled: "${SWAGGER_ENABLED:true}" - api_path_regex: "${SWAGGER_API_PATH_REGEX:/api/.*}" - security_path_regex: "${SWAGGER_SECURITY_PATH_REGEX:/api/.*}" + api_path: "${SWAGGER_API_PATH:/api/**}" non_security_path_regex: "${SWAGGER_NON_SECURITY_PATH_REGEX:/api/(?:noauth|v1)/.*}" title: "${SWAGGER_TITLE:ThingsBoard REST API}" description: "${SWAGGER_DESCRIPTION: ThingsBoard open-source IoT platform REST API documentation.}" diff --git a/common/data/pom.xml b/common/data/pom.xml index cf528b9bbd..9aa6aed2c0 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -105,8 +105,8 @@ commons-codec - io.swagger - swagger-annotations + io.swagger.core.v3 + swagger-annotations-jakarta com.google.protobuf diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java index c1f296c26c..a70d235bd5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java @@ -16,14 +16,13 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.id.AdminSettingsId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema public class AdminSettings extends BaseData implements HasTenantId { private static final long serialVersionUID = -7670322981725511892L; @@ -50,19 +49,19 @@ public class AdminSettings extends BaseData implements HasTenan this.jsonValue = adminSettings.getJsonValue(); } - @ApiModelProperty(position = 1, value = "The Id of the Administration Settings, auto-generated, UUID") + @Schema(description = "The Id of the Administration Settings, auto-generated, UUID") @Override public AdminSettingsId getId() { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the settings creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the settings creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -71,7 +70,7 @@ public class AdminSettings extends BaseData implements HasTenan this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "The Administration Settings key, (e.g. 'general' or 'mail')", example = "mail") + @Schema(description = "The Administration Settings key, (e.g. 'general' or 'mail')", example = "mail") public String getKey() { return key; } @@ -80,7 +79,7 @@ public class AdminSettings extends BaseData implements HasTenan this.key = key; } - @ApiModelProperty(position = 5, value = "JSON representation of the Administration Settings value") + @Schema(description = "JSON representation of the Administration Settings value") public JsonNode getJsonValue() { return jsonValue; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java index 636ab0de38..6f9d6e4360 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java @@ -19,7 +19,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -35,9 +36,9 @@ public class Customer extends ContactBased implements HasTenantId, E @NoXss @Length(fieldName = "title") - @ApiModelProperty(position = 3, value = "Title of the customer", example = "Company A") + @Schema(description = "Title of the customer", example = "Company A") private String title; - @ApiModelProperty(position = 5, required = true, value = "JSON object with Tenant Id") + @Schema(required = true, description = "JSON object with Tenant Id") private TenantId tenantId; @Getter @Setter @@ -74,7 +75,7 @@ public class Customer extends ContactBased implements HasTenantId, E this.title = title; } - @ApiModelProperty(position = 1, value = "JSON object with the customer Id. " + + @Schema(description = "JSON object with the customer Id. " + "Specify this field to update the customer. " + "Referencing non-existing customer Id will cause error. " + "Omit this field to create new customer." ) @@ -83,61 +84,61 @@ public class Customer extends ContactBased implements HasTenantId, E return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the customer creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the customer creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 6, required = true, value = "Country", example = "US") + @Schema(required = true, description = "Country", example = "US") @Override public String getCountry() { return super.getCountry(); } - @ApiModelProperty(position = 7, required = true, value = "State", example = "NY") + @Schema(required = true, description = "State", example = "NY") @Override public String getState() { return super.getState(); } - @ApiModelProperty(position = 8, required = true, value = "City", example = "New York") + @Schema(required = true, description = "City", example = "New York") @Override public String getCity() { return super.getCity(); } - @ApiModelProperty(position = 9, required = true, value = "Address Line 1", example = "42 Broadway Suite 12-400") + @Schema(required = true, description = "Address Line 1", example = "42 Broadway Suite 12-400") @Override public String getAddress() { return super.getAddress(); } - @ApiModelProperty(position = 10, required = true, value = "Address Line 2", example = "") + @Schema(required = true, description = "Address Line 2", example = "") @Override public String getAddress2() { return super.getAddress2(); } - @ApiModelProperty(position = 11, required = true, value = "Zip code", example = "10004") + @Schema(required = true, description = "Zip code", example = "10004") @Override public String getZip() { return super.getZip(); } - @ApiModelProperty(position = 12, required = true, value = "Phone number", example = "+1(415)777-7777") + @Schema(required = true, description = "Phone number", example = "+1(415)777-7777") @Override public String getPhone() { return super.getPhone(); } - @ApiModelProperty(position = 13, required = true, value = "Email", example = "example@company.com") + @Schema(required = true, description = "Email", example = "example@company.com") @Override public String getEmail() { return super.getEmail(); } - @ApiModelProperty(position = 14, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); @@ -159,7 +160,7 @@ public class Customer extends ContactBased implements HasTenantId, E @Override @JsonProperty(access = Access.READ_ONLY) - @ApiModelProperty(position = 4, value = "Name of the customer. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the customer. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = Schema.AccessMode.READ_ONLY) public String getName() { return title; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java index 10496aaaa2..f0e09a1128 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.collect.Streams; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -59,10 +59,10 @@ public class Dashboard extends DashboardInfo implements ExportableEntity implements HasName, HasTenantId, HasTitle { private TenantId tenantId; @@ -61,7 +60,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.mobileOrder = dashboardInfo.getMobileOrder(); } - @ApiModelProperty(position = 1, value = "JSON object with the dashboard Id. " + + @Schema(description = "JSON object with the dashboard Id. " + "Specify existing dashboard Id to update the dashboard. " + "Referencing non-existing dashboard id will cause error. " + "Omit this field to create new dashboard.") @@ -70,13 +69,13 @@ public class DashboardInfo extends BaseData implements HasName, Has return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the dashboard creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the dashboard creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the dashboard can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Tenant Id of the dashboard can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -85,7 +84,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "Title of the dashboard.") + @Schema(description = "Title of the dashboard.") public String getTitle() { return title; } @@ -94,7 +93,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.title = title; } - @ApiModelProperty(position = 8, value = "Thumbnail picture for rendering of the dashboards in a grid view on mobile devices.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Thumbnail picture for rendering of the dashboards in a grid view on mobile devices.", accessMode = Schema.AccessMode.READ_ONLY) public String getImage() { return image; } @@ -103,7 +102,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.image = image; } - @ApiModelProperty(position = 5, value = "List of assigned customers with their info.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "List of assigned customers with their info.", accessMode = Schema.AccessMode.READ_ONLY) public Set getAssignedCustomers() { return assignedCustomers; } @@ -112,7 +111,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.assignedCustomers = assignedCustomers; } - @ApiModelProperty(position = 6, value = "Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Hide dashboard from mobile devices. Useful if the dashboard is not designed for small screens.", accessMode = Schema.AccessMode.READ_ONLY) public boolean isMobileHide() { return mobileHide; } @@ -121,7 +120,7 @@ public class DashboardInfo extends BaseData implements HasName, Has this.mobileHide = mobileHide; } - @ApiModelProperty(position = 7, value = "Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Order on mobile devices. Useful to adjust sorting of the dashboards for mobile applications", accessMode = Schema.AccessMode.READ_ONLY) public Integer getMobileOrder() { return mobileOrder; } @@ -179,7 +178,7 @@ public class DashboardInfo extends BaseData implements HasName, Has } } - @ApiModelProperty(position = 4, value = "Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Same as title of the dashboard. Read-only field. Update the 'title' to change the 'name' of the dashboard.", accessMode = Schema.AccessMode.READ_ONLY) @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java index 45e4244bcb..c8cb6384e2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -37,7 +36,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Optional; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) @Slf4j public class Device extends BaseDataWithAdditionalInfo implements HasLabel, HasTenantId, HasCustomerId, HasOtaPackage, ExportableEntity { @@ -103,7 +102,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL return this; } - @ApiModelProperty(position = 1, value = "JSON object with the Device Id. " + + @Schema(description = "JSON object with the Device Id. " + "Specify this field to update the Device. " + "Referencing non-existing Device Id will cause error. " + "Omit this field to create new Device." ) @@ -112,13 +111,13 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the device creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the device creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -127,7 +126,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignDeviceToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignDeviceToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } @@ -136,7 +135,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.customerId = customerId; } - @ApiModelProperty(position = 5, required = true, value = "Unique Device Name in scope of Tenant", example = "A4B72CCDFF33") + @Schema(required = true, description = "Unique Device Name in scope of Tenant", example = "A4B72CCDFF33") @Override public String getName() { return name; @@ -146,7 +145,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.name = name; } - @ApiModelProperty(position = 6, required = true, value = "Device Profile Name", example = "Temperature Sensor") + @Schema(required = true, description = "Device Profile Name", example = "Temperature Sensor") public String getType() { return type; } @@ -155,7 +154,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.type = type; } - @ApiModelProperty(position = 7, required = true, value = "Label that may be used in widgets", example = "Room 234 Sensor") + @Schema(required = true, description = "Label that may be used in widgets", example = "Room 234 Sensor") public String getLabel() { return label; } @@ -164,7 +163,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.label = label; } - @ApiModelProperty(position = 8, required = true, value = "JSON object with Device Profile Id.") + @Schema(required = true, description = "JSON object with Device Profile Id.") public DeviceProfileId getDeviceProfileId() { return deviceProfileId; } @@ -173,7 +172,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.deviceProfileId = deviceProfileId; } - @ApiModelProperty(position = 9, value = "JSON object with content specific to type of transport in the device profile.") + @Schema(description = "JSON object with content specific to type of transport in the device profile.") public DeviceData getDeviceData() { if (deviceData != null) { return deviceData; @@ -201,7 +200,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL } } - @ApiModelProperty(position = 10, value = "JSON object with Ota Package Id.") + @Schema(description = "JSON object with Ota Package Id.") public OtaPackageId getFirmwareId() { return firmwareId; } @@ -210,7 +209,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.firmwareId = firmwareId; } - @ApiModelProperty(position = 11, value = "JSON object with Ota Package Id.") + @Schema(description = "JSON object with Ota Package Id.") public OtaPackageId getSoftwareId() { return softwareId; } @@ -219,7 +218,7 @@ public class Device extends BaseDataWithAdditionalInfo implements HasL this.softwareId = softwareId; } - @ApiModelProperty(position = 12, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java index 3204cc217a..80cc3a1d24 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceInfo.java @@ -15,26 +15,25 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.DeviceId; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class DeviceInfo extends Device { private static final long serialVersionUID = -3004579925090663691L; - @ApiModelProperty(position = 13, value = "Title of the Customer that owns the device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title of the Customer that owns the device.", accessMode = Schema.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 14, value = "Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates special 'Public' Customer that is auto-generated to use the devices on public dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private boolean customerIsPublic; - @ApiModelProperty(position = 15, value = "Name of the corresponding Device Profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the corresponding Device Profile.", accessMode = Schema.AccessMode.READ_ONLY) private String deviceProfileName; - @ApiModelProperty(position = 16, value = "Device active flag.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Device active flag.", accessMode = Schema.AccessMode.READ_ONLY) private boolean active; public DeviceInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index 2be110b258..090bafdb69 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -36,7 +35,7 @@ import jakarta.validation.Valid; import java.io.ByteArrayInputStream; import java.io.IOException; -@ApiModel +@Schema @Data @ToString(exclude = {"image", "profileDataBytes"}) @EqualsAndHashCode(callSuper = true) @@ -45,34 +44,34 @@ public class DeviceProfile extends BaseData implements HasName, private static final long serialVersionUID = 6998485460273302018L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id that owns the profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id that owns the profile.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 4, value = "Unique Device Profile Name in scope of Tenant.", example = "Moisture Sensor") + @Schema(description = "Unique Device Profile Name in scope of Tenant.", example = "Moisture Sensor") private String name; @NoXss - @ApiModelProperty(position = 11, value = "Device Profile description. ") + @Schema(description = "Device Profile description. ") private String description; @Length(fieldName = "image", max = 1000000) - @ApiModelProperty(position = 12, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") private String image; private boolean isDefault; - @ApiModelProperty(position = 16, value = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") + @Schema(description = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") private DeviceProfileType type; - @ApiModelProperty(position = 14, value = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") + @Schema(description = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") private DeviceTransportType transportType; - @ApiModelProperty(position = 15, value = "Provisioning strategy.") + @Schema(description = "Provisioning strategy.") private DeviceProfileProvisionType provisionType; - @ApiModelProperty(position = 7, value = "Reference to the rule chain. " + + @Schema(description = "Reference to the rule chain. " + "If present, the specified rule chain will be used to process all messages related to device, including telemetry, attribute updates, etc. " + "Otherwise, the root rule chain will be used to process those messages.") private RuleChainId defaultRuleChainId; - @ApiModelProperty(position = 6, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") private DashboardId defaultDashboardId; @NoXss - @ApiModelProperty(position = 8, value = "Rule engine queue name. " + + @Schema(description = "Rule engine queue name. " + "If present, the specified queue will be used to store all unprocessed messages related to device, including telemetry, attribute updates, etc. " + "Otherwise, the 'Main' queue will be used to store those messages.") private String defaultQueueName; @@ -81,15 +80,15 @@ public class DeviceProfile extends BaseData implements HasName, @JsonIgnore private byte[] profileDataBytes; @NoXss - @ApiModelProperty(position = 13, value = "Unique provisioning key used by 'Device Provisioning' feature.") + @Schema(description = "Unique provisioning key used by 'Device Provisioning' feature.") private String provisionDeviceKey; - @ApiModelProperty(position = 9, value = "Reference to the firmware OTA package. If present, the specified package will be used as default device firmware. ") + @Schema(description = "Reference to the firmware OTA package. If present, the specified package will be used as default device firmware. ") private OtaPackageId firmwareId; - @ApiModelProperty(position = 10, value = "Reference to the software OTA package. If present, the specified package will be used as default device software. ") + @Schema(description = "Reference to the software OTA package. If present, the specified package will be used as default device software. ") private OtaPackageId softwareId; - @ApiModelProperty(position = 17, value = "Reference to the edge rule chain. " + + @Schema(description = "Reference to the edge rule chain. " + "If present, the specified edge rule chain will be used on the edge to process all messages related to device, including telemetry, attribute updates, etc. " + "Otherwise, the edge root rule chain will be used to process those messages.") private RuleChainId defaultEdgeRuleChainId; @@ -122,7 +121,7 @@ public class DeviceProfile extends BaseData implements HasName, this.externalId = deviceProfile.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the device profile Id. " + + @Schema(description = "JSON object with the device profile Id. " + "Specify this field to update the device profile. " + "Referencing non-existing device profile Id will cause error. " + "Omit this field to create new device profile.") @@ -131,18 +130,18 @@ public class DeviceProfile extends BaseData implements HasName, return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 5, value = "Used to mark the default profile. Default profile is used when the device profile is not specified during device creation.") + @Schema(description = "Used to mark the default profile. Default profile is used when the device profile is not specified during device creation.") public boolean isDefault() { return isDefault; } - @ApiModelProperty(position = 16, value = "Complex JSON object that includes addition device profile configuration (transport, alarm rules, etc).") + @Schema(description = "Complex JSON object that includes addition device profile configuration (transport, alarm rules, etc).") public DeviceProfileData getProfileData() { if (profileData != null) { return profileData; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java index 295b9f6b99..93b094f901 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileInfo.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.Value; @@ -33,16 +33,16 @@ import java.util.UUID; @ToString(callSuper = true, exclude = "image") public class DeviceProfileInfo extends EntityInfo { - @ApiModelProperty(position = 3, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of device profiles in the grid view. ") private final String image; - @ApiModelProperty(position = 4, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to device details.") private final DashboardId defaultDashboardId; - @ApiModelProperty(position = 5, value = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") + @Schema(description = "Type of the profile. Always 'DEFAULT' for now. Reserved for future use.") private final DeviceProfileType type; - @ApiModelProperty(position = 6, value = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") + @Schema(description = "Type of the transport used to connect the device. Default transport supports HTTP, CoAP and MQTT.") private final DeviceTransportType transportType; - @ApiModelProperty(position = 7, value = "Tenant id.") + @Schema(description = "Tenant id.") private final TenantId tenantId; @JsonCreator diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java index 6a86a65d1f..d3109c68d6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityInfo.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; @@ -26,13 +25,13 @@ import org.thingsboard.server.common.data.id.HasId; import java.util.UUID; -@ApiModel +@Schema @Data public class EntityInfo implements HasId, HasName { - @ApiModelProperty(position = 1, value = "JSON object with the entity Id. ") + @Schema(description = "JSON object with the entity Id. ") private final EntityId id; - @ApiModelProperty(position = 2, value = "Entity Name") + @Schema(description = "Entity Name") private final String name; @JsonCreator diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java index c0e44baeb3..72c7346c9e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -40,23 +40,23 @@ public class EntityView extends BaseDataWithAdditionalInfo private static final long serialVersionUID = 5582010124562018986L; - @ApiModelProperty(position = 7, required = true, value = "JSON object with the referenced Entity Id (Device or Asset).") + @Schema(required = true, description = "JSON object with the referenced Entity Id (Device or Asset).") private EntityId entityId; private TenantId tenantId; private CustomerId customerId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 5, required = true, value = "Entity View name", example = "A4B72CCDFF33") + @Schema(required = true, description = "Entity View name", example = "A4B72CCDFF33") private String name; @NoXss @Length(fieldName = "type") - @ApiModelProperty(position = 6, required = true, value = "Device Profile Name", example = "Temperature Sensor") + @Schema(required = true, description = "Device Profile Name", example = "Temperature Sensor") private String type; - @ApiModelProperty(position = 8, required = true, value = "Set of telemetry and attribute keys to expose via Entity View.") + @Schema(required = true, description = "Set of telemetry and attribute keys to expose via Entity View.") private TelemetryEntityView keys; - @ApiModelProperty(position = 9, value = "Represents the start time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") + @Schema(description = "Represents the start time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") private long startTimeMs; - @ApiModelProperty(position = 10, value = "Represents the end time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") + @Schema(description = "Represents the end time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") private long endTimeMs; private EntityViewId externalId; @@ -82,7 +82,7 @@ public class EntityView extends BaseDataWithAdditionalInfo this.externalId = entityView.getExternalId(); } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEntityViewToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignEntityViewToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public CustomerId getCustomerId() { return customerId; @@ -93,13 +93,13 @@ public class EntityView extends BaseDataWithAdditionalInfo return name; } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public TenantId getTenantId() { return tenantId; } - @ApiModelProperty(position = 1, value = "JSON object with the Entity View Id. " + + @Schema(description = "JSON object with the Entity View Id. " + "Specify this field to update the Entity View. " + "Referencing non-existing Entity View Id will cause error. " + "Omit this field to create new Entity View." ) @@ -108,13 +108,13 @@ public class EntityView extends BaseDataWithAdditionalInfo return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Entity View creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the Entity View creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 11, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java index 069ea3ae5d..ca3d26087f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityViewInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.EntityViewId; @@ -24,9 +24,9 @@ import org.thingsboard.server.common.data.id.EntityViewId; @EqualsAndHashCode(callSuper = true) public class EntityViewInfo extends EntityView { - @ApiModelProperty(position = 12, value = "Title of the Customer that owns the entity view.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title of the Customer that owns the entity view.", accessMode = Schema.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 13, value = "Indicates special 'Public' Customer that is auto-generated to use the entity view on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates special 'Public' Customer that is auto-generated to use the entity view on public dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private boolean customerIsPublic; public EntityViewInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java index 11491db4f9..d20438a5b3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EventInfo.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EventId; @@ -27,18 +26,18 @@ import org.thingsboard.server.common.data.id.TenantId; * @author Andrew Shvayka */ @Data -@ApiModel +@Schema public class EventInfo extends BaseData { - @ApiModelProperty(position = 1, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 2, value = "Event type", example = "STATS") + @Schema(description = "Event type", example = "STATS") private String type; - @ApiModelProperty(position = 3, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(description = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") private String uid; - @ApiModelProperty(position = 4, value = "JSON object with Entity Id for which event is created.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Entity Id for which event is created.", accessMode = Schema.AccessMode.READ_ONLY) private EntityId entityId; - @ApiModelProperty(position = 5, value = "Event body.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Event body.",implementation = com.fasterxml.jackson.databind.JsonNode.class) private transient JsonNode body; public EventInfo() { @@ -53,7 +52,7 @@ public class EventInfo extends BaseData { super(event); } - @ApiModelProperty(position = 6, value = "Timestamp of the event creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the event creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java b/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java index 4677cff29b..a2b21d2a86 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ExportableEntity.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.TenantId; @@ -24,7 +24,7 @@ public interface ExportableEntity extends HasId, HasName void setId(I id); - @ApiModelProperty(position = 100, value = "JSON object with External Id from the VCS", accessMode = ApiModelProperty.AccessMode.READ_ONLY, hidden = true) + @Schema(description = "JSON object with External Id from the VCS", accessMode = Schema.AccessMode.READ_ONLY, hidden = true) I getExternalId(); void setExternalId(I externalId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java index 6dfbfaa4ed..8971eb9f78 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboard.java @@ -15,17 +15,16 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class HomeDashboard extends Dashboard { public static final String HIDE_DASHBOARD_TOOLBAR_DESCRIPTION = "Hide dashboard toolbar flag. Useful for rendering dashboards on mobile."; - @ApiModelProperty(position = 10, value = HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) + @Schema(description = HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) private boolean hideDashboardToolbar; public HomeDashboard(Dashboard dashboard, boolean hideDashboardToolbar) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java index ae694fd61a..173b88259c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.id.DashboardId; -@ApiModel +@Schema @Data @AllArgsConstructor public class HomeDashboardInfo { - @ApiModelProperty(position = 1, value = "JSON object with the dashboard Id.") + @Schema(description = "JSON object with the dashboard Id.") private DashboardId dashboardId; - @ApiModelProperty(position = 1, value = HomeDashboard.HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) + @Schema(description = HomeDashboard.HIDE_DASHBOARD_TOOLBAR_DESCRIPTION) private boolean hideDashboardToolbar; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java index d3aaddf3af..d7f4f20e02 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackage.java @@ -15,22 +15,21 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.OtaPackageId; import java.nio.ByteBuffer; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class OtaPackage extends OtaPackageInfo { private static final long serialVersionUID = 3091601761339422546L; - @ApiModelProperty(position = 16, value = "OTA Package data.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package data.", accessMode = Schema.AccessMode.READ_ONLY) private transient ByteBuffer data; public OtaPackage() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java index ab84724117..aa43567adc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/OtaPackageInfo.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -30,7 +29,7 @@ import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Slf4j @Data @EqualsAndHashCode(callSuper = true) @@ -38,44 +37,44 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp private static final long serialVersionUID = 3168391583570815419L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the ota package can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Tenant Id of the ota package can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Device Profile Id. Device Profile Id of the ota package can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Device Profile Id. Device Profile Id of the ota package can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) private DeviceProfileId deviceProfileId; - @ApiModelProperty(position = 5, value = "OTA Package type.", example = "FIRMWARE", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package type.", example = "FIRMWARE", accessMode = Schema.AccessMode.READ_ONLY) private OtaPackageType type; @Length(fieldName = "title") @NoXss - @ApiModelProperty(position = 6, value = "OTA Package title.", example = "fw", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package title.", example = "fw", accessMode = Schema.AccessMode.READ_ONLY) private String title; @Length(fieldName = "version") @NoXss - @ApiModelProperty(position = 7, value = "OTA Package version.", example = "1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package version.", example = "1.0", accessMode = Schema.AccessMode.READ_ONLY) private String version; @Length(fieldName = "tag") @NoXss - @ApiModelProperty(position = 8, value = "OTA Package tag.", example = "fw_1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package tag.", example = "fw_1.0", accessMode = Schema.AccessMode.READ_ONLY) private String tag; @Length(fieldName = "url") @NoXss - @ApiModelProperty(position = 9, value = "OTA Package url.", example = "http://thingsboard.org/fw/1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package url.", example = "http://thingsboard.org/fw/1", accessMode = Schema.AccessMode.READ_ONLY) private String url; - @ApiModelProperty(position = 10, value = "Indicates OTA Package 'has data'. Field is returned from DB ('true' if data exists or url is set). If OTA Package 'has data' is 'false' we can not assign the OTA Package to the Device or Device Profile.", example = "true", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates OTA Package 'has data'. Field is returned from DB ('true' if data exists or url is set). If OTA Package 'has data' is 'false' we can not assign the OTA Package to the Device or Device Profile.", example = "true", accessMode = Schema.AccessMode.READ_ONLY) private boolean hasData; @Length(fieldName = "file name") @NoXss - @ApiModelProperty(position = 11, value = "OTA Package file name.", example = "fw_1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package file name.", example = "fw_1.0", accessMode = Schema.AccessMode.READ_ONLY) private String fileName; @NoXss @Length(fieldName = "contentType") - @ApiModelProperty(position = 12, value = "OTA Package content type.", example = "APPLICATION_OCTET_STREAM", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package content type.", example = "APPLICATION_OCTET_STREAM", accessMode = Schema.AccessMode.READ_ONLY) private String contentType; - @ApiModelProperty(position = 13, value = "OTA Package checksum algorithm.", example = "CRC32", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package checksum algorithm.", example = "CRC32", accessMode = Schema.AccessMode.READ_ONLY) private ChecksumAlgorithm checksumAlgorithm; @Length(fieldName = "checksum", max = 1020) - @ApiModelProperty(position = 14, value = "OTA Package checksum.", example = "0xd87f7e0c", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package checksum.", example = "0xd87f7e0c", accessMode = Schema.AccessMode.READ_ONLY) private String checksum; - @ApiModelProperty(position = 15, value = "OTA Package data size.", example = "8", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "OTA Package data size.", example = "8", accessMode = Schema.AccessMode.READ_ONLY) private Long dataSize; public OtaPackageInfo() { @@ -103,7 +102,7 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp this.dataSize = otaPackageInfo.getDataSize(); } - @ApiModelProperty(position = 1, value = "JSON object with the ota package Id. " + + @Schema(description = "JSON object with the ota package Id. " + "Specify existing ota package Id to update the ota package. " + "Referencing non-existing ota package id will cause error. " + "Omit this field to create new ota package.") @@ -112,7 +111,7 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the ota package creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the ota package creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); @@ -129,7 +128,7 @@ public class OtaPackageInfo extends BaseDataWithAdditionalInfo imp return StringUtils.isNotEmpty(url); } - @ApiModelProperty(position = 17, value = "OTA Package description.", example = "Description for the OTA Package fw_1.0") + @Schema(description = "OTA Package description.", example = "Description for the OTA Package fw_1.0") @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java index f8c74a5155..7714be385b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SaveDeviceWithCredentialsRequest.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.security.DeviceCredentials; -@ApiModel +@Schema @Data public class SaveDeviceWithCredentialsRequest { - @ApiModelProperty(position = 1, value = "The JSON with device entity.", required = true) + @Schema(description = "The JSON with device entity.", required = true) private final Device device; - @ApiModelProperty(position = 2, value = "The JSON with credentials entity.", required = true) + @Schema(description = "The JSON with credentials entity.", required = true) private final DeviceCredentials credentials; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java index 8a54de65fa..4c85c44d94 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SaveOtaPackageInfoRequest.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @NoArgsConstructor public class SaveOtaPackageInfoRequest extends OtaPackageInfo { - @ApiModelProperty(position = 16, value = "Indicates OTA Package uses url. Should be 'true' if uses url or 'false' if will be used data.", example = "true", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates OTA Package uses url. Should be 'true' if uses url or 'false' if will be used data.", example = "true", accessMode = Schema.AccessMode.READ_ONLY) boolean usesUrl; public SaveOtaPackageInfoRequest(OtaPackageInfo otaPackageInfo, boolean usesUrl) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java index 237a4d9a22..180180f569 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @@ -27,20 +26,20 @@ import org.thingsboard.server.common.data.validation.NoXss; * Created by igor on 2/27/18. */ -@ApiModel +@Schema @AllArgsConstructor public class ShortCustomerInfo { - @ApiModelProperty(position = 1, value = "JSON object with the customer Id.") + @Schema(description = "JSON object with the customer Id.") @Getter @Setter private CustomerId customerId; - @ApiModelProperty(position = 2, value = "Title of the customer.") + @Schema(description = "Title of the customer.") @Getter @Setter @NoXss private String title; - @ApiModelProperty(position = 3, value = "Indicates special 'Public' customer used to embed dashboards on public websites.") + @Schema(description = "Indicates special 'Public' customer used to embed dashboards on public websites.") @Getter @Setter private boolean isPublic; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java index ea46c91239..93ff39ef7a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfo.java @@ -15,15 +15,15 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; @Data public class SystemInfo { - @ApiModelProperty(position = 1, value = "Is monolith.") + @Schema(description = "Is monolith.") private boolean isMonolith; - @ApiModelProperty(position = 2, value = "System data.") + @Schema(description = "System data.") private List systemData; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java index 5ae53565cf..1db6a5002a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/SystemInfoData.java @@ -15,26 +15,26 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data public class SystemInfoData { - @ApiModelProperty(position = 1, value = "Service Id.") + @Schema(description = "Service Id.") private String serviceId; - @ApiModelProperty(position = 2, value = "Service type.") + @Schema(description = "Service type.") private String serviceType; - @ApiModelProperty(position = 3, value = "CPU usage, in percent.") + @Schema(description = "CPU usage, in percent.") private Long cpuUsage; - @ApiModelProperty(position = 4, value = "Total CPU usage.") + @Schema(description = "Total CPU usage.") private Long cpuCount; - @ApiModelProperty(position = 5, value = "Memory usage, in percent.") + @Schema(description = "Memory usage, in percent.") private Long memoryUsage; - @ApiModelProperty(position = 6, value = "Total memory in bytes.") + @Schema(description = "Total memory in bytes.") private Long totalMemory; - @ApiModelProperty(position = 7, value = "Disk usage, in percent.") + @Schema(description = "Disk usage, in percent.") private Long discUsage; - @ApiModelProperty(position = 8, value = "Total disc space in bytes.") + @Schema(description = "Total disc space in bytes.") private Long totalDiscSpace; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java index 91bb7ba383..c6aa878948 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResource.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -32,10 +32,10 @@ public class TbResource extends TbResourceInfo { @NoXss @Length(fieldName = "file name") - @ApiModelProperty(position = 8, value = "Resource file name.", example = "19.xml", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource file name.", example = "19.xml", accessMode = Schema.AccessMode.READ_ONLY) private String fileName; - @ApiModelProperty(position = 9, value = "Resource data.", example = "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLQpGSUxFIElORk9STUFUSU9OCgpPTUEgUGVybWFuZW50IERvY3VtZW50CiAgIEZpbGU6IE9NQS1TVVAtTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci1WMV8wXzEtMjAxOTAyMjEtQQogICBUeXBlOiB4bWwKClB1YmxpYyBSZWFjaGFibGUgSW5mb3JtYXRpb24KICAgUGF0aDogaHR0cDovL3d3dy5vcGVubW9iaWxlYWxsaWFuY2Uub3JnL3RlY2gvcHJvZmlsZXMKICAgTmFtZTogTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci12MV8wXzEueG1sCgpOT1JNQVRJVkUgSU5GT1JNQVRJT04KCiAgSW5mb3JtYXRpb24gYWJvdXQgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBpbiB0aGUgbGF0ZXN0IHJldmlzaW9uIG9mCgogIE9NQS1UUy1MV00yTV9CaW5hcnlBcHBEYXRhQ29udGFpbmVyLVYxXzBfMQoKICBUaGlzIGlzIGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm9wZW5tb2JpbGVhbGxpYW5jZS5vcmcvCgogIFNlbmQgY29tbWVudHMgdG8gaHR0cHM6Ly9naXRodWIuY29tL09wZW5Nb2JpbGVBbGxpYW5jZS9PTUFfTHdNMk1fZm9yX0RldmVsb3BlcnMvaXNzdWVzCgpDSEFOR0UgSElTVE9SWQoKMTUwNjIwMTggU3RhdHVzIGNoYW5nZWQgdG8gQXBwcm92ZWQgYnkgRE0sIERvYyBSZWYgIyBPTUEtRE0mU0UtMjAxOC0wMDYxLUlOUF9MV00yTV9BUFBEQVRBX1YxXzBfRVJQX2Zvcl9maW5hbF9BcHByb3ZhbAoyMTAyMjAxOSBTdGF0dXMgY2hhbmdlZCB0byBBcHByb3ZlZCBieSBJUFNPLCBEb2MgUmVmICMgT01BLUlQU08tMjAxOS0wMDI1LUlOUF9Md00yTV9PYmplY3RfQXBwX0RhdGFfQ29udGFpbmVyXzFfMF8xX2Zvcl9GaW5hbF9BcHByb3ZhbAoKTEVHQUwgRElTQ0xBSU1FUgoKQ29weXJpZ2h0IDIwMTkgT3BlbiBNb2JpbGUgQWxsaWFuY2UuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCmFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodApub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cm5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cwpjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwoiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwpGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULApJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCkxJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOCkFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQpQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KClRoZSBhYm92ZSBsaWNlbnNlIGlzIHVzZWQgYXMgYSBsaWNlbnNlIHVuZGVyIGNvcHlyaWdodCBvbmx5LiBQbGVhc2UKcmVmZXJlbmNlIHRoZSBPTUEgSVBSIFBvbGljeSBmb3IgcGF0ZW50IGxpY2Vuc2luZyB0ZXJtczoKaHR0cHM6Ly93d3cub21hc3BlY3dvcmtzLm9yZy9hYm91dC9pbnRlbGxlY3R1YWwtcHJvcGVydHktcmlnaHRzLwoKLS0+CjxMV00yTSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj0iaHR0cDovL29wZW5tb2JpbGVhbGxpYW5jZS5vcmcvdGVjaC9wcm9maWxlcy9MV00yTS54c2QiPgoJPE9iamVjdCBPYmplY3RUeXBlPSJNT0RlZmluaXRpb24iPgoJCTxOYW1lPkJpbmFyeUFwcERhdGFDb250YWluZXI8L05hbWU+CgkJPERlc2NyaXB0aW9uMT48IVtDREFUQVtUaGlzIEx3TTJNIE9iamVjdHMgcHJvdmlkZXMgdGhlIGFwcGxpY2F0aW9uIHNlcnZpY2UgZGF0YSByZWxhdGVkIHRvIGEgTHdNMk0gU2VydmVyLCBlZy4gV2F0ZXIgbWV0ZXIgZGF0YS4gClRoZXJlIGFyZSBzZXZlcmFsIG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlIGRpcmVjdGlvbiBiYXNlZCBvbiB0aGUgbmVnb3RpYXRpb24gYmV0d2VlbiBBcHBsaWNhdGlvbiBhbmQgTHdNMk0uIFRoZSBDbGllbnQgYW5kIFNlcnZlciBzaG91bGQgbmVnb3RpYXRlIHRoZSBpbnN0YW5jZShzKSB1c2VkIHRvIGV4Y2hhbmdlIHRoZSBkYXRhLiBGb3IgZXhhbXBsZToKIC0gVXNpbmcgYSBzaW5nbGUgaW5zdGFuY2UgZm9yIGJvdGggZGlyZWN0aW9ucyBjb21tdW5pY2F0aW9uLCBmcm9tIENsaWVudCB0byBTZXJ2ZXIgYW5kIGZyb20gU2VydmVyIHRvIENsaWVudC4KIC0gVXNpbmcgYW4gaW5zdGFuY2UgZm9yIGNvbW11bmljYXRpb24gZnJvbSBDbGllbnQgdG8gU2VydmVyIGFuZCBhbm90aGVyIG9uZSBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIFNlcnZlciB0byBDbGllbnQKIC0gVXNpbmcgc2V2ZXJhbCBpbnN0YW5jZXMKXV0+PC9EZXNjcmlwdGlvbjE+CgkJPE9iamVjdElEPjE5PC9PYmplY3RJRD4KCQk8T2JqZWN0VVJOPnVybjpvbWE6bHdtMm06b21hOjE5PC9PYmplY3RVUk4+CgkJPExXTTJNVmVyc2lvbj4xLjA8L0xXTTJNVmVyc2lvbj4KCQk8T2JqZWN0VmVyc2lvbj4xLjA8L09iamVjdFZlcnNpb24+CgkJPE11bHRpcGxlSW5zdGFuY2VzPk11bHRpcGxlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJPFJlc291cmNlcz4KCQkJPEl0ZW0gSUQ9IjAiPjxOYW1lPkRhdGE8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5NdWx0aXBsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk1hbmRhdG9yeTwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+T3BhcXVlPC9UeXBlPgoJCQkJPFJhbmdlRW51bWVyYXRpb24gLz4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZW50Ll1dPjwvRGVzY3JpcHRpb24+CgkJCTwvSXRlbT4KCQkJPEl0ZW0gSUQ9IjEiPjxOYW1lPkRhdGEgUHJpb3JpdHk8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5TaW5nbGU8L011bHRpcGxlSW5zdGFuY2VzPgoJCQkJPE1hbmRhdG9yeT5PcHRpb25hbDwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+SW50ZWdlcjwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjEgYnl0ZXM8L1JhbmdlRW51bWVyYXRpb24+CgkJCQk8VW5pdHMgLz4KCQkJCTxEZXNjcmlwdGlvbj48IVtDREFUQVtJbmRpY2F0ZXMgdGhlIEFwcGxpY2F0aW9uIGRhdGEgcHJpb3JpdHk6CjA6SW1tZWRpYXRlCjE6QmVzdEVmZm9ydAoyOkxhdGVzdAozLTEwMDogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCjEwMS0yNTQ6IFByb3ByaWV0YXJ5IG1vZGUuXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iMiI+PE5hbWU+RGF0YSBDcmVhdGlvbiBUaW1lPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlRpbWU8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbiAvPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBEYXRhIGluc3RhbmNlIGNyZWF0aW9uIHRpbWVzdGFtcC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSIzIj48TmFtZT5EYXRhIERlc2NyaXB0aW9uPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlN0cmluZzwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjMyIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkYXRhIGRlc2NyaXB0aW9uLgplLmcuICJtZXRlciByZWFkaW5nIi5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSI0Ij48TmFtZT5EYXRhIEZvcm1hdDwvTmFtZT4KCQkJCTxPcGVyYXRpb25zPlJXPC9PcGVyYXRpb25zPgoJCQkJPE11bHRpcGxlSW5zdGFuY2VzPlNpbmdsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJCQk8VHlwZT5TdHJpbmc8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4zMiBieXRlczwvUmFuZ2VFbnVtZXJhdGlvbj4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgZm9ybWF0IG9mIHRoZSBBcHBsaWNhdGlvbiBEYXRhLgplLmcuIFlHLU1ldGVyLVdhdGVyLVJlYWRpbmcKVVRGOC1zdHJpbmcKXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iNSI+PE5hbWU+QXBwIElEPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPkludGVnZXI8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4yIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkZXN0aW5hdGlvbiBBcHBsaWNhdGlvbiBJRC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+PC9SZXNvdXJjZXM+CgkJPERlc2NyaXB0aW9uMj48IVtDREFUQVtdXT48L0Rlc2NyaXB0aW9uMj4KCTwvT2JqZWN0Pgo8L0xXTTJNPgo=", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource data.", example = "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLQpGSUxFIElORk9STUFUSU9OCgpPTUEgUGVybWFuZW50IERvY3VtZW50CiAgIEZpbGU6IE9NQS1TVVAtTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci1WMV8wXzEtMjAxOTAyMjEtQQogICBUeXBlOiB4bWwKClB1YmxpYyBSZWFjaGFibGUgSW5mb3JtYXRpb24KICAgUGF0aDogaHR0cDovL3d3dy5vcGVubW9iaWxlYWxsaWFuY2Uub3JnL3RlY2gvcHJvZmlsZXMKICAgTmFtZTogTHdNMk1fQmluYXJ5QXBwRGF0YUNvbnRhaW5lci12MV8wXzEueG1sCgpOT1JNQVRJVkUgSU5GT1JNQVRJT04KCiAgSW5mb3JtYXRpb24gYWJvdXQgdGhpcyBmaWxlIGNhbiBiZSBmb3VuZCBpbiB0aGUgbGF0ZXN0IHJldmlzaW9uIG9mCgogIE9NQS1UUy1MV00yTV9CaW5hcnlBcHBEYXRhQ29udGFpbmVyLVYxXzBfMQoKICBUaGlzIGlzIGF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm9wZW5tb2JpbGVhbGxpYW5jZS5vcmcvCgogIFNlbmQgY29tbWVudHMgdG8gaHR0cHM6Ly9naXRodWIuY29tL09wZW5Nb2JpbGVBbGxpYW5jZS9PTUFfTHdNMk1fZm9yX0RldmVsb3BlcnMvaXNzdWVzCgpDSEFOR0UgSElTVE9SWQoKMTUwNjIwMTggU3RhdHVzIGNoYW5nZWQgdG8gQXBwcm92ZWQgYnkgRE0sIERvYyBSZWYgIyBPTUEtRE0mU0UtMjAxOC0wMDYxLUlOUF9MV00yTV9BUFBEQVRBX1YxXzBfRVJQX2Zvcl9maW5hbF9BcHByb3ZhbAoyMTAyMjAxOSBTdGF0dXMgY2hhbmdlZCB0byBBcHByb3ZlZCBieSBJUFNPLCBEb2MgUmVmICMgT01BLUlQU08tMjAxOS0wMDI1LUlOUF9Md00yTV9PYmplY3RfQXBwX0RhdGFfQ29udGFpbmVyXzFfMF8xX2Zvcl9GaW5hbF9BcHByb3ZhbAoKTEVHQUwgRElTQ0xBSU1FUgoKQ29weXJpZ2h0IDIwMTkgT3BlbiBNb2JpbGUgQWxsaWFuY2UuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCmFyZSBtZXQ6CgoxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodApub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCjIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0Cm5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cwpjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQKZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgoKVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwoiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVApMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUwpGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpDT1BZUklHSFQgSE9MREVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULApJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLApCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7CkxPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIKQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCkxJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOCkFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRQpQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KClRoZSBhYm92ZSBsaWNlbnNlIGlzIHVzZWQgYXMgYSBsaWNlbnNlIHVuZGVyIGNvcHlyaWdodCBvbmx5LiBQbGVhc2UKcmVmZXJlbmNlIHRoZSBPTUEgSVBSIFBvbGljeSBmb3IgcGF0ZW50IGxpY2Vuc2luZyB0ZXJtczoKaHR0cHM6Ly93d3cub21hc3BlY3dvcmtzLm9yZy9hYm91dC9pbnRlbGxlY3R1YWwtcHJvcGVydHktcmlnaHRzLwoKLS0+CjxMV00yTSB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6bm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbj0iaHR0cDovL29wZW5tb2JpbGVhbGxpYW5jZS5vcmcvdGVjaC9wcm9maWxlcy9MV00yTS54c2QiPgoJPE9iamVjdCBPYmplY3RUeXBlPSJNT0RlZmluaXRpb24iPgoJCTxOYW1lPkJpbmFyeUFwcERhdGFDb250YWluZXI8L05hbWU+CgkJPERlc2NyaXB0aW9uMT48IVtDREFUQVtUaGlzIEx3TTJNIE9iamVjdHMgcHJvdmlkZXMgdGhlIGFwcGxpY2F0aW9uIHNlcnZpY2UgZGF0YSByZWxhdGVkIHRvIGEgTHdNMk0gU2VydmVyLCBlZy4gV2F0ZXIgbWV0ZXIgZGF0YS4gClRoZXJlIGFyZSBzZXZlcmFsIG1ldGhvZHMgdG8gY3JlYXRlIGluc3RhbmNlIHRvIGluZGljYXRlIHRoZSBtZXNzYWdlIGRpcmVjdGlvbiBiYXNlZCBvbiB0aGUgbmVnb3RpYXRpb24gYmV0d2VlbiBBcHBsaWNhdGlvbiBhbmQgTHdNMk0uIFRoZSBDbGllbnQgYW5kIFNlcnZlciBzaG91bGQgbmVnb3RpYXRlIHRoZSBpbnN0YW5jZShzKSB1c2VkIHRvIGV4Y2hhbmdlIHRoZSBkYXRhLiBGb3IgZXhhbXBsZToKIC0gVXNpbmcgYSBzaW5nbGUgaW5zdGFuY2UgZm9yIGJvdGggZGlyZWN0aW9ucyBjb21tdW5pY2F0aW9uLCBmcm9tIENsaWVudCB0byBTZXJ2ZXIgYW5kIGZyb20gU2VydmVyIHRvIENsaWVudC4KIC0gVXNpbmcgYW4gaW5zdGFuY2UgZm9yIGNvbW11bmljYXRpb24gZnJvbSBDbGllbnQgdG8gU2VydmVyIGFuZCBhbm90aGVyIG9uZSBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIFNlcnZlciB0byBDbGllbnQKIC0gVXNpbmcgc2V2ZXJhbCBpbnN0YW5jZXMKXV0+PC9EZXNjcmlwdGlvbjE+CgkJPE9iamVjdElEPjE5PC9PYmplY3RJRD4KCQk8T2JqZWN0VVJOPnVybjpvbWE6bHdtMm06b21hOjE5PC9PYmplY3RVUk4+CgkJPExXTTJNVmVyc2lvbj4xLjA8L0xXTTJNVmVyc2lvbj4KCQk8T2JqZWN0VmVyc2lvbj4xLjA8L09iamVjdFZlcnNpb24+CgkJPE11bHRpcGxlSW5zdGFuY2VzPk11bHRpcGxlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJPFJlc291cmNlcz4KCQkJPEl0ZW0gSUQ9IjAiPjxOYW1lPkRhdGE8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5NdWx0aXBsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk1hbmRhdG9yeTwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+T3BhcXVlPC9UeXBlPgoJCQkJPFJhbmdlRW51bWVyYXRpb24gLz4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgYXBwbGljYXRpb24gZGF0YSBjb250ZW50Ll1dPjwvRGVzY3JpcHRpb24+CgkJCTwvSXRlbT4KCQkJPEl0ZW0gSUQ9IjEiPjxOYW1lPkRhdGEgUHJpb3JpdHk8L05hbWU+CgkJCQk8T3BlcmF0aW9ucz5SVzwvT3BlcmF0aW9ucz4KCQkJCTxNdWx0aXBsZUluc3RhbmNlcz5TaW5nbGU8L011bHRpcGxlSW5zdGFuY2VzPgoJCQkJPE1hbmRhdG9yeT5PcHRpb25hbDwvTWFuZGF0b3J5PgoJCQkJPFR5cGU+SW50ZWdlcjwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjEgYnl0ZXM8L1JhbmdlRW51bWVyYXRpb24+CgkJCQk8VW5pdHMgLz4KCQkJCTxEZXNjcmlwdGlvbj48IVtDREFUQVtJbmRpY2F0ZXMgdGhlIEFwcGxpY2F0aW9uIGRhdGEgcHJpb3JpdHk6CjA6SW1tZWRpYXRlCjE6QmVzdEVmZm9ydAoyOkxhdGVzdAozLTEwMDogUmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UuCjEwMS0yNTQ6IFByb3ByaWV0YXJ5IG1vZGUuXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iMiI+PE5hbWU+RGF0YSBDcmVhdGlvbiBUaW1lPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlRpbWU8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbiAvPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBEYXRhIGluc3RhbmNlIGNyZWF0aW9uIHRpbWVzdGFtcC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSIzIj48TmFtZT5EYXRhIERlc2NyaXB0aW9uPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPlN0cmluZzwvVHlwZT4KCQkJCTxSYW5nZUVudW1lcmF0aW9uPjMyIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkYXRhIGRlc2NyaXB0aW9uLgplLmcuICJtZXRlciByZWFkaW5nIi5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+CgkJCTxJdGVtIElEPSI0Ij48TmFtZT5EYXRhIEZvcm1hdDwvTmFtZT4KCQkJCTxPcGVyYXRpb25zPlJXPC9PcGVyYXRpb25zPgoJCQkJPE11bHRpcGxlSW5zdGFuY2VzPlNpbmdsZTwvTXVsdGlwbGVJbnN0YW5jZXM+CgkJCQk8TWFuZGF0b3J5Pk9wdGlvbmFsPC9NYW5kYXRvcnk+CgkJCQk8VHlwZT5TdHJpbmc8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4zMiBieXRlczwvUmFuZ2VFbnVtZXJhdGlvbj4KCQkJCTxVbml0cyAvPgoJCQkJPERlc2NyaXB0aW9uPjwhW0NEQVRBW0luZGljYXRlcyB0aGUgZm9ybWF0IG9mIHRoZSBBcHBsaWNhdGlvbiBEYXRhLgplLmcuIFlHLU1ldGVyLVdhdGVyLVJlYWRpbmcKVVRGOC1zdHJpbmcKXV0+PC9EZXNjcmlwdGlvbj4KCQkJPC9JdGVtPgoJCQk8SXRlbSBJRD0iNSI+PE5hbWU+QXBwIElEPC9OYW1lPgoJCQkJPE9wZXJhdGlvbnM+Ulc8L09wZXJhdGlvbnM+CgkJCQk8TXVsdGlwbGVJbnN0YW5jZXM+U2luZ2xlPC9NdWx0aXBsZUluc3RhbmNlcz4KCQkJCTxNYW5kYXRvcnk+T3B0aW9uYWw8L01hbmRhdG9yeT4KCQkJCTxUeXBlPkludGVnZXI8L1R5cGU+CgkJCQk8UmFuZ2VFbnVtZXJhdGlvbj4yIGJ5dGVzPC9SYW5nZUVudW1lcmF0aW9uPgoJCQkJPFVuaXRzIC8+CgkJCQk8RGVzY3JpcHRpb24+PCFbQ0RBVEFbSW5kaWNhdGVzIHRoZSBkZXN0aW5hdGlvbiBBcHBsaWNhdGlvbiBJRC5dXT48L0Rlc2NyaXB0aW9uPgoJCQk8L0l0ZW0+PC9SZXNvdXJjZXM+CgkJPERlc2NyaXB0aW9uMj48IVtDREFUQVtdXT48L0Rlc2NyaXB0aW9uMj4KCTwvT2JqZWN0Pgo8L0xXTTJNPgo=", accessMode = Schema.AccessMode.READ_ONLY) private String data; public TbResource() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java index 331958ac58..f3e8f1bf8f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -26,7 +25,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Slf4j @Data @EqualsAndHashCode(callSuper = true) @@ -34,19 +33,19 @@ public class TbResourceInfo extends BaseData implements HasName, H private static final long serialVersionUID = 7282664529021651736L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Tenant Id of the resource can't be changed.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Tenant Id of the resource can't be changed.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "title") - @ApiModelProperty(position = 4, value = "Resource title.", example = "BinaryAppDataContainer id=19 v1.0") + @Schema(description = "Resource title.", example = "BinaryAppDataContainer id=19 v1.0") private String title; - @ApiModelProperty(position = 5, value = "Resource type.", example = "LWM2M_MODEL", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource type.", example = "LWM2M_MODEL", accessMode = Schema.AccessMode.READ_ONLY) private ResourceType resourceType; @NoXss @Length(fieldName = "resourceKey") - @ApiModelProperty(position = 6, value = "Resource key.", example = "19_1.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource key.", example = "19_1.0", accessMode = Schema.AccessMode.READ_ONLY) private String resourceKey; - @ApiModelProperty(position = 7, value = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Resource search text.", example = "19_1.0:binaryappdatacontainer", accessMode = Schema.AccessMode.READ_ONLY) private String searchText; public TbResourceInfo() { @@ -66,7 +65,7 @@ public class TbResourceInfo extends BaseData implements HasName, H this.searchText = resourceInfo.getSearchText(); } - @ApiModelProperty(position = 1, value = "JSON object with the Resource Id. " + + @Schema(description = "JSON object with the Resource Id. " + "Specify this field to update the Resource. " + "Referencing non-existing Resource Id will cause error. " + "Omit this field to create new Resource." ) @@ -75,7 +74,7 @@ public class TbResourceInfo extends BaseData implements HasName, H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the resource creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the resource creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java index 89cd9ec467..d01cc3aa41 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java @@ -18,15 +18,14 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class Tenant extends ContactBased implements HasTenantId, HasTitle { @@ -34,14 +33,14 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi @Length(fieldName = "title") @NoXss - @ApiModelProperty(position = 3, value = "Title of the tenant", example = "Company A") + @Schema(description = "Title of the tenant", example = "Company A") private String title; @NoXss @Length(fieldName = "region") - @ApiModelProperty(position = 5, value = "Geo region of the tenant", example = "North America") + @Schema(description = "Geo region of the tenant", example = "North America") private String region; - @ApiModelProperty(position = 6, required = true, value = "JSON object with Tenant Profile Id") + @Schema(required = true, description = "JSON object with Tenant Profile Id") private TenantProfileId tenantProfileId; public Tenant() { @@ -74,7 +73,7 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi } @Override - @ApiModelProperty(position = 4, value = "Name of the tenant. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the tenant. Read-only, duplicated from title for backward compatibility", example = "Company A", accessMode = Schema.AccessMode.READ_ONLY) @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { return title; @@ -96,7 +95,7 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi this.tenantProfileId = tenantProfileId; } - @ApiModelProperty(position = 1, value = "JSON object with the tenant Id. " + + @Schema(description = "JSON object with the tenant Id. " + "Specify this field to update the tenant. " + "Referencing non-existing tenant Id will cause error. " + "Omit this field to create new tenant." ) @@ -105,61 +104,61 @@ public class Tenant extends ContactBased implements HasTenantId, HasTi return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the tenant creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the tenant creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 7, required = true, value = "Country", example = "US") + @Schema(required = true, description = "Country", example = "US") @Override public String getCountry() { return super.getCountry(); } - @ApiModelProperty(position = 8, required = true, value = "State", example = "NY") + @Schema(required = true, description = "State", example = "NY") @Override public String getState() { return super.getState(); } - @ApiModelProperty(position = 9, required = true, value = "City", example = "New York") + @Schema(required = true, description = "City", example = "New York") @Override public String getCity() { return super.getCity(); } - @ApiModelProperty(position = 10, required = true, value = "Address Line 1", example = "42 Broadway Suite 12-400") + @Schema(required = true, description = "Address Line 1", example = "42 Broadway Suite 12-400") @Override public String getAddress() { return super.getAddress(); } - @ApiModelProperty(position = 11, required = true, value = "Address Line 2", example = "") + @Schema(required = true, description = "Address Line 2", example = "") @Override public String getAddress2() { return super.getAddress2(); } - @ApiModelProperty(position = 12, required = true, value = "Zip code", example = "10004") + @Schema(required = true, description = "Zip code", example = "10004") @Override public String getZip() { return super.getZip(); } - @ApiModelProperty(position = 13, required = true, value = "Phone number", example = "+1(415)777-7777") + @Schema(required = true, description = "Phone number", example = "+1(415)777-7777") @Override public String getPhone() { return super.getPhone(); } - @ApiModelProperty(position = 14, required = true, value = "Email", example = "example@company.com") + @Schema(required = true, description = "Email", example = "example@company.com") @Override public String getEmail() { return super.getEmail(); } - @ApiModelProperty(position = 15, value = "Additional parameters of the device", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the device",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java index e98e14d2d0..fd7ca7fc7f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantInfo.java @@ -15,15 +15,14 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.TenantId; -@ApiModel +@Schema @Data public class TenantInfo extends Tenant { - @ApiModelProperty(position = 15, value = "Tenant Profile name", example = "Default") + @Schema(description = "Tenant Profile name", example = "Default") private String tenantProfileName; public TenantInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java index 5ce6c00fb8..d4b5f51e77 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TenantProfile.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -34,7 +33,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Optional; -@ApiModel +@Schema @Data @ToString(exclude = {"profileDataBytes"}) @EqualsAndHashCode(callSuper = true) @@ -47,17 +46,17 @@ public class TenantProfile extends BaseData implements HasName @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 3, value = "Name of the tenant profile", example = "High Priority Tenants") + @Schema(description = "Name of the tenant profile", example = "High Priority Tenants") private String name; @NoXss - @ApiModelProperty(position = 4, value = "Description of the tenant profile", example = "Any text") + @Schema(description = "Description of the tenant profile", example = "Any text") private String description; - @ApiModelProperty(position = 5, value = "Default Tenant profile to be used.", example = "true") + @Schema(description = "Default Tenant profile to be used.", example = "true") private boolean isDefault; - @ApiModelProperty(position = 6, value = "If enabled, will push all messages related to this tenant and processed by the rule engine into separate queue. " + + @Schema(description = "If enabled, will push all messages related to this tenant and processed by the rule engine into separate queue. " + "Useful for complex microservices deployments, to isolate processing of the data for specific tenants", example = "true") private boolean isolatedTbRuleEngine; - @ApiModelProperty(position = 7, value = "Complex JSON object that contains profile settings: queue configs, max devices, max assets, rate limits, etc.") + @Schema(description = "Complex JSON object that contains profile settings: queue configs, max devices, max assets, rate limits, etc.") private transient TenantProfileData profileData; @JsonIgnore private byte[] profileDataBytes; @@ -79,7 +78,7 @@ public class TenantProfile extends BaseData implements HasName this.setProfileData(tenantProfile.getProfileData()); } - @ApiModelProperty(position = 1, value = "JSON object with the tenant profile Id. " + + @Schema(description = "JSON object with the tenant profile Id. " + "Specify this field to update the tenant profile. " + "Referencing non-existing tenant profile Id will cause error. " + "Omit this field to create new tenant profile.") @@ -88,7 +87,7 @@ public class TenantProfile extends BaseData implements HasName return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the tenant profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the tenant profile creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java b/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java index 43210de9d0..522ef80c53 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UpdateMessage.java @@ -15,27 +15,26 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class UpdateMessage implements Serializable { - @ApiModelProperty(position = 1, value = "'True' if new platform update is available.") + @Schema(description = "'True' if new platform update is available.") private final boolean updateAvailable; - @ApiModelProperty(position = 2, value = "Current ThingsBoard version.") + @Schema(description = "Current ThingsBoard version.") private final String currentVersion; - @ApiModelProperty(position = 3, value = "Latest ThingsBoard version.") + @Schema(description = "Latest ThingsBoard version.") private final String latestVersion; - @ApiModelProperty(position = 4, value = "Upgrade instructions URL.") + @Schema(description = "Upgrade instructions URL.") private final String upgradeInstructionsUrl; - @ApiModelProperty(position = 5, value = "Current ThingsBoard version release notes URL.") + @Schema(description = "Current ThingsBoard version release notes URL.") private final String currentVersionReleaseNotesUrl; - @ApiModelProperty(position = 6, value = "Latest ThingsBoard version release notes URL.") + @Schema(description = "Latest ThingsBoard version release notes URL.") private final String latestVersionReleaseNotesUrl; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/User.java b/common/data/src/main/java/org/thingsboard/server/common/data/User.java index b3d9268c6b..15bc41f22c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/User.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/User.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; @@ -32,7 +31,7 @@ import org.thingsboard.server.common.data.validation.NoXss; import static org.apache.commons.lang3.StringUtils.isNotEmpty; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class User extends BaseDataWithAdditionalInfo implements HasName, HasTenantId, HasCustomerId, NotificationRecipient { @@ -71,7 +70,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, } - @ApiModelProperty(position = 1, value = "JSON object with the User Id. " + + @Schema(description = "JSON object with the User Id. " + "Specify this field to update the device. " + "Referencing non-existing User Id will cause error. " + "Omit this field to create new customer.") @@ -80,13 +79,13 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the user creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the user creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with the Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -95,7 +94,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } @@ -104,7 +103,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.customerId = customerId; } - @ApiModelProperty(position = 5, required = true, value = "Email of the user", example = "user@example.com") + @Schema(required = true, description = "Email of the user", example = "user@example.com") public String getEmail() { return email; } @@ -113,14 +112,14 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.email = email; } - @ApiModelProperty(position = 6, accessMode = ApiModelProperty.AccessMode.READ_ONLY, value = "Duplicates the email of the user, readonly", example = "user@example.com") + @Schema(accessMode = Schema.AccessMode.READ_ONLY, description = "Duplicates the email of the user, readonly", example = "user@example.com") @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { return email; } - @ApiModelProperty(position = 7, required = true, value = "Authority", example = "SYS_ADMIN, TENANT_ADMIN or CUSTOMER_USER") + @Schema(required = true, description = "Authority", example = "SYS_ADMIN, TENANT_ADMIN or CUSTOMER_USER") public Authority getAuthority() { return authority; } @@ -129,7 +128,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.authority = authority; } - @ApiModelProperty(position = 8, required = true, value = "First name of the user", example = "John") + @Schema(required = true, description = "First name of the user", example = "John") public String getFirstName() { return firstName; } @@ -138,7 +137,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.firstName = firstName; } - @ApiModelProperty(position = 9, required = true, value = "Last name of the user", example = "Doe") + @Schema(required = true, description = "Last name of the user", example = "Doe") public String getLastName() { return lastName; } @@ -147,7 +146,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.lastName = lastName; } - @ApiModelProperty(position = 10, required = true, value = "Phone number of the user", example = "38012345123") + @Schema(required = true, description = "Phone number of the user", example = "38012345123") public String getPhone() { return phone; } @@ -156,7 +155,7 @@ public class User extends BaseDataWithAdditionalInfo implements HasName, this.phone = phone; } - @ApiModelProperty(position = 11, value = "Additional parameters of the user", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the user", implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java index f1eb95c805..644144efa5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java @@ -15,25 +15,24 @@ */ package org.thingsboard.server.common.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.UserId; -@ApiModel +@Schema @Data @AllArgsConstructor public class UserEmailInfo implements HasId { - @ApiModelProperty(position = 1, value = "User id") + @Schema(description = "User id") private UserId id; - @ApiModelProperty(position = 2, value = "User email", example = "john@gmail.com") + @Schema(description = "User email", example = "john@gmail.com") private String email; - @ApiModelProperty(position = 3, value = "User first name", example = "John") + @Schema(description = "User first name", example = "John") private String firstName; - @ApiModelProperty(position = 4, value = "User last name", example = "Brown") + @Schema(description = "User last name", example = "Brown") private String lastName; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java index 34fec2cd82..222570e914 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -41,7 +40,7 @@ import java.util.List; /** * Created by ashvayka on 11.05.17. */ -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @Builder @@ -49,45 +48,45 @@ import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) public class Alarm extends BaseData implements HasName, HasTenantId, HasCustomerId { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id", accessMode = Schema.AccessMode.READ_ONLY) private CustomerId customerId; @NoXss - @ApiModelProperty(position = 6, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") + @Schema(required = true, description = "representing type of the Alarm", example = "High Temperature Alarm") @Length(fieldName = "type") private String type; - @ApiModelProperty(position = 7, required = true, value = "JSON object with alarm originator id") + @Schema(required = true, description = "JSON object with alarm originator id") private EntityId originator; - @ApiModelProperty(position = 8, required = true, value = "Alarm severity", example = "CRITICAL") + @Schema(required = true, description = "Alarm severity", example = "CRITICAL") private AlarmSeverity severity; - @ApiModelProperty(position = 9, required = true, value = "Acknowledged", example = "true") + @Schema(required = true, description = "Acknowledged", example = "true") private boolean acknowledged; - @ApiModelProperty(position = 10, required = true, value = "Cleared", example = "false") + @Schema(required = true, description = "Cleared", example = "false") private boolean cleared; - @ApiModelProperty(position = 11, value = "Alarm assignee user id") + @Schema(description = "Alarm assignee user id") private UserId assigneeId; - @ApiModelProperty(position = 12, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") + @Schema(description = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") private long startTs; - @ApiModelProperty(position = 13, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") + @Schema(description = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") private long endTs; - @ApiModelProperty(position = 14, value = "Timestamp of the alarm acknowledgement, in milliseconds", example = "1634115221948") + @Schema(description = "Timestamp of the alarm acknowledgement, in milliseconds", example = "1634115221948") private long ackTs; - @ApiModelProperty(position = 15, value = "Timestamp of the alarm clearing, in milliseconds", example = "1634114528465") + @Schema(description = "Timestamp of the alarm clearing, in milliseconds", example = "1634114528465") private long clearTs; - @ApiModelProperty(position = 16, value = "Timestamp of the alarm assignment, in milliseconds", example = "1634115928465") + @Schema(description = "Timestamp of the alarm assignment, in milliseconds", example = "1634115928465") private long assignTs; - @ApiModelProperty(position = 17, value = "JSON object with alarm details") + @Schema(description = "JSON object with alarm details") private transient JsonNode details; - @ApiModelProperty(position = 18, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") private boolean propagate; - @ApiModelProperty(position = 19, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") private boolean propagateToOwner; - @ApiModelProperty(position = 20, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") private boolean propagateToTenant; - @ApiModelProperty(position = 21, value = "JSON array of relation types that should be used for propagation. " + + @Schema(description = "JSON array of relation types that should be used for propagation. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") private List propagateRelationTypes; @@ -125,12 +124,12 @@ public class Alarm extends BaseData implements HasName, HasTenantId, Ha @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @ApiModelProperty(position = 5, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") + @Schema(required = true, description = "representing type of the Alarm", example = "High Temperature Alarm") public String getName() { return type; } - @ApiModelProperty(position = 1, value = "JSON object with the alarm Id. " + + @Schema(description = "JSON object with the alarm Id. " + "Specify this field to update the alarm. " + "Referencing non-existing alarm Id will cause error. " + "Omit this field to create new alarm.") @@ -140,14 +139,14 @@ public class Alarm extends BaseData implements HasName, HasTenantId, Ha } - @ApiModelProperty(position = 2, value = "Timestamp of the alarm creation, in milliseconds", example = "1634058704567", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the alarm creation, in milliseconds", example = "1634058704567", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @ApiModelProperty(position = 22, required = true, value = "status of the Alarm", example = "ACTIVE_UNACK", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "status of the Alarm", example = "ACTIVE_UNACK", accessMode = Schema.AccessMode.READ_ONLY) public AlarmStatus getStatus() { return toStatus(cleared, acknowledged); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java index 982e0f94d1..0ed046311f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmComment.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,23 +29,23 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @Builder @AllArgsConstructor public class AlarmComment extends BaseData implements HasName { - @ApiModelProperty(position = 3, value = "JSON object with Alarm id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Alarm id.", accessMode = Schema.AccessMode.READ_ONLY) private EntityId alarmId; - @ApiModelProperty(position = 4, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with User id.", accessMode = Schema.AccessMode.READ_ONLY) private UserId userId; - @ApiModelProperty(position = 5, value = "Defines origination of comment. System type means comment was created by TB. OTHER type means comment was created by user.", example = "SYSTEM/OTHER", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Defines origination of comment. System type means comment was created by TB. OTHER type means comment was created by user.", example = "SYSTEM/OTHER", accessMode = Schema.AccessMode.READ_ONLY) private AlarmCommentType type; - @ApiModelProperty(position = 6, value = "JSON object with text of comment.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "JSON object with text of comment.",implementation = com.fasterxml.jackson.databind.JsonNode.class) @NoXss @Length(fieldName = "comment", max = 10000) private transient JsonNode comment; - @ApiModelProperty(position = 1, value = "JSON object with the alarm comment Id. " + + @Schema(description = "JSON object with the alarm comment Id. " + "Specify this field to update the alarm comment. " + "Referencing non-existing alarm Id will cause error. " + "Omit this field to create new alarm." ) @@ -55,7 +54,7 @@ public class AlarmComment extends BaseData implements HasName { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the alarm comment creation, in milliseconds", example = "1634058704567", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the alarm comment creation, in milliseconds", example = "1634058704567", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); @@ -71,7 +70,7 @@ public class AlarmComment extends BaseData implements HasName { @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) - @ApiModelProperty(position = 5, required = true, value = "representing comment text", example = "Please take a look") + @Schema(required = true, description = "representing comment text", example = "Please take a look") public String getName() { return comment.toString(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java index e84cb78697..b68f771621 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentInfo.java @@ -15,24 +15,23 @@ */ package org.thingsboard.server.common.data.alarm; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class AlarmCommentInfo extends AlarmComment { private static final long serialVersionUID = 2807343093519543377L; - @ApiModelProperty(position = 19, value = "User first name", example = "John") + @Schema(description = "User first name", example = "John") private String firstName; - @ApiModelProperty(position = 19, value = "User last name", example = "Brown") + @Schema(description = "User last name", example = "Brown") private String lastName; - @ApiModelProperty(position = 19, value = "User email address", example = "johnBrown@gmail.com") + @Schema(description = "User email address", example = "johnBrown@gmail.com") private String email; public AlarmCommentInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java index 1c71e66b87..ea4649bcd6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCreateOrUpdateActiveRequest.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.id.AlarmId; @@ -35,29 +35,29 @@ import jakarta.validation.constraints.NotNull; public class AlarmCreateOrUpdateActiveRequest implements AlarmModificationRequest { @NotNull - @ApiModelProperty(position = 1, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 2, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id", accessMode = Schema.AccessMode.READ_ONLY) private CustomerId customerId; @NotNull - @ApiModelProperty(position = 3, required = true, value = "representing type of the Alarm", example = "High Temperature Alarm") + @Schema(required = true, description = "representing type of the Alarm", example = "High Temperature Alarm") @Length(fieldName = "type") private String type; @NotNull - @ApiModelProperty(position = 4, required = true, value = "JSON object with alarm originator id") + @Schema(required = true, description = "JSON object with alarm originator id") private EntityId originator; @NotNull - @ApiModelProperty(position = 5, required = true, value = "Alarm severity", example = "CRITICAL") + @Schema(required = true, description = "Alarm severity", example = "CRITICAL") private AlarmSeverity severity; - @ApiModelProperty(position = 6, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") + @Schema(description = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") private long startTs; - @ApiModelProperty(position = 7, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") + @Schema(description = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") private long endTs; @NoXss - @ApiModelProperty(position = 8, value = "JSON object with alarm details") + @Schema(description = "JSON object with alarm details") private JsonNode details; @Valid - @ApiModelProperty(position = 9, value = "JSON object with propagation details") + @Schema(description = "JSON object with propagation details") private AlarmPropagationInfo propagation; private UserId userId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java index 9086c4aa7b..61e53044ad 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.alarm; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -24,24 +23,24 @@ import lombok.ToString; @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -@ApiModel +@Schema public class AlarmInfo extends Alarm { private static final long serialVersionUID = 2807343093519543363L; @Getter @Setter - @ApiModelProperty(position = 19, value = "Alarm originator name", example = "Thermostat") + @Schema(description = "Alarm originator name", example = "Thermostat") private String originatorName; @Getter @Setter - @ApiModelProperty(position = 20, value = "Alarm originator label", example = "Thermostat label") + @Schema(description = "Alarm originator label", example = "Thermostat label") private String originatorLabel; @Getter @Setter - @ApiModelProperty(position = 21, value = "Alarm assignee") + @Schema(description = "Alarm assignee") private AlarmAssignee assignee; public AlarmInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java index 8ba744a85e..49ad2c4ded 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmPropagationInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.alarm; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.validation.NoXss; @@ -29,14 +29,14 @@ public class AlarmPropagationInfo { public static AlarmPropagationInfo EMPTY = new AlarmPropagationInfo(false, false, false, Collections.emptyList()); - @ApiModelProperty(position = 1, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") private boolean propagate; - @ApiModelProperty(position = 2, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") private boolean propagateToOwner; - @ApiModelProperty(position = 3, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") private boolean propagateToTenant; @NoXss - @ApiModelProperty(position = 4, value = "JSON array of relation types that should be used for propagation. " + + @Schema(description = "JSON array of relation types that should be used for propagation. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") private List propagateRelationTypes; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java index e97b40e1f1..06bacb50fc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmUpdateRequest.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data.alarm; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import org.thingsboard.server.common.data.id.AlarmId; @@ -32,26 +32,26 @@ import jakarta.validation.constraints.NotNull; public class AlarmUpdateRequest implements AlarmModificationRequest { @NotNull - @ApiModelProperty(position = 1, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NotNull - @ApiModelProperty(position = 2, value = "JSON object with the alarm Id. " + + @Schema(description = "JSON object with the alarm Id. " + "Specify this field to update the alarm. " + "Referencing non-existing alarm Id will cause error. " + "Omit this field to create new alarm.") private AlarmId alarmId; @NotNull - @ApiModelProperty(position = 3, required = true, value = "Alarm severity", example = "CRITICAL") + @Schema(required = true, description = "Alarm severity", example = "CRITICAL") private AlarmSeverity severity; - @ApiModelProperty(position = 4, value = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") + @Schema(description = "Timestamp of the alarm start time, in milliseconds", example = "1634058704565") private long startTs; - @ApiModelProperty(position = 5, value = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") + @Schema(description = "Timestamp of the alarm end time(last time update), in milliseconds", example = "1634111163522") private long endTs; @NoXss - @ApiModelProperty(position = 6, value = "JSON object with alarm details") + @Schema(description = "JSON object with alarm details") private JsonNode details; @Valid - @ApiModelProperty(position = 7, value = "JSON object with propagation details") + @Schema(description = "JSON object with propagation details") private AlarmPropagationInfo propagation; private UserId userId; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java index bbb56305db..49bcc15875 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.asset; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -35,7 +34,7 @@ import org.thingsboard.server.common.data.validation.NoXss; import java.util.Optional; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class Asset extends BaseDataWithAdditionalInfo implements HasLabel, HasTenantId, HasCustomerId, ExportableEntity { @@ -88,7 +87,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.externalId = asset.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the asset Id. " + + @Schema(description = "JSON object with the asset Id. " + "Specify this field to update the asset. " + "Referencing non-existing asset Id will cause error. " + "Omit this field to create new asset.") @@ -97,13 +96,13 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the asset creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the asset creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) public TenantId getTenantId() { return tenantId; } @@ -112,7 +111,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.tenantId = tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignAssetToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignAssetToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) public CustomerId getCustomerId() { return customerId; } @@ -121,7 +120,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.customerId = customerId; } - @ApiModelProperty(position = 5, required = true, value = "Unique Asset Name in scope of Tenant", example = "Empire State Building") + @Schema(required = true, description = "Unique Asset Name in scope of Tenant", example = "Empire State Building") @Override public String getName() { return name; @@ -131,7 +130,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.name = name; } - @ApiModelProperty(position = 6, required = true, value = "Asset type", example = "Building") + @Schema(required = true, description = "Asset type", example = "Building") public String getType() { return type; } @@ -140,7 +139,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.type = type; } - @ApiModelProperty(position = 7, required = true, value = "Label that may be used in widgets", example = "NY Building") + @Schema(required = true, description = "Label that may be used in widgets", example = "NY Building") public String getLabel() { return label; } @@ -149,7 +148,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.label = label; } - @ApiModelProperty(position = 8, required = true, value = "JSON object with Asset Profile Id.") + @Schema(required = true, description = "JSON object with Asset Profile Id.") public AssetProfileId getAssetProfileId() { return assetProfileId; } @@ -158,7 +157,7 @@ public class Asset extends BaseDataWithAdditionalInfo implements HasLab this.assetProfileId = assetProfileId; } - @ApiModelProperty(position = 9, value = "Additional parameters of the asset", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the asset",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java index b2d1fa95a2..08c084fde6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetInfo.java @@ -15,25 +15,24 @@ */ package org.thingsboard.server.common.data.asset; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.AssetId; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class AssetInfo extends Asset { private static final long serialVersionUID = -4094528227011066194L; - @ApiModelProperty(position = 10, value = "Title of the Customer that owns the asset.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title of the Customer that owns the asset.", accessMode = Schema.AccessMode.READ_ONLY) private String customerTitle; - @ApiModelProperty(position = 11, value = "Indicates special 'Public' Customer that is auto-generated to use the assets on public dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Indicates special 'Public' Customer that is auto-generated to use the assets on public dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private boolean customerIsPublic; - @ApiModelProperty(position = 12, value = "Name of the corresponding Asset Profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the corresponding Asset Profile.", accessMode = Schema.AccessMode.READ_ONLY) private String assetProfileName; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java index 5456ba36ce..f8acb0ef08 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfile.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.asset; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -34,7 +33,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @ToString(exclude = {"image"}) @EqualsAndHashCode(callSuper = true) @@ -43,33 +42,33 @@ public class AssetProfile extends BaseData implements HasName, H private static final long serialVersionUID = 6998485460273302018L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id that owns the profile.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id that owns the profile.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 4, value = "Unique Asset Profile Name in scope of Tenant.", example = "Building") + @Schema(description = "Unique Asset Profile Name in scope of Tenant.", example = "Building") private String name; @NoXss - @ApiModelProperty(position = 11, value = "Asset Profile description. ") + @Schema(description = "Asset Profile description. ") private String description; @Length(fieldName = "image", max = 1000000) - @ApiModelProperty(position = 12, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") private String image; private boolean isDefault; - @ApiModelProperty(position = 7, value = "Reference to the rule chain. " + + @Schema(description = "Reference to the rule chain. " + "If present, the specified rule chain will be used to process all messages related to asset, including asset updates, telemetry, attribute updates, etc. " + "Otherwise, the root rule chain will be used to process those messages.") private RuleChainId defaultRuleChainId; - @ApiModelProperty(position = 6, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") private DashboardId defaultDashboardId; @NoXss - @ApiModelProperty(position = 8, value = "Rule engine queue name. " + + @Schema(description = "Rule engine queue name. " + "If present, the specified queue will be used to store all unprocessed messages related to asset, including asset updates, telemetry, attribute updates, etc. " + "Otherwise, the 'Main' queue will be used to store those messages.") private String defaultQueueName; - @ApiModelProperty(position = 13, value = "Reference to the edge rule chain. " + + @Schema(description = "Reference to the edge rule chain. " + "If present, the specified edge rule chain will be used on the edge to process all messages related to asset, including asset updates, telemetry, attribute updates, etc. " + "Otherwise, the edge root rule chain will be used to process those messages.") private RuleChainId defaultEdgeRuleChainId; @@ -98,7 +97,7 @@ public class AssetProfile extends BaseData implements HasName, H this.externalId = assetProfile.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the asset profile Id. " + + @Schema(description = "JSON object with the asset profile Id. " + "Specify this field to update the asset profile. " + "Referencing non-existing asset profile Id will cause error. " + "Omit this field to create new asset profile.") @@ -107,13 +106,13 @@ public class AssetProfile extends BaseData implements HasName, H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the profile creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 5, value = "Used to mark the default profile. Default profile is used when the asset profile is not specified during asset creation.") + @Schema(description = "Used to mark the default profile. Default profile is used when the asset profile is not specified during asset creation.") public boolean isDefault(){ return isDefault; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java index e590c4c094..dc1adb1b63 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetProfileInfo.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.asset; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.ToString; import lombok.Value; @@ -35,12 +35,12 @@ import java.util.UUID; @ToString(callSuper = true, exclude = "image") public class AssetProfileInfo extends EntityInfo { - @ApiModelProperty(position = 3, value = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") + @Schema(description = "Either URL or Base64 data of the icon. Used in the mobile application to visualize set of asset profiles in the grid view. ") private final String image; - @ApiModelProperty(position = 4, value = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") + @Schema(description = "Reference to the dashboard. Used in the mobile application to open the default dashboard when user navigates to asset details.") private final DashboardId defaultDashboardId; - @ApiModelProperty(position = 5, value = "Tenant id.") + @Schema(description = "Tenant id.") private final TenantId tenantId; @JsonCreator diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java index aeb693b02c..c8a7be5df5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/AssetSearchQuery.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.asset; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -32,11 +32,11 @@ import java.util.List; @Data public class AssetSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and asset (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and asset (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of asset types to filter the related entities (e.g. 'Building', 'Vehicle').") + @Schema(description = "Array of asset types to filter the related entities (e.g. 'Building', 'Vehicle').") private List assetTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java b/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java index 5b6b68e622..5e95a54bb1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/audit/AuditLog.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.audit; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; @@ -28,31 +27,31 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) @Data public class AuditLog extends BaseData { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Customer Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id", accessMode = Schema.AccessMode.READ_ONLY) private CustomerId customerId; - @ApiModelProperty(position = 5, value = "JSON object with Entity id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Entity id", accessMode = Schema.AccessMode.READ_ONLY) private EntityId entityId; @NoXss - @ApiModelProperty(position = 6, value = "Name of the logged entity", example = "Thermometer", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Name of the logged entity", example = "Thermometer", accessMode = Schema.AccessMode.READ_ONLY) private String entityName; - @ApiModelProperty(position = 7, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with User id.", accessMode = Schema.AccessMode.READ_ONLY) private UserId userId; - @ApiModelProperty(position = 8, value = "Unique user name(email) of the user that performed some action on logged entity", example = "tenant@thingsboard.org", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Unique user name(email) of the user that performed some action on logged entity", example = "tenant@thingsboard.org", accessMode = Schema.AccessMode.READ_ONLY) private String userName; - @ApiModelProperty(position = 9, value = "String represented Action type", example = "ADDED", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "String represented Action type", example = "ADDED", accessMode = Schema.AccessMode.READ_ONLY) private ActionType actionType; - @ApiModelProperty(position = 10, value = "JsonNode represented action data", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JsonNode represented action data", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode actionData; - @ApiModelProperty(position = 11, value = "String represented Action status", example = "SUCCESS", allowableValues = "SUCCESS,FAILURE", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "String represented Action status", example = "SUCCESS", allowableValues = "SUCCESS,FAILURE", accessMode = Schema.AccessMode.READ_ONLY) private ActionStatus actionStatus; - @ApiModelProperty(position = 12, value = "Failure action details info. An empty string in case of action status type 'SUCCESS', otherwise includes stack trace of the caused exception.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Failure action details info. An empty string in case of action status type 'SUCCESS', otherwise includes stack trace of the caused exception.", accessMode = Schema.AccessMode.READ_ONLY) private String actionFailureDetails; public AuditLog() { @@ -77,13 +76,13 @@ public class AuditLog extends BaseData { this.actionFailureDetails = auditLog.getActionFailureDetails(); } - @ApiModelProperty(position = 2, value = "Timestamp of the auditLog creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the auditLog creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 1, value = "JSON object with the auditLog Id") + @Schema(description = "JSON object with the auditLog Id") @Override public AuditLogId getId() { return super.getId(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java index dbde84abbe..f3157c1571 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/DeviceSearchQuery.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -27,15 +26,15 @@ import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @Data public class DeviceSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of device types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") + @Schema(description = "Array of device types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") private List deviceTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java index 9e7c85e6f4..a5dd1919e1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DefaultDeviceConfiguration.java @@ -15,11 +15,11 @@ */ package org.thingsboard.server.common.data.device.data; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.DeviceProfileType; -@ApiModel +@Schema @Data public class DefaultDeviceConfiguration implements DeviceConfiguration { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java index 79793b0fd7..aa1cb8dff8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceConfiguration.java @@ -19,12 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.DeviceProfileType; import java.io.Serializable; -@ApiModel +@Schema @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java index 5ec461c271..b362231691 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceData.java @@ -15,21 +15,20 @@ */ package org.thingsboard.server.common.data.device.data; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class DeviceData implements Serializable { private static final long serialVersionUID = -3771567735290681274L; - @ApiModelProperty(position = 1, value = "Device configuration for device profile type. DEFAULT is only supported value for now") + @Schema(description = "Device configuration for device profile type. DEFAULT is only supported value for now") private DeviceConfiguration configuration; - @ApiModelProperty(position = 2, value = "Device transport configuration used to connect the device") + @Schema(description = "Device transport configuration used to connect the device") private DeviceTransportConfiguration transportConfiguration; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java index c5f385df4a..ace00a129f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/DeviceTransportConfiguration.java @@ -19,12 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.DeviceTransportType; import java.io.Serializable; -@ApiModel +@Schema @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java index a8b83a1cf6..3cb3ff99f1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmCondition.java @@ -16,23 +16,22 @@ package org.thingsboard.server.common.data.device.profile; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import jakarta.validation.Valid; import java.io.Serializable; import java.util.List; -@ApiModel +@Schema @Data @JsonIgnoreProperties(ignoreUnknown = true) public class AlarmCondition implements Serializable { @Valid - @ApiModelProperty(position = 1, value = "JSON array of alarm condition filters") + @Schema(description = "JSON array of alarm condition filters") private List condition; - @ApiModelProperty(position = 2, value = "JSON object representing alarm condition type") + @Schema(description = "JSON object representing alarm condition type") private AlarmConditionSpec spec; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java index 7a44d707f9..39360cdb3e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilter.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.query.EntityKeyValueType; import org.thingsboard.server.common.data.query.KeyFilterPredicate; @@ -25,20 +24,20 @@ import org.thingsboard.server.common.data.validation.NoXss; import jakarta.validation.Valid; import java.io.Serializable; -@ApiModel +@Schema @Data public class AlarmConditionFilter implements Serializable { @Valid - @ApiModelProperty(position = 1, value = "JSON object for specifying alarm condition by specific key") + @Schema(description = "JSON object for specifying alarm condition by specific key") private AlarmConditionFilterKey key; - @ApiModelProperty(position = 2, value = "String representation of the type of the value", example = "NUMERIC") + @Schema(description = "String representation of the type of the value", example = "NUMERIC") private EntityKeyValueType valueType; @NoXss - @ApiModelProperty(position = 3, value = "Value used in Constant comparison. For other types, such as TIME_SERIES or ATTRIBUTE, the predicate condition is used") + @Schema(description = "Value used in Constant comparison. For other types, such as TIME_SERIES or ATTRIBUTE, the predicate condition is used") private Object value; @Valid - @ApiModelProperty(position = 4, value = "JSON object representing filter condition") + @Schema(description = "JSON object representing filter condition") private KeyFilterPredicate predicate; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java index 58dcedc993..a4782fdbff 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmConditionFilterKey.java @@ -15,21 +15,20 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.validation.NoXss; import java.io.Serializable; -@ApiModel +@Schema @Data public class AlarmConditionFilterKey implements Serializable { - @ApiModelProperty(position = 1, value = "The key type", example = "TIME_SERIES") + @Schema(description = "The key type", example = "TIME_SERIES") private final AlarmConditionKeyType type; @NoXss - @ApiModelProperty(position = 2, value = "String value representing the key", example = "temp") + @Schema(description = "String value representing the key", example = "temp") private final String key; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java index 0f23ae5624..83615dfd4f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmRule.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.validation.NoXss; @@ -24,20 +23,20 @@ import org.thingsboard.server.common.data.validation.NoXss; import jakarta.validation.Valid; import java.io.Serializable; -@ApiModel +@Schema @Data public class AlarmRule implements Serializable { @Valid - @ApiModelProperty(position = 1, value = "JSON object representing the alarm rule condition") + @Schema(description = "JSON object representing the alarm rule condition") private AlarmCondition condition; - @ApiModelProperty(position = 2, value = "JSON object representing time interval during which the rule is active") + @Schema(description = "JSON object representing time interval during which the rule is active") private AlarmSchedule schedule; // Advanced @NoXss - @ApiModelProperty(position = 3, value = "String value representing the additional details for an alarm rule") + @Schema(description = "String value representing the additional details for an alarm rule") private String alarmDetails; - @ApiModelProperty(position = 4, value = "JSON object with the dashboard Id representing the reference to alarm details dashboard used by mobile application") + @Schema(description = "JSON object with the dashboard Id representing the reference to alarm details dashboard used by mobile application") private DashboardId dashboardId; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java index 96f365a152..395149c52b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileAlarm.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.validation.Length; @@ -27,34 +26,34 @@ import java.io.Serializable; import java.util.List; import java.util.TreeMap; -@ApiModel +@Schema @Data public class DeviceProfileAlarm implements Serializable { - @ApiModelProperty(position = 1, value = "String value representing the alarm rule id", example = "highTemperatureAlarmID") + @Schema(description = "String value representing the alarm rule id", example = "highTemperatureAlarmID") private String id; @Length(fieldName = "alarm type") @NoXss - @ApiModelProperty(position = 2, value = "String value representing type of the alarm", example = "High Temperature Alarm") + @Schema(description = "String value representing type of the alarm", example = "High Temperature Alarm") private String alarmType; @Valid - @ApiModelProperty(position = 3, value = "Complex JSON object representing create alarm rules. The unique create alarm rule can be created for each alarm severity type. " + + @Schema(description = "Complex JSON object representing create alarm rules. The unique create alarm rule can be created for each alarm severity type. " + "There can be 5 create alarm rules configured per a single alarm type. See method implementation notes and AlarmRule model for more details") private TreeMap createRules; @Valid - @ApiModelProperty(position = 4, value = "JSON object representing clear alarm rule") + @Schema(description = "JSON object representing clear alarm rule") private AlarmRule clearRule; // Hidden in advanced settings - @ApiModelProperty(position = 5, value = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to parent entities of alarm originator", example = "true") private boolean propagate; - @ApiModelProperty(position = 6, value = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the owner (tenant or customer) of alarm originator", example = "true") private boolean propagateToOwner; - @ApiModelProperty(position = 7, value = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") + @Schema(description = "Propagation flag to specify if alarm should be propagated to the tenant entity", example = "true") private boolean propagateToTenant; - @ApiModelProperty(position = 8, value = "JSON array of relation types that should be used for propagation. " + + @Schema(description = "JSON array of relation types that should be used for propagation. " + "By default, 'propagateRelationTypes' array is empty which means that the alarm will be propagated based on any relation type to parent entities. " + "This parameter should be used only in case when 'propagate' parameter is set to true, otherwise, 'propagateRelationTypes' array will be ignored.") private List propagateRelationTypes; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java index f6b2de915b..e2e7a646ea 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileData.java @@ -15,27 +15,26 @@ */ package org.thingsboard.server.common.data.device.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import jakarta.validation.Valid; import java.io.Serializable; import java.util.List; -@ApiModel +@Schema @Data public class DeviceProfileData implements Serializable { - @ApiModelProperty(position = 1, value = "JSON object of device profile configuration") + @Schema(description = "JSON object of device profile configuration") private DeviceProfileConfiguration configuration; @Valid - @ApiModelProperty(position = 2, value = "JSON object of device profile transport configuration") + @Schema(description = "JSON object of device profile transport configuration") private DeviceProfileTransportConfiguration transportConfiguration; - @ApiModelProperty(position = 3, value = "JSON object of provisioning strategy type per device profile") + @Schema(description = "JSON object of provisioning strategy type per device profile") private DeviceProfileProvisionConfiguration provisionConfiguration; @Valid - @ApiModelProperty(position = 4, value = "JSON array of alarm rules configuration per device profile") + @Schema(description = "JSON array of alarm rules configuration per device profile") private List alarms; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java index 4405115905..b59c5fadea 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfig.java @@ -15,56 +15,55 @@ */ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class LwM2MServerSecurityConfig implements Serializable { - @ApiModelProperty(position = 1, value = "Server short Id. Used as link to associate server Object Instance. This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client. " + + @Schema(description = "Server short Id. Used as link to associate server Object Instance. This identifier uniquely identifies each LwM2M Server configured for the LwM2M Client. " + "This Resource MUST be set when the Bootstrap-Server Resource has a value of 'false'. " + - "The values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.", example = "123", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "The values ID:0 and ID:65535 values MUST NOT be used for identifying the LwM2M Server.", example = "123", accessMode = Schema.AccessMode.READ_ONLY) protected Integer shortServerId = 123; /** Security -> ObjectId = 0 'LWM2M Security' */ - @ApiModelProperty(position = 2, value = "Is Bootstrap Server or Lwm2m Server. " + + @Schema(description = "Is Bootstrap Server or Lwm2m Server. " + "The LwM2M Client MAY be configured to use one or more LwM2M Server Account(s). " + "The LwM2M Client MUST have at most one LwM2M Bootstrap-Server Account. " + - "(*) The LwM2M client MUST have at least one LwM2M server account after completing the boot sequence specified.", example = "true or false", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "(*) The LwM2M client MUST have at least one LwM2M server account after completing the boot sequence specified.", example = "true or false", accessMode = Schema.AccessMode.READ_ONLY) protected boolean bootstrapServerIs = false; - @ApiModelProperty(position = 3, value = "Host for 'No Security' mode", example = "0.0.0.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Host for 'No Security' mode", example = "0.0.0.0", accessMode = Schema.AccessMode.READ_ONLY) protected String host; - @ApiModelProperty(position = 4, value = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", accessMode = Schema.AccessMode.READ_ONLY) protected Integer port; - @ApiModelProperty(position = 7, value = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", accessMode = Schema.AccessMode.READ_ONLY) protected Integer clientHoldOffTime = 1; - @ApiModelProperty(position = 8, value = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" + - "+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" + + "+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", accessMode = Schema.AccessMode.READ_ONLY) protected String serverPublicKey; - @ApiModelProperty(position = 9, value = "Server Public Key for 'Security' mode (DTLS): X509. Format: base64 encoded", example = "MMIICODCCAd6gAwIBAgIUI88U1zowOdrxDK/dOV+36gJxI2MwCgYIKoZIzj0EAwIwejELMAkGA1UEBhMCVUs\n" + + @Schema(description = "Server Public Key for 'Security' mode (DTLS): X509. Format: base64 encoded", example = "MMIICODCCAd6gAwIBAgIUI88U1zowOdrxDK/dOV+36gJxI2MwCgYIKoZIzj0EAwIwejELMAkGA1UEBhMCVUs\n" + "xEjAQBgNVBAgTCUt5aXYgY2l0eTENMAsGA1UEBxMES3lpdjEUMBIGA1UEChMLVGhpbmdzYm9hcmQxFzAVBgNVBAsMDkRFVkVMT1BFUl9URVNUMRkwFwYDVQQDDBBpbnRlcm1lZGlhdGVfY2EwMB4XDTIyMDEwOTEzMDMwMFoXDTI3MDEwODEzMDMwMFowFDESMBAGA1UEAxM\n" + "JbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUO3vBo/JTv0eooY7XHiKAIVDoWKFqtrU7C6q8AIKqpLcqhCdW+haFeBOH3PjY6EwaWkY04Bir4oanU0s7tz2uKOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/\n" + "BAIwADAdBgNVHQ4EFgQUEjc3Q4a0TxzP/3x3EV4fHxYUg0YwHwYDVR0jBBgwFoAUuSquGycMU6Q0SYNcbtSkSD3TfH0wLwYDVR0RBCgwJoIVbG9jYWxob3N0LmxvY2FsZG9tYWlugglsb2NhbGhvc3SCAiAtMAoGCCqGSM49BAMCA0gAMEUCIQD7dbZObyUaoDiNbX+9fUNp\n" + - "AWrD7N7XuJUwZ9FcN75R3gIgb2RNjDkHoyUyF1YajwkBk+7XmIXNClmizNJigj908mw=", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "AWrD7N7XuJUwZ9FcN75R3gIgb2RNjDkHoyUyF1YajwkBk+7XmIXNClmizNJigj908mw=", accessMode = Schema.AccessMode.READ_ONLY) protected String serverCertificate; - @ApiModelProperty(position = 10, value = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", accessMode = Schema.AccessMode.READ_ONLY) Integer bootstrapServerAccountTimeout = 0; /** Config -> ObjectId = 1 'LwM2M Server' */ - @ApiModelProperty(position = 11, value = "Specify the lifetime of the registration in seconds.", example = "300", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Specify the lifetime of the registration in seconds.", example = "300", accessMode = Schema.AccessMode.READ_ONLY) private Integer lifetime = 300; - @ApiModelProperty(position = 12, value = "The default value the LwM2M Client should use for the Minimum Period of an Observation in the absence of this parameter being included in an Observation. " + - "If this Resource doesn’t exist, the default value is 0.", example = "1", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The default value the LwM2M Client should use for the Minimum Period of an Observation in the absence of this parameter being included in an Observation. " + + "If this Resource doesn’t exist, the default value is 0.", example = "1", accessMode = Schema.AccessMode.READ_ONLY) private Integer defaultMinPeriod = 1; /** ResourceID=6 'Notification Storing When Disabled or Offline' */ - @ApiModelProperty(position = 13, value = "If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline. After the LwM2M Server account is enabled or the LwM2M Client is online, the LwM2M Client reports the stored “Notify” operations to the Server. " + + @Schema(description = "If true, the LwM2M Client stores “Notify” operations to the LwM2M Server while the LwM2M Server account is disabled or the LwM2M Client is offline. After the LwM2M Server account is enabled or the LwM2M Client is online, the LwM2M Client reports the stored “Notify” operations to the Server. " + "If false, the LwM2M Client discards all the “Notify” operations or temporarily disables the Observe function while the LwM2M Server is disabled or the LwM2M Client is offline. " + - "The default value is true.", example = "true", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + "The default value is true.", example = "true", accessMode = Schema.AccessMode.READ_ONLY) private boolean notifIfDisabled = true; - @ApiModelProperty(position = 14, value = "This Resource defines the transport binding configured for the LwM2M Client. " + - "If the LwM2M Client supports the binding specified in this Resource, the LwM2M Client MUST use that transport for the Current Binding Mode.", example = "U", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "This Resource defines the transport binding configured for the LwM2M Client. " + + "If the LwM2M Client supports the binding specified in this Resource, the LwM2M Client MUST use that transport for the Current Binding Mode.", example = "U", accessMode = Schema.AccessMode.READ_ONLY) private String binding = "U"; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java index ce622322d9..ea3e5a8dce 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/lwm2m/bootstrap/LwM2MServerSecurityConfigDefault.java @@ -15,15 +15,14 @@ */ package org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LwM2MServerSecurityConfigDefault extends LwM2MServerSecurityConfig { - @ApiModelProperty(position = 5, value = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", accessMode = Schema.AccessMode.READ_ONLY) protected String securityHost; - @ApiModelProperty(position = 6, value = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", accessMode = Schema.AccessMode.READ_ONLY) protected Integer securityPort; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java index 6d1d9390ba..169f4007f0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/Edge.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.edge; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Setter; import lombok.ToString; @@ -31,7 +30,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) @ToString @Setter @@ -89,7 +88,7 @@ public class Edge extends BaseDataWithAdditionalInfo implements HasLabel this.secret = edge.getSecret(); } - @ApiModelProperty(position = 1, value = "JSON object with the Edge Id. " + + @Schema(description = "JSON object with the Edge Id. " + "Specify this field to update the Edge. " + "Referencing non-existing Edge Id will cause error. " + "Omit this field to create new Edge." ) @@ -98,51 +97,51 @@ public class Edge extends BaseDataWithAdditionalInfo implements HasLabel return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the edge creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the edge creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id. Use 'assignDeviceToTenant' to change the Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public TenantId getTenantId() { return this.tenantId; } - @ApiModelProperty(position = 4, value = "JSON object with Customer Id. Use 'assignEdgeToCustomer' to change the Customer Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Customer Id. Use 'assignEdgeToCustomer' to change the Customer Id.", accessMode = Schema.AccessMode.READ_ONLY) @Override public CustomerId getCustomerId() { return this.customerId; } - @ApiModelProperty(position = 5, value = "JSON object with Root Rule Chain Id. Use 'setEdgeRootRuleChain' to change the Root Rule Chain Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Root Rule Chain Id. Use 'setEdgeRootRuleChain' to change the Root Rule Chain Id.", accessMode = Schema.AccessMode.READ_ONLY) public RuleChainId getRootRuleChainId() { return this.rootRuleChainId; } - @ApiModelProperty(position = 6, required = true, value = "Unique Edge Name in scope of Tenant", example = "Silo_A_Edge") + @Schema(required = true, description = "Unique Edge Name in scope of Tenant", example = "Silo_A_Edge") @Override public String getName() { return this.name; } - @ApiModelProperty(position = 7, required = true, value = "Edge type", example = "Silos") + @Schema(required = true, description = "Edge type", example = "Silos") public String getType() { return this.type; } - @ApiModelProperty(position = 8, value = "Label that may be used in widgets", example = "Silo Edge on far field") + @Schema(description = "Label that may be used in widgets", example = "Silo Edge on far field") public String getLabel() { return this.label; } - @ApiModelProperty(position = 9, required = true, value = "Edge routing key ('username') to authorize on cloud") + @Schema(required = true, description = "Edge routing key ('username') to authorize on cloud") public String getRoutingKey() { return this.routingKey; } - @ApiModelProperty(position = 10, required = true, value = "Edge secret ('password') to authorize on cloud") + @Schema(required = true, description = "Edge secret ('password') to authorize on cloud") public String getSecret() { return this.secret; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java index acfc458906..92a893c973 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeInstallInstructions.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data.edge; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel +@Schema @Data @AllArgsConstructor @NoArgsConstructor public class EdgeInstallInstructions { - @ApiModelProperty(position = 1, value = "Markdown with docker install instructions") + @Schema(description = "Markdown with docker install instructions") private String dockerInstallInstructions; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java index cf029ba793..575e4cbba0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/edge/EdgeSearchQuery.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.edge; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -29,11 +29,11 @@ import java.util.List; @Data public class EdgeSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and edge (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and edge (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of edge types to filter the related entities (e.g. 'Silos', 'Stores').") + @Schema(description = "Array of edge types to filter the related entities (e.g. 'Silos', 'Stores').") private List edgeTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java index c840d828fa..de77d3bb76 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.entityview; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.relation.EntityRelation; @@ -27,15 +26,15 @@ import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @Data public class EntityViewSearchQuery { - @ApiModelProperty(position = 3, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") + @Schema(description = "Type of the relation between root entity and device (e.g. 'Contains' or 'Manages').") private String relationType; - @ApiModelProperty(position = 2, value = "Array of entity view types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") + @Schema(description = "Array of entity view types to filter the related entities (e.g. 'Temperature Sensor', 'Smoke Sensor').") private List entityViewTypes; public EntityRelationsQuery toEntitySearchQuery() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java index c6773838a7..14507abae7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/DebugEventFilter.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public abstract class DebugEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 10, value = "Boolean value to filter the errors", allowableValues = "false, true") + @Schema(description = "Boolean value to filter the errors", allowableValues = "false, true") protected boolean isError; - @ApiModelProperty(position = 11, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") + @Schema(description = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") protected String errorStr; public void setIsError(boolean isError) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java index e20cd0dfa9..951965ee72 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/ErrorEventFilter.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public class ErrorEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 2, value = "String value representing the method name when the error happened", example = "onClusterEventMsg") + @Schema(description = "String value representing the method name when the error happened", example = "onClusterEventMsg") protected String method; - @ApiModelProperty(position = 3, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") + @Schema(description = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") protected String errorStr; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java index 7a520e212f..af4a283ef7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/EventFilter.java @@ -17,10 +17,9 @@ package org.thingsboard.server.common.data.event; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; -@ApiModel +@Schema @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, @@ -34,7 +33,7 @@ import io.swagger.annotations.ApiModelProperty; }) public interface EventFilter { - @ApiModelProperty(position = 1, required = true, value = "String value representing the event type", example = "STATS") + @Schema(required = true, description = "String value representing the event type", example = "STATS") EventType getEventType(); boolean isNotEmpty(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java index 659a16a135..3d193a5064 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/LifeCycleEventFilter.java @@ -15,22 +15,21 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public class LifeCycleEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 2, value = "String value representing the lifecycle event type", example = "STARTED") + @Schema(description = "String value representing the lifecycle event type", example = "STARTED") protected String event; - @ApiModelProperty(position = 3, value = "String value representing status of the lifecycle event", allowableValues = "Success, Failure") + @Schema(description = "String value representing status of the lifecycle event", allowableValues = "Success, Failure") protected String status; - @ApiModelProperty(position = 4, value = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") + @Schema(description = "The case insensitive 'contains' filter based on error message", example = "not present in the DB") protected String errorStr; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java index 29e31cf0c8..7f00c26579 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleChainDebugEventFilter.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.StringUtils; @Data @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema public class RuleChainDebugEventFilter extends DebugEventFilter { - @ApiModelProperty(position = 2, value = "String value representing the message") + @Schema(description = "String value representing the message") protected String message; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java index 589a70106e..b9cdfe8d37 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/RuleNodeDebugEventFilter.java @@ -15,32 +15,31 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.StringUtils; @Data @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema public class RuleNodeDebugEventFilter extends DebugEventFilter { - @ApiModelProperty(position = 2, value = "String value representing msg direction type (incoming to entity or outcoming from entity)", allowableValues = "IN, OUT") + @Schema(description = "String value representing msg direction type (incoming to entity or outcoming from entity)", allowableValues = "IN, OUT") protected String msgDirectionType; - @ApiModelProperty(position = 3, value = "String value representing the entity id in the event body (originator of the message)", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") + @Schema(description = "String value representing the entity id in the event body (originator of the message)", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") protected String entityId; - @ApiModelProperty(position = 4, value = "String value representing the entity type", allowableValues = "DEVICE") + @Schema(description = "String value representing the entity type", allowableValues = "DEVICE") protected String entityType; - @ApiModelProperty(position = 5, value = "String value representing the message id in the rule engine", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") + @Schema(description = "String value representing the message id in the rule engine", example = "de9d54a0-2b7a-11ec-a3cc-23386423d98f") protected String msgId; - @ApiModelProperty(position = 6, value = "String value representing the message type", example = "POST_TELEMETRY_REQUEST") + @Schema(description = "String value representing the message type", example = "POST_TELEMETRY_REQUEST") protected String msgType; - @ApiModelProperty(position = 7, value = "String value representing the type of message routing", example = "Success") + @Schema(description = "String value representing the type of message routing", example = "Success") protected String relationType; - @ApiModelProperty(position = 8, value = "The case insensitive 'contains' filter based on data (key and value) for the message.", example = "humidity") + @Schema(description = "The case insensitive 'contains' filter based on data (key and value) for the message.", example = "humidity") protected String dataSearch; - @ApiModelProperty(position = 9, value = "The case insensitive 'contains' filter based on metadata (key and value) for the message.", example = "deviceName") + @Schema(description = "The case insensitive 'contains' filter based on metadata (key and value) for the message.", example = "deviceName") protected String metadataSearch; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java index 15ac1c9c90..24485dd297 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/event/StatisticsEventFilter.java @@ -15,24 +15,23 @@ */ package org.thingsboard.server.common.data.event; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.StringUtils; @Data -@ApiModel +@Schema public class StatisticsEventFilter implements EventFilter { - @ApiModelProperty(position = 1, value = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") + @Schema(description = "String value representing the server name, identifier or ip address where the platform is running", example = "ip-172-31-24-152") protected String server; - @ApiModelProperty(position = 2, value = "The minimum number of successfully processed messages", example = "25") + @Schema(description = "The minimum number of successfully processed messages", example = "25") protected Integer minMessagesProcessed; - @ApiModelProperty(position = 3, value = "The maximum number of successfully processed messages", example = "250") + @Schema(description = "The maximum number of successfully processed messages", example = "250") protected Integer maxMessagesProcessed; - @ApiModelProperty(position = 4, value = "The minimum number of errors occurred during messages processing", example = "30") + @Schema(description = "The minimum number of errors occurred during messages processing", example = "30") protected Integer minErrorsOccurred; - @ApiModelProperty(position = 5, value = "The maximum number of errors occurred during messages processing", example = "300") + @Schema(description = "The maximum number of errors occurred during messages processing", example = "300") protected Integer maxErrorsOccurred; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java index 1cccaa4147..fdd8902127 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmCommentId.java @@ -17,11 +17,11 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import java.util.UUID; -@ApiModel +@Schema public class AlarmCommentId extends UUIDBased { private static final long serialVersionUID = 1L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java index 74e61ce9f3..be60f8f329 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AlarmId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class AlarmId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -37,7 +36,7 @@ public class AlarmId extends UUIDBased implements EntityId { return new AlarmId(UUID.fromString(alarmId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ALARM", allowableValues = "ALARM") + @Schema(required = true, description = "string", example = "ALARM", allowableValues = "ALARM") @Override public EntityType getEntityType() { return EntityType.ALARM; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java index 50e24a0f22..0cdf879eac 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/ApiUsageStateId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class ApiUsageStateId extends UUIDBased implements EntityId { @JsonCreator @@ -35,7 +34,7 @@ public class ApiUsageStateId extends UUIDBased implements EntityId { return new ApiUsageStateId(UUID.fromString(userId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "API_USAGE_STATE", allowableValues = "API_USAGE_STATE") + @Schema(required = true, description = "string", example = "API_USAGE_STATE", allowableValues = "API_USAGE_STATE") @Override public EntityType getEntityType() { return EntityType.API_USAGE_STATE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java index 593c305a07..01fdc7680b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class AssetId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -37,7 +36,7 @@ public class AssetId extends UUIDBased implements EntityId { return new AssetId(UUID.fromString(assetId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ASSET", allowableValues = "ASSET") + @Schema(required = true, description = "string", example = "ASSET", allowableValues = "ASSET") @Override public EntityType getEntityType() { return EntityType.ASSET; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java index 5de08e53e5..7fbf28c4d3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/AssetProfileId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class AssetProfileId extends UUIDBased implements EntityId { return new AssetProfileId(UUID.fromString(assetProfileId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ASSET_PROFILE", allowableValues = "ASSET_PROFILE") + @Schema(required = true, description = "string", example = "ASSET_PROFILE", allowableValues = "ASSET_PROFILE") @Override public EntityType getEntityType() { return EntityType.ASSET_PROFILE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java index beaa331ecf..dccd89b73b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/CustomerId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public final class CustomerId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -33,7 +32,7 @@ public final class CustomerId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "CUSTOMER", allowableValues = "CUSTOMER") + @Schema(required = true, description = "string", example = "CUSTOMER", allowableValues = "CUSTOMER") @Override public EntityType getEntityType() { return EntityType.CUSTOMER; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java index 740a801651..3af27d5457 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/DashboardId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class DashboardId extends UUIDBased implements EntityId { @JsonCreator @@ -35,7 +34,7 @@ public class DashboardId extends UUIDBased implements EntityId { return new DashboardId(UUID.fromString(dashboardId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "DASHBOARD", allowableValues = "DASHBOARD") + @Schema(required = true, description = "string", example = "DASHBOARD", allowableValues = "DASHBOARD") @Override public EntityType getEntityType() { return EntityType.DASHBOARD; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java index e39c5805ce..25c1fb6be4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceId.java @@ -17,13 +17,12 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; -@ApiModel +@Schema public class DeviceId extends UUIDBased implements EntityId { private static final long serialVersionUID = 1L; @@ -38,7 +37,7 @@ public class DeviceId extends UUIDBased implements EntityId { } @Override - @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE", allowableValues = "DEVICE") + @Schema(required = true, description = "string", example = "DEVICE", allowableValues = "DEVICE") public EntityType getEntityType() { return EntityType.DEVICE; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java index 26bc6d2b96..25c22ce8c1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/DeviceProfileId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class DeviceProfileId extends UUIDBased implements EntityId { return new DeviceProfileId(UUID.fromString(deviceProfileId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "DEVICE_PROFILE", allowableValues = "DEVICE_PROFILE") + @Schema(required = true, description = "string", example = "DEVICE_PROFILE", allowableValues = "DEVICE_PROFILE") @Override public EntityType getEntityType() { return EntityType.DEVICE_PROFILE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java index fb96f15740..b5a6632b44 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EdgeId.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType; import org.thingsboard.server.common.data.EntityType; @@ -41,7 +41,7 @@ public class EdgeId extends UUIDBased implements EntityId { return new EdgeId(UUID.fromString(edgeId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "EDGE", allowableValues = "EDGE") + @Schema(required = true, description = "string", example = "EDGE", allowableValues = "EDGE") @Override public EntityType getEntityType() { return EntityType.EDGE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java index 3f112e92ed..a6addb1d11 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java @@ -18,8 +18,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.io.Serializable; @@ -31,15 +30,15 @@ import java.util.UUID; @JsonDeserialize(using = EntityIdDeserializer.class) @JsonSerialize(using = EntityIdSerializer.class) -@ApiModel +@Schema public interface EntityId extends HasUUID, Serializable { //NOSONAR, the constant is closely related to EntityId UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); - @ApiModelProperty(position = 1, required = true, value = "ID of the entity, time-based UUID v1", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(required = true, description = "ID of the entity, time-based UUID v1", example = "784f394c-42b6-435a-983c-b7beff2784f9") UUID getId(); - @ApiModelProperty(position = 2, required = true, example = "DEVICE") + @Schema(required = true, example = "DEVICE") EntityType getEntityType(); @JsonIgnore diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java index 9cf7e83fa3..0a57acb813 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityViewId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -38,7 +38,7 @@ public class EntityViewId extends UUIDBased implements EntityId { return new EntityViewId(UUID.fromString(entityViewID)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "ENTITY_VIEW", allowableValues = "ENTITY_VIEW") + @Schema(required = true, description = "string", example = "ENTITY_VIEW", allowableValues = "ENTITY_VIEW") @Override public EntityType getEntityType() { return EntityType.ENTITY_VIEW; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java index 8977da637b..2799ecfdab 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/OtaPackageId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class OtaPackageId extends UUIDBased implements EntityId { return new OtaPackageId(UUID.fromString(firmwareId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "OTA_PACKAGE", allowableValues = "OTA_PACKAGE") + @Schema(required = true, description = "string", example = "OTA_PACKAGE", allowableValues = "OTA_PACKAGE") @Override public EntityType getEntityType() { return EntityType.OTA_PACKAGE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java index 7a3045c8a8..4f640303b9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RpcId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public final class RpcId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "RPC", allowableValues = "RPC") + @Schema(required = true, description = "string", example = "RPC", allowableValues = "RPC") @Override public EntityType getEntityType() { return EntityType.RPC; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java index cb3e2ca334..a4e4b9019c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleChainId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -29,7 +29,7 @@ public class RuleChainId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_CHAIN", allowableValues = "RULE_CHAIN") + @Schema(required = true, description = "string", example = "RULE_CHAIN", allowableValues = "RULE_CHAIN") @Override public EntityType getEntityType() { return EntityType.RULE_CHAIN; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java index db410dfea2..a4fc103ada 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/RuleNodeId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -29,7 +29,7 @@ public class RuleNodeId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "RULE_NODE", allowableValues = "RULE_NODE") + @Schema(required = true, description = "string", example = "RULE_NODE", allowableValues = "RULE_NODE") @Override public EntityType getEntityType() { return EntityType.RULE_NODE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java index e2716b0f43..eb1ce5cd13 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/TbResourceId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public class TbResourceId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "TB_RESOURCE", allowableValues = "TB_RESOURCE") + @Schema(required = true, description = "string", example = "TB_RESOURCE", allowableValues = "TB_RESOURCE") @Override public EntityType getEntityType() { return EntityType.TB_RESOURCE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java index 6f5fb09927..9a4264ca60 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java @@ -18,7 +18,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType; import org.thingsboard.server.common.data.EntityType; @@ -50,7 +50,7 @@ public final class TenantId extends UUIDBased implements EntityId { return this.equals(SYS_TENANT_ID); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "TENANT", allowableValues = "TENANT") + @Schema(required = true, description = "string", example = "TENANT", allowableValues = "TENANT") @Override public EntityType getEntityType() { return EntityType.TENANT; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java index f1e67a9435..e73d94df9f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/TenantProfileId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -35,7 +35,7 @@ public class TenantProfileId extends UUIDBased implements EntityId { return new TenantProfileId(UUID.fromString(tenantProfileId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "TENANT_PROFILE", allowableValues = "TENANT_PROFILE") + @Schema(required = true, description = "string", example = "TENANT_PROFILE", allowableValues = "TENANT_PROFILE") @Override public EntityType getEntityType() { return EntityType.TENANT_PROFILE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java index b234ee5961..5b52bd0af9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/UUIDBased.java @@ -15,13 +15,12 @@ */ package org.thingsboard.server.common.data.id; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import java.io.Serializable; import java.util.UUID; -@ApiModel +@Schema public abstract class UUIDBased implements HasUUID, Serializable { private static final long serialVersionUID = 1L; @@ -37,7 +36,7 @@ public abstract class UUIDBased implements HasUUID, Serializable { this.id = id; } - @ApiModelProperty(position = 1, required = true, value = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(required = true, description = "string", example = "784f394c-42b6-435a-983c-b7beff2784f9") public UUID getId() { return id; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java index 999e762a12..4053ada987 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/UserId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -33,7 +33,7 @@ public class UserId extends UUIDBased implements EntityId { return new UserId(UUID.fromString(userId)); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "USER", allowableValues = "USER") + @Schema(required = true, description = "string", example = "USER", allowableValues = "USER") @Override public EntityType getEntityType() { return EntityType.USER; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java index ff5fe2b62f..3dfef42d57 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetTypeId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public final class WidgetTypeId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGET_TYPE", allowableValues = "WIDGET_TYPE") + @Schema(required = true, description = "string", example = "WIDGET_TYPE", allowableValues = "WIDGET_TYPE") @Override public EntityType getEntityType() { return EntityType.WIDGET_TYPE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java index b6e6d2cc00..46509c1fe4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/WidgetsBundleId.java @@ -17,7 +17,7 @@ package org.thingsboard.server.common.data.id; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import org.thingsboard.server.common.data.EntityType; import java.util.UUID; @@ -31,7 +31,7 @@ public final class WidgetsBundleId extends UUIDBased implements EntityId { super(id); } - @ApiModelProperty(position = 2, required = true, value = "string", example = "WIDGETS_BUNDLE", allowableValues = "WIDGETS_BUNDLE") + @Schema(required = true, description = "string", example = "WIDGETS_BUNDLE", allowableValues = "WIDGETS_BUNDLE") @Override public EntityType getEntityType() { return EntityType.WIDGETS_BUNDLE; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java index 382dca5415..7614501c56 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java @@ -15,16 +15,15 @@ */ package org.thingsboard.server.common.data.lwm2m; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LwM2mInstance { - @ApiModelProperty(position = 1, value = "LwM2M Instance id.", example = "0") + @Schema(description = "LwM2M Instance id.", example = "0") int id; - @ApiModelProperty(position = 2, value = "LwM2M Resource observe.") + @Schema(description = "LwM2M Resource observe.") LwM2mResourceObserve[] resources; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java index 18de593227..44165bccd1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java @@ -15,23 +15,22 @@ */ package org.thingsboard.server.common.data.lwm2m; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class LwM2mObject { - @ApiModelProperty(position = 1, value = "LwM2M Object id.", example = "19") + @Schema(description = "LwM2M Object id.", example = "19") int id; - @ApiModelProperty(position = 2, value = "LwM2M Object key id.", example = "19_1.0") + @Schema(description = "LwM2M Object key id.", example = "19_1.0") String keyId; - @ApiModelProperty(position = 3, value = "LwM2M Object name.", example = "BinaryAppDataContainer") + @Schema(description = "LwM2M Object name.", example = "BinaryAppDataContainer") String name; - @ApiModelProperty(position = 4, value = "LwM2M Object multiple.", example = "true") + @Schema(description = "LwM2M Object multiple.", example = "true") boolean multiple; - @ApiModelProperty(position = 5, value = "LwM2M Object mandatory.", example = "false") + @Schema(description = "LwM2M Object mandatory.", example = "false") boolean mandatory; - @ApiModelProperty(position = 6, value = "LwM2M Object instances.") + @Schema(description = "LwM2M Object instances.") LwM2mInstance [] instances; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java index a40f422ad0..611d3ca66a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResourceObserve.java @@ -15,28 +15,27 @@ */ package org.thingsboard.server.common.data.lwm2m; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import java.util.stream.Stream; -@ApiModel +@Schema @Data @AllArgsConstructor public class LwM2mResourceObserve { - @ApiModelProperty(position = 1, value = "LwM2M Resource Observe id.", example = "0") + @Schema(description = "LwM2M Resource Observe id.", example = "0") int id; - @ApiModelProperty(position = 2, value = "LwM2M Resource Observe name.", example = "Data") + @Schema(description = "LwM2M Resource Observe name.", example = "Data") String name; - @ApiModelProperty(position = 3, value = "LwM2M Resource Observe observe.", example = "false") + @Schema(description = "LwM2M Resource Observe observe.", example = "false") boolean observe; - @ApiModelProperty(position = 4, value = "LwM2M Resource Observe attribute.", example = "false") + @Schema(description = "LwM2M Resource Observe attribute.", example = "false") boolean attribute; - @ApiModelProperty(position = 5, value = "LwM2M Resource Observe telemetry.", example = "false") + @Schema(description = "LwM2M Resource Observe telemetry.", example = "false") boolean telemetry; - @ApiModelProperty(position = 6, value = "LwM2M Resource Observe key name.", example = "data") + @Schema(description = "LwM2M Resource Observe key name.", example = "data") String keyName; public LwM2mResourceObserve(int id, String name, boolean observe, boolean attribute, boolean telemetry) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java index ba86a5781c..96ab5ccbed 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2BasicMapperConfig.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; @@ -27,31 +26,31 @@ import org.thingsboard.server.common.data.validation.Length; @EqualsAndHashCode @Data @ToString -@ApiModel +@Schema public class OAuth2BasicMapperConfig { @Length(fieldName = "emailAttributeKey", max = 31) - @ApiModelProperty(value = "Email attribute key of OAuth2 principal attributes. " + + @Schema(description = "Email attribute key of OAuth2 principal attributes. " + "Must be specified for BASIC mapper type and cannot be specified for GITHUB type") private final String emailAttributeKey; @Length(fieldName = "firstNameAttributeKey", max = 31) - @ApiModelProperty(value = "First name attribute key") + @Schema(description = "First name attribute key") private final String firstNameAttributeKey; @Length(fieldName = "lastNameAttributeKey", max = 31) - @ApiModelProperty(value = "Last name attribute key") + @Schema(description = "Last name attribute key") private final String lastNameAttributeKey; - @ApiModelProperty(value = "Tenant naming strategy. For DOMAIN type, domain for tenant name will be taken from the email (substring before '@')", required = true) + @Schema(description = "Tenant naming strategy. For DOMAIN type, domain for tenant name will be taken from the email (substring before '@')", required = true) private final TenantNameStrategyType tenantNameStrategy; @Length(fieldName = "tenantNamePattern") - @ApiModelProperty(value = "Tenant name pattern for CUSTOM naming strategy. " + + @Schema(description = "Tenant name pattern for CUSTOM naming strategy. " + "OAuth2 attributes in the pattern can be used by enclosing attribute key in '%{' and '}'", example = "%{email}") private final String tenantNamePattern; @Length(fieldName = "customerNamePattern") - @ApiModelProperty(value = "Customer name pattern. When creating a user on the first OAuth2 log in, if specified, " + + @Schema(description = "Customer name pattern. When creating a user on the first OAuth2 log in, if specified, " + "customer name will be used to create or find existing customer in the platform and assign customerId to the user") private final String customerNamePattern; @Length(fieldName = "defaultDashboardName") - @ApiModelProperty(value = "Name of the tenant's dashboard to set as default dashboard for newly created user") + @Schema(description = "Name of the tenant's dashboard to set as default dashboard for newly created user") private final String defaultDashboardName; - @ApiModelProperty(value = "Whether default dashboard should be open in full screen") + @Schema(description = "Whether default dashboard should be open in full screen") private final boolean alwaysFullScreen; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java index c7770cca0f..be8d2c9d54 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -26,14 +25,14 @@ import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor -@ApiModel +@Schema public class OAuth2ClientInfo { - @ApiModelProperty(value = "OAuth2 client name", example = "GitHub") + @Schema(description = "OAuth2 client name", example = "GitHub") private String name; - @ApiModelProperty(value = "Name of the icon, displayed on OAuth2 log in button", example = "github-logo") + @Schema(description = "Name of the icon, displayed on OAuth2 log in button", example = "github-logo") private String icon; - @ApiModelProperty(value = "URI for OAuth2 log in. On HTTP GET request to this URI, it redirects to the OAuth2 provider page", + @Schema(description = "URI for OAuth2 log in. On HTTP GET request to this URI, it redirects to the OAuth2 provider page", example = "/oauth2/authorization/8352f191-2b4d-11ec-9ed1-cbf57c026ecc") private String url; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java index 57945bf93e..cf56547e4d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ClientRegistrationTemplate.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @@ -33,45 +32,45 @@ import java.util.List; @Data @ToString @NoArgsConstructor -@ApiModel +@Schema public class OAuth2ClientRegistrationTemplate extends BaseDataWithAdditionalInfo implements HasName { @Length(fieldName = "providerId") - @ApiModelProperty(value = "OAuth2 provider identifier (e.g. its name)", required = true) + @Schema(description = "OAuth2 provider identifier (e.g. its name)", required = true) private String providerId; @Valid - @ApiModelProperty(value = "Default config for mapping OAuth2 log in response to platform entities") + @Schema(description = "Default config for mapping OAuth2 log in response to platform entities") private OAuth2MapperConfig mapperConfig; @Length(fieldName = "authorizationUri") - @ApiModelProperty(value = "Default authorization URI of the OAuth2 provider") + @Schema(description = "Default authorization URI of the OAuth2 provider") private String authorizationUri; @Length(fieldName = "accessTokenUri") - @ApiModelProperty(value = "Default access token URI of the OAuth2 provider") + @Schema(description = "Default access token URI of the OAuth2 provider") private String accessTokenUri; - @ApiModelProperty(value = "Default OAuth scopes that will be requested from OAuth2 platform") + @Schema(description = "Default OAuth scopes that will be requested from OAuth2 platform") private List scope; @Length(fieldName = "userInfoUri") - @ApiModelProperty(value = "Default user info URI of the OAuth2 provider") + @Schema(description = "Default user info URI of the OAuth2 provider") private String userInfoUri; @Length(fieldName = "userNameAttributeName") - @ApiModelProperty(value = "Default name of the username attribute in OAuth2 provider log in response") + @Schema(description = "Default name of the username attribute in OAuth2 provider log in response") private String userNameAttributeName; @Length(fieldName = "jwkSetUri") - @ApiModelProperty(value = "Default JSON Web Key URI of the OAuth2 provider") + @Schema(description = "Default JSON Web Key URI of the OAuth2 provider") private String jwkSetUri; @Length(fieldName = "clientAuthenticationMethod") - @ApiModelProperty(value = "Default client authentication method to use: 'BASIC' or 'POST'") + @Schema(description = "Default client authentication method to use: 'BASIC' or 'POST'") private String clientAuthenticationMethod; - @ApiModelProperty(value = "Comment for OAuth2 provider") + @Schema(description = "Comment for OAuth2 provider") private String comment; @Length(fieldName = "loginButtonIcon") - @ApiModelProperty(value = "Default log in button icon for OAuth2 provider") + @Schema(description = "Default log in button icon for OAuth2 provider") private String loginButtonIcon; @Length(fieldName = "loginButtonLabel") - @ApiModelProperty(value = "Default OAuth2 provider label") + @Schema(description = "Default OAuth2 provider label") private String loginButtonLabel; @Length(fieldName = "helpLink") - @ApiModelProperty(value = "Help link for OAuth2 provider") + @Schema(description = "Help link for OAuth2 provider") private String helpLink; public OAuth2ClientRegistrationTemplate(OAuth2ClientRegistrationTemplate clientRegistrationTemplate) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java index 06a175b441..71108ef137 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2DomainInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,10 +29,10 @@ import lombok.ToString; @NoArgsConstructor @AllArgsConstructor @Builder -@ApiModel +@Schema public class OAuth2DomainInfo { - @ApiModelProperty(value = "Domain scheme. Mixed scheme means than both HTTP and HTTPS are going to be used", required = true) + @Schema(description = "Domain scheme. Mixed scheme means than both HTTP and HTTPS are going to be used", required = true) private SchemeType scheme; - @ApiModelProperty(value = "Domain name. Cannot be empty", required = true) + @Schema(description = "Domain name. Cannot be empty", required = true) private String name; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java index 30531c3241..5c292ef23e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2Info.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -32,10 +31,10 @@ import java.util.List; @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor -@ApiModel +@Schema public class OAuth2Info { - @ApiModelProperty("Whether OAuth2 settings are enabled or not") + @Schema(description = "Whether OAuth2 settings are enabled or not") private boolean enabled; - @ApiModelProperty(value = "List of configured OAuth2 clients. Cannot contain null values", required = true) + @Schema(description = "List of configured OAuth2 clients. Cannot contain null values", required = true) private List oauth2ParamsInfos; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java index 89c8bcaa07..0896734d84 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MapperConfig.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; @@ -28,16 +28,16 @@ import jakarta.validation.Valid; @Data @ToString public class OAuth2MapperConfig { - @ApiModelProperty(value = "Whether user should be created if not yet present on the platform after successful authentication") + @Schema(description = "Whether user should be created if not yet present on the platform after successful authentication") private boolean allowUserCreation; - @ApiModelProperty(value = "Whether user credentials should be activated when user is created after successful authentication") + @Schema(description = "Whether user credentials should be activated when user is created after successful authentication") private boolean activateUser; - @ApiModelProperty(value = "Type of OAuth2 mapper. Depending on this param, different mapper config fields must be specified", required = true) + @Schema(description = "Type of OAuth2 mapper. Depending on this param, different mapper config fields must be specified", required = true) private MapperType type; @Valid - @ApiModelProperty(value = "Mapper config for BASIC and GITHUB mapper types") + @Schema(description = "Mapper config for BASIC and GITHUB mapper types") private OAuth2BasicMapperConfig basic; @Valid - @ApiModelProperty(value = "Mapper config for CUSTOM mapper type") + @Schema(description = "Mapper config for CUSTOM mapper type") private OAuth2CustomMapperConfig custom; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java index 2f6717adfc..f8999fa44b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2MobileInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -30,10 +29,10 @@ import lombok.ToString; @NoArgsConstructor @AllArgsConstructor @Builder -@ApiModel +@Schema public class OAuth2MobileInfo { - @ApiModelProperty(value = "Application package name. Cannot be empty", required = true) + @Schema(description = "Application package name. Cannot be empty", required = true) private String pkgName; - @ApiModelProperty(value = "Application secret. The length must be at least 16 characters", required = true) + @Schema(description = "Application secret. The length must be at least 16 characters", required = true) private String appSecret; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java index 8dcb827d71..9e34a5e598 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2ParamsInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.oauth2; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -32,16 +31,16 @@ import java.util.List; @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor -@ApiModel +@Schema public class OAuth2ParamsInfo { - @ApiModelProperty(value = "List of configured domains where OAuth2 platform will redirect a user after successful " + + @Schema(description = "List of configured domains where OAuth2 platform will redirect a user after successful " + "authentication. Cannot be empty. There have to be only one domain with specific name with scheme type 'MIXED'. " + "Configured domains with the same name must have different scheme types", required = true) private List domainInfos; - @ApiModelProperty(value = "Mobile applications settings. Application package name must be unique within the list", required = true) + @Schema(description = "Mobile applications settings. Application package name must be unique within the list", required = true) private List mobileInfos; - @ApiModelProperty(value = "List of OAuth2 provider settings. Cannot be empty", required = true) + @Schema(description = "List of OAuth2 provider settings. Cannot be empty", required = true) private List clientRegistrations; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java index e212585efb..3ccbb72bdb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/oauth2/OAuth2RegistrationInfo.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.oauth2; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -33,34 +32,34 @@ import java.util.List; @NoArgsConstructor @AllArgsConstructor @Builder -@ApiModel +@Schema public class OAuth2RegistrationInfo { - @ApiModelProperty(value = "Config for mapping OAuth2 log in response to platform entities", required = true) + @Schema(description = "Config for mapping OAuth2 log in response to platform entities", required = true) private OAuth2MapperConfig mapperConfig; - @ApiModelProperty(value = "OAuth2 client ID. Cannot be empty", required = true) + @Schema(description = "OAuth2 client ID. Cannot be empty", required = true) private String clientId; - @ApiModelProperty(value = "OAuth2 client secret. Cannot be empty", required = true) + @Schema(description = "OAuth2 client secret. Cannot be empty", required = true) private String clientSecret; - @ApiModelProperty(value = "Authorization URI of the OAuth2 provider. Cannot be empty", required = true) + @Schema(description = "Authorization URI of the OAuth2 provider. Cannot be empty", required = true) private String authorizationUri; - @ApiModelProperty(value = "Access token URI of the OAuth2 provider. Cannot be empty", required = true) + @Schema(description = "Access token URI of the OAuth2 provider. Cannot be empty", required = true) private String accessTokenUri; - @ApiModelProperty(value = "OAuth scopes that will be requested from OAuth2 platform. Cannot be empty", required = true) + @Schema(description = "OAuth scopes that will be requested from OAuth2 platform. Cannot be empty", required = true) private List scope; - @ApiModelProperty(value = "User info URI of the OAuth2 provider") + @Schema(description = "User info URI of the OAuth2 provider") private String userInfoUri; - @ApiModelProperty(value = "Name of the username attribute in OAuth2 provider response. Cannot be empty") + @Schema(description = "Name of the username attribute in OAuth2 provider response. Cannot be empty") private String userNameAttributeName; - @ApiModelProperty(value = "JSON Web Key URI of the OAuth2 provider") + @Schema(description = "JSON Web Key URI of the OAuth2 provider") private String jwkSetUri; - @ApiModelProperty(value = "Client authentication method to use: 'BASIC' or 'POST'. Cannot be empty", required = true) + @Schema(description = "Client authentication method to use: 'BASIC' or 'POST'. Cannot be empty", required = true) private String clientAuthenticationMethod; - @ApiModelProperty(value = "OAuth2 provider label. Cannot be empty", required = true) + @Schema(description = "OAuth2 provider label. Cannot be empty", required = true) private String loginButtonLabel; - @ApiModelProperty(value = "Log in button icon for OAuth2 provider") + @Schema(description = "Log in button icon for OAuth2 provider") private String loginButtonIcon; - @ApiModelProperty(value = "List of platforms for which usage of the OAuth2 client is allowed (empty for all allowed)") + @Schema(description = "List of platforms for which usage of the OAuth2 client is allowed (empty for all allowed)") private List platforms; - @ApiModelProperty(value = "Additional info of OAuth2 client (e.g. providerName)", required = true) + @Schema(description = "Additional info of OAuth2 client (e.g. providerName)", required = true) private JsonNode additionalInfo; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java index 44f9ab0a2f..b2e71bf947 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/objects/AttributesEntityView.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.objects; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; @@ -28,15 +27,15 @@ import java.util.List; * Created by Victor Basanets on 9/05/2017. */ @Data -@ApiModel +@Schema @NoArgsConstructor public class AttributesEntityView implements Serializable { - @ApiModelProperty(position = 1, required = true, value = "List of client-side attribute keys to expose", example = "currentConfiguration") + @Schema(required = true, description = "List of client-side attribute keys to expose", example = "currentConfiguration") private List cs = new ArrayList<>(); - @ApiModelProperty(position = 3, required = true, value = "List of server-side attribute keys to expose", example = "model") + @Schema(required = true, description = "List of server-side attribute keys to expose", example = "model") private List ss = new ArrayList<>(); - @ApiModelProperty(position = 2, required = true, value = "List of shared attribute keys to expose", example = "targetConfiguration") + @Schema(required = true, description = "List of shared attribute keys to expose", example = "targetConfiguration") private List sh = new ArrayList<>(); public AttributesEntityView(List cs, diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java index 2dd115138e..ad538128b7 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/objects/TelemetryEntityView.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.objects; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; @@ -27,14 +26,14 @@ import java.util.List; /** * Created by Victor Basanets on 9/05/2017. */ -@ApiModel +@Schema @Data @NoArgsConstructor public class TelemetryEntityView implements Serializable { - @ApiModelProperty(position = 1, required = true, value = "List of time-series data keys to expose", example = "temperature, humidity") + @Schema(required = true, description = "List of time-series data keys to expose", example = "temperature, humidity") private List timeseries; - @ApiModelProperty(position = 2, required = true, value = "JSON object with attributes to expose") + @Schema(required = true, description = "JSON object with attributes to expose") private AttributesEntityView attributes; public TelemetryEntityView(List timeseries, AttributesEntityView attributes) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java index 2ae94a0064..4f510ebb2b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageData.java @@ -17,15 +17,14 @@ package org.thingsboard.server.common.data.page; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; -@ApiModel +@Schema public class PageData { private final List data; @@ -48,22 +47,22 @@ public class PageData { this.hasNext = hasNext; } - @ApiModelProperty(position = 1, value = "Array of the entities", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Array of the entities", accessMode = Schema.AccessMode.READ_ONLY) public List getData() { return data; } - @ApiModelProperty(position = 2, value = "Total number of available pages. Calculated based on the 'pageSize' request parameter and total number of entities that match search criteria", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Total number of available pages. Calculated based on the 'pageSize' request parameter and total number of entities that match search criteria", accessMode = Schema.AccessMode.READ_ONLY) public int getTotalPages() { return totalPages; } - @ApiModelProperty(position = 3, value = "Total number of elements in all available pages", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Total number of elements in all available pages", accessMode = Schema.AccessMode.READ_ONLY) public long getTotalElements() { return totalElements; } - @ApiModelProperty(position = 4, value = "'false' value indicates the end of the result set", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "'false' value indicates the end of the result set", accessMode = Schema.AccessMode.READ_ONLY) @JsonProperty("hasNext") public boolean hasNext() { return hasNext; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index 1c186f2697..3387f85e6f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.plugin; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -29,27 +28,27 @@ import org.thingsboard.server.common.data.validation.Length; /** * @author Andrew Shvayka */ -@ApiModel +@Schema @ToString public class ComponentDescriptor extends BaseData { private static final long serialVersionUID = 1L; - @ApiModelProperty(position = 3, value = "Type of the Rule Node", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Type of the Rule Node", accessMode = Schema.AccessMode.READ_ONLY) @Getter @Setter private ComponentType type; - @ApiModelProperty(position = 4, value = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "TENANT", example = "TENANT") + @Schema(description = "Scope of the Rule Node. Always set to 'TENANT', since no rule chains on the 'SYSTEM' level yet.", accessMode = Schema.AccessMode.READ_ONLY, allowableValues = "TENANT", example = "TENANT") @Getter @Setter private ComponentScope scope; - @ApiModelProperty(position = 5, value = "Clustering mode of the RuleNode. This mode represents the ability to start Rule Node in multiple microservices.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, allowableValues = "USER_PREFERENCE, ENABLED, SINGLETON", example = "ENABLED") + @Schema(description = "Clustering mode of the RuleNode. This mode represents the ability to start Rule Node in multiple microservices.", accessMode = Schema.AccessMode.READ_ONLY, allowableValues = "USER_PREFERENCE, ENABLED, SINGLETON", example = "ENABLED") @Getter @Setter private ComponentClusteringMode clusteringMode; @Length(fieldName = "name") - @ApiModelProperty(position = 6, value = "Name of the Rule Node. Taken from the @RuleNode annotation.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "Custom Rule Node") + @Schema(description = "Name of the Rule Node. Taken from the @RuleNode annotation.", accessMode = Schema.AccessMode.READ_ONLY, example = "Custom Rule Node") @Getter @Setter private String name; - @ApiModelProperty(position = 7, value = "Full name of the Java class that implements the Rule Engine Node interface.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "com.mycompany.CustomRuleNode") + @Schema(description = "Full name of the Java class that implements the Rule Engine Node interface.", accessMode = Schema.AccessMode.READ_ONLY, example = "com.mycompany.CustomRuleNode") @Getter @Setter private String clazz; - @ApiModelProperty(position = 8, value = "Complex JSON object that represents the Rule Node configuration.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Complex JSON object that represents the Rule Node configuration.", accessMode = Schema.AccessMode.READ_ONLY) @Getter @Setter private transient JsonNode configurationDescriptor; @Length(fieldName = "actions") - @ApiModelProperty(position = 9, value = "Rule Node Actions. Deprecated. Always null.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Rule Node Actions. Deprecated. Always null.", accessMode = Schema.AccessMode.READ_ONLY) @Getter @Setter private String actions; public ComponentDescriptor() { @@ -70,7 +69,7 @@ public class ComponentDescriptor extends BaseData { this.actions = plugin.getActions(); } - @ApiModelProperty(position = 1, value = "JSON object with the descriptor Id. " + + @Schema(description = "JSON object with the descriptor Id. " + "Specify existing descriptor id to update the descriptor. " + "Referencing non-existing descriptor Id will cause error. " + "Omit this field to create new descriptor." ) @@ -79,7 +78,7 @@ public class ComponentDescriptor extends BaseData { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the descriptor creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the descriptor creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java index 2665abe7e9..e85cbc2fb8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityCountQuery.java @@ -15,14 +15,14 @@ */ package org.thingsboard.server.common.data.query; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.ToString; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @ToString public class EntityCountQuery { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java index f5362dd824..76d90087fe 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java @@ -15,12 +15,12 @@ */ package org.thingsboard.server.common.data.query; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class EntityKey implements Serializable { private static final long serialVersionUID = -6421575477523085543L; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java index ad5d42e31d..c8999cce2b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java @@ -15,12 +15,12 @@ */ package org.thingsboard.server.common.data.query; -import io.swagger.annotations.ApiModel; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class KeyFilter implements Serializable { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java index fa2d52f3f4..ecde8d82dc 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelation.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.relation; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.BaseDataWithAdditionalInfo; import org.thingsboard.server.common.data.id.EntityId; @@ -27,7 +26,7 @@ import org.thingsboard.server.common.data.validation.Length; import java.io.Serializable; @Slf4j -@ApiModel +@Schema public class EntityRelation implements Serializable { private static final long serialVersionUID = 2807343040519543363L; @@ -73,7 +72,7 @@ public class EntityRelation implements Serializable { this.additionalInfo = entityRelation.getAdditionalInfo(); } - @ApiModelProperty(position = 1, value = "JSON object with [from] Entity Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with [from] Entity Id.", accessMode = Schema.AccessMode.READ_ONLY) public EntityId getFrom() { return from; } @@ -82,7 +81,7 @@ public class EntityRelation implements Serializable { this.from = from; } - @ApiModelProperty(position = 2, value = "JSON object with [to] Entity Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with [to] Entity Id.", accessMode = Schema.AccessMode.READ_ONLY) public EntityId getTo() { return to; } @@ -91,7 +90,7 @@ public class EntityRelation implements Serializable { this.to = to; } - @ApiModelProperty(position = 3, value = "String value of relation type.", example = "Contains") + @Schema(description = "String value of relation type.", example = "Contains") public String getType() { return type; } @@ -100,7 +99,7 @@ public class EntityRelation implements Serializable { this.type = type; } - @ApiModelProperty(position = 4, value = "Represents the type group of the relation.", example = "COMMON") + @Schema(description = "Represents the type group of the relation.", example = "COMMON") public RelationTypeGroup getTypeGroup() { return typeGroup; } @@ -109,7 +108,7 @@ public class EntityRelation implements Serializable { this.typeGroup = typeGroup; } - @ApiModelProperty(position = 5, value = "Additional parameters of the relation", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the relation",implementation = com.fasterxml.jackson.databind.JsonNode.class) public JsonNode getAdditionalInfo() { return BaseDataWithAdditionalInfo.getJson(() -> additionalInfo, () -> additionalInfoBytes); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java index 44acbb6a5f..364d40b062 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.relation; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; public class EntityRelationInfo extends EntityRelation { @@ -32,7 +32,7 @@ public class EntityRelationInfo extends EntityRelation { super(entityRelation); } - @ApiModelProperty(position = 6, value = "Name of the entity for [from] direction.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "A4B72CCDFF33") + @Schema(description = "Name of the entity for [from] direction.", accessMode = Schema.AccessMode.READ_ONLY, example = "A4B72CCDFF33") public String getFromName() { return fromName; } @@ -41,7 +41,7 @@ public class EntityRelationInfo extends EntityRelation { this.fromName = fromName; } - @ApiModelProperty(position = 7, value = "Name of the entity for [to] direction.", accessMode = ApiModelProperty.AccessMode.READ_ONLY, example = "A4B72CCDFF35") + @Schema(description = "Name of the entity for [to] direction.", accessMode = Schema.AccessMode.READ_ONLY, example = "A4B72CCDFF35") public String getToName() { return toName; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java index b3f052d59e..cefd2fa4f4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationsQuery.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.relation; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; @@ -25,12 +24,12 @@ import java.util.List; * Created by ashvayka on 02.05.17. */ @Data -@ApiModel +@Schema public class EntityRelationsQuery { - @ApiModelProperty(position = 2, value = "Main search parameters.") + @Schema(description = "Main search parameters.") private RelationsSearchParameters parameters; - @ApiModelProperty(position = 1, value = "Main filters.") + @Schema(description = "Main filters.") private List filters; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java index 80ff4fe874..b8e5e94a19 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationEntityTypeFilter.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.relation; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.EntityType; @@ -28,12 +27,12 @@ import java.util.List; */ @Data @AllArgsConstructor -@ApiModel +@Schema public class RelationEntityTypeFilter { - @ApiModelProperty(position = 1, value = "Type of the relation between root entity and other entity (e.g. 'Contains' or 'Manages').", example = "Contains") + @Schema(description = "Type of the relation between root entity and other entity (e.g. 'Contains' or 'Manages').", example = "Contains") private String relationType; - @ApiModelProperty(position = 2, value = "Array of entity types to filter the related entities (e.g. 'DEVICE', 'ASSET').") + @Schema(description = "Array of entity types to filter the related entities (e.g. 'DEVICE', 'ASSET').") private List entityTypes; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java index 23a3a6407c..cfc338ff55 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.relation; import com.fasterxml.jackson.annotation.JsonIgnore; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import org.thingsboard.server.common.data.EntityType; @@ -29,22 +28,22 @@ import java.util.UUID; /** * Created by ashvayka on 03.05.17. */ -@ApiModel +@Schema @Data @AllArgsConstructor public class RelationsSearchParameters { - @ApiModelProperty(position = 1, value = "Root entity id to start search from.", example = "784f394c-42b6-435a-983c-b7beff2784f9") + @Schema(description = "Root entity id to start search from.", example = "784f394c-42b6-435a-983c-b7beff2784f9") private UUID rootId; - @ApiModelProperty(position = 2, value = "Type of the root entity.") + @Schema(description = "Type of the root entity.") private EntityType rootType; - @ApiModelProperty(position = 3, value = "Type of the root entity.") + @Schema(description = "Type of the root entity.") private EntitySearchDirection direction; - @ApiModelProperty(position = 4, value = "Type of the relation.") + @Schema(description = "Type of the relation.") private RelationTypeGroup relationTypeGroup; - @ApiModelProperty(position = 5, value = "Maximum level of the search depth.") + @Schema(description = "Maximum level of the search depth.") private int maxLevel = 1; - @ApiModelProperty(position = 6, value = "Fetch entities that match the last level of search. Useful to find Devices that are strictly 'maxLevel' relations away from the root entity.") + @Schema(description = "Fetch entities that match the last level of search. Useful to find Devices that are strictly 'maxLevel' relations away from the root entity.") private boolean fetchLastLevelOnly; public RelationsSearchParameters(EntityId entityId, EntitySearchDirection direction, int maxLevel, boolean fetchLastLevelOnly) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java b/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java index 154a725761..d764a1fe0b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rpc/Rpc.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.rpc; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; @@ -26,24 +25,24 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.RpcId; import org.thingsboard.server.common.data.id.TenantId; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) public class Rpc extends BaseData implements HasTenantId { - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; - @ApiModelProperty(position = 4, value = "JSON object with Device Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Device Id.", accessMode = Schema.AccessMode.READ_ONLY) private DeviceId deviceId; - @ApiModelProperty(position = 5, value = "Expiration time of the request.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Expiration time of the request.", accessMode = Schema.AccessMode.READ_ONLY) private long expirationTime; - @ApiModelProperty(position = 6, value = "The request body that will be used to send message to device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The request body that will be used to send message to device.", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode request; - @ApiModelProperty(position = 7, value = "The response from the device.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The response from the device.", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode response; - @ApiModelProperty(position = 8, value = "The current status of the RPC call.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "The current status of the RPC call.", accessMode = Schema.AccessMode.READ_ONLY) private RpcStatus status; - @ApiModelProperty(position = 9, value = "Additional info used in the rule engine to process the updates to the RPC state.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Additional info used in the rule engine to process the updates to the RPC state.", accessMode = Schema.AccessMode.READ_ONLY) private JsonNode additionalInfo; public Rpc() { @@ -65,13 +64,13 @@ public class Rpc extends BaseData implements HasTenantId { this.additionalInfo = rpc.getAdditionalInfo(); } - @ApiModelProperty(position = 1, value = "JSON object with the rpc Id. Referencing non-existing rpc Id will cause error.") + @Schema(description = "JSON object with the rpc Id. Referencing non-existing rpc Id will cause error.") @Override public RpcId getId() { return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rpc creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the rpc creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java index 0df8b4e03a..3ab6912824 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/DefaultRuleChainCreateRequest.java @@ -15,21 +15,20 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.io.Serializable; -@ApiModel +@Schema @Data @Slf4j public class DefaultRuleChainCreateRequest implements Serializable { private static final long serialVersionUID = 5600333716030561537L; - @ApiModelProperty(position = 1, required = true, value = "Name of the new rule chain", example = "Root Rule Chain") + @Schema(required = true, description = "Name of the new rule chain", example = "Root Rule Chain") private String name; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java index 4bccbf6366..febf3e29f0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/NodeConnectionInfo.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; /** * Created by ashvayka on 21.03.18. */ -@ApiModel +@Schema @Data public class NodeConnectionInfo { - @ApiModelProperty(position = 1, required = true, value = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") + @Schema(required = true, description = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") private int fromIndex; - @ApiModelProperty(position = 2, required = true, value = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'to' part of the connection.") + @Schema(required = true, description = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'to' part of the connection.") private int toIndex; - @ApiModelProperty(position = 3, required = true, value = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") + @Schema(required = true, description = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") private String type; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java index edb70cefda..9d4099755e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChain.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.rule; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -32,7 +31,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @Slf4j @@ -40,21 +39,21 @@ public class RuleChain extends BaseDataWithAdditionalInfo implement private static final long serialVersionUID = -5656679015121935465L; - @ApiModelProperty(position = 3, required = true, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 4, required = true, value = "Rule Chain name", example = "Humidity data processing") + @Schema(required = true, description = "Rule Chain name", example = "Humidity data processing") private String name; - @ApiModelProperty(position = 5, value = "Rule Chain type. 'EDGE' rule chains are processing messages on the edge devices only.", example = "A4B72CCDFF33") + @Schema(description = "Rule Chain type. 'EDGE' rule chains are processing messages on the edge devices only.", example = "A4B72CCDFF33") private RuleChainType type; - @ApiModelProperty(position = 6, value = "JSON object with Rule Chain Id. Pointer to the first rule node that should receive all messages pushed to this rule chain.") + @Schema(description = "JSON object with Rule Chain Id. Pointer to the first rule node that should receive all messages pushed to this rule chain.") private RuleNodeId firstRuleNodeId; - @ApiModelProperty(position = 7, value = "Indicates root rule chain. The root rule chain process messages from all devices and entities by default. User may configure default rule chain per device profile.") + @Schema(description = "Indicates root rule chain. The root rule chain process messages from all devices and entities by default. User may configure default rule chain per device profile.") private boolean root; - @ApiModelProperty(position = 8, value = "Reserved for future usage.") + @Schema(description = "Reserved for future usage.") private boolean debugMode; - @ApiModelProperty(position = 9, value = "Reserved for future usage. The actual list of rule nodes and their relations is stored in the database separately.") + @Schema(description = "Reserved for future usage. The actual list of rule nodes and their relations is stored in the database separately.") private transient JsonNode configuration; private RuleChainId externalId; @@ -86,7 +85,7 @@ public class RuleChain extends BaseDataWithAdditionalInfo implement return name; } - @ApiModelProperty(position = 1, value = "JSON object with the Rule Chain Id. " + + @Schema(description = "JSON object with the Rule Chain Id. " + "Specify this field to update the Rule Chain. " + "Referencing non-existing Rule Chain Id will cause error. " + "Omit this field to create new rule chain." ) @@ -95,7 +94,7 @@ public class RuleChain extends BaseDataWithAdditionalInfo implement return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rule chain creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the rule chain creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java index edd22564f1..87a7dde0ca 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainConnectionInfo.java @@ -16,23 +16,22 @@ package org.thingsboard.server.common.data.rule; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.RuleChainId; /** * Created by ashvayka on 21.03.18. */ -@ApiModel +@Schema @Data public class RuleChainConnectionInfo { - @ApiModelProperty(position = 1, required = true, value = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") + @Schema(required = true, description = "Index of rule node in the 'nodes' array of the RuleChainMetaData. Indicates the 'from' part of the connection.") private int fromIndex; - @ApiModelProperty(position = 2, required = true, value = "JSON object with the Rule Chain Id.") + @Schema(required = true, description = "JSON object with the Rule Chain Id.") private RuleChainId targetRuleChainId; - @ApiModelProperty(position = 3, required = true, value = "JSON object with the additional information about the connection.") + @Schema(required = true, description = "JSON object with the additional information about the connection.") private JsonNode additionalInfo; - @ApiModelProperty(position = 4, required = true, value = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") + @Schema(required = true, description = "Type of the relation. Typically indicated the result of processing by the 'from' rule node. For example, 'Success' or 'Failure'") private String type; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java index ee53811ce1..74aaaa2c12 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainData.java @@ -15,18 +15,17 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; -@ApiModel +@Schema @Data public class RuleChainData { - @ApiModelProperty(position = 1, required = true, value = "List of the Rule Chain objects.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "List of the Rule Chain objects.", accessMode = Schema.AccessMode.READ_ONLY) List ruleChains; - @ApiModelProperty(position = 2, required = true, value = "List of the Rule Chain metadata objects.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "List of the Rule Chain metadata objects.", accessMode = Schema.AccessMode.READ_ONLY) List metadata; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java index 6ebdeed1dc..79d2f75254 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainMetaData.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.RuleChainId; @@ -26,23 +25,23 @@ import java.util.List; /** * Created by igor on 3/13/18. */ -@ApiModel +@Schema @Data public class RuleChainMetaData { - @ApiModelProperty(position = 1, required = true, value = "JSON object with Rule Chain Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "JSON object with Rule Chain Id.", accessMode = Schema.AccessMode.READ_ONLY) private RuleChainId ruleChainId; - @ApiModelProperty(position = 2, required = true, value = "Index of the first rule node in the 'nodes' list") + @Schema(required = true, description = "Index of the first rule node in the 'nodes' list") private Integer firstNodeIndex; - @ApiModelProperty(position = 3, required = true, value = "List of rule node JSON objects") + @Schema(required = true, description = "List of rule node JSON objects") private List nodes; - @ApiModelProperty(position = 4, required = true, value = "List of JSON objects that represent connections between rule nodes") + @Schema(required = true, description = "List of JSON objects that represent connections between rule nodes") private List connections; - @ApiModelProperty(position = 5, required = true, value = "List of JSON objects that represent connections between rule nodes and other rule chains.") + @Schema(required = true, description = "List of JSON objects that represent connections between rule nodes and other rule chains.") private List ruleChainConnections; public void addConnectionInfo(int fromIndex, int toIndex, String type) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java index 7a2b2c5b8d..f148aaa9f4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleChainOutputLabelsUsage.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.rule; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.id.RuleChainId; @@ -24,21 +23,21 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import java.util.Set; -@ApiModel +@Schema @Data @Slf4j public class RuleChainOutputLabelsUsage { - @ApiModelProperty(position = 1, required = true, value = "Rule Chain Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Chain Id", accessMode = Schema.AccessMode.READ_ONLY) private RuleChainId ruleChainId; - @ApiModelProperty(position = 2, required = true, value = "Rule Node Id", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Node Id", accessMode = Schema.AccessMode.READ_ONLY) private RuleNodeId ruleNodeId; - @ApiModelProperty(position = 3, required = true, value = "Rule Chain Name", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Chain Name", accessMode = Schema.AccessMode.READ_ONLY) private String ruleChainName; - @ApiModelProperty(position = 4, required = true, value = "Rule Node Name", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Rule Node Name", accessMode = Schema.AccessMode.READ_ONLY) private String ruleNodeName; - @ApiModelProperty(position = 5, required = true, value = "Output labels", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(required = true, description = "Output labels", accessMode = Schema.AccessMode.READ_ONLY) private Set labels; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java index 16a127e48a..1926bb8c3c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleNode.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.rule; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -29,7 +28,7 @@ import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @Data @EqualsAndHashCode(callSuper = true) @Slf4j @@ -37,20 +36,20 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements private static final long serialVersionUID = -5656679015121235465L; - @ApiModelProperty(position = 3, value = "JSON object with the Rule Chain Id. ", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with the Rule Chain Id. ", accessMode = Schema.AccessMode.READ_ONLY) private RuleChainId ruleChainId; @Length(fieldName = "type") - @ApiModelProperty(position = 4, value = "Full Java Class Name of the rule node implementation. ", example = "com.mycompany.iot.rule.engine.ProcessingNode") + @Schema(description = "Full Java Class Name of the rule node implementation. ", example = "com.mycompany.iot.rule.engine.ProcessingNode") private String type; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 5, value = "User defined name of the rule node. Used on UI and for logging. ", example = "Process sensor reading") + @Schema(description = "User defined name of the rule node. Used on UI and for logging. ", example = "Process sensor reading") private String name; - @ApiModelProperty(position = 6, value = "Enable/disable debug. ", example = "false") + @Schema(description = "Enable/disable debug. ", example = "false") private boolean debugMode; - @ApiModelProperty(position = 7, value = "Enable/disable singleton mode. ", example = "false") + @Schema(description = "Enable/disable singleton mode. ", example = "false") private boolean singletonMode; - @ApiModelProperty(position = 8, value = "JSON with the rule node configuration. Structure depends on the rule node implementation.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "JSON with the rule node configuration. Structure depends on the rule node implementation.",implementation = com.fasterxml.jackson.databind.JsonNode.class) private transient JsonNode configuration; @JsonIgnore private byte[] configurationBytes; @@ -89,7 +88,7 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements setJson(data, json -> this.configuration = json, bytes -> this.configurationBytes = bytes); } - @ApiModelProperty(position = 1, value = "JSON object with the Rule Node Id. " + + @Schema(description = "JSON object with the Rule Node Id. " + "Specify this field to update the Rule Node. " + "Referencing non-existing Rule Node Id will cause error. " + "Omit this field to create new rule node." ) @@ -98,13 +97,13 @@ public class RuleNode extends BaseDataWithAdditionalInfo implements return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the rule node creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the rule node creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 8, value = "Additional parameters of the rule node. Contains 'layoutX' and 'layoutY' properties for visualization.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "Additional parameters of the rule node. Contains 'layoutX' and 'layoutY' properties for visualization.",implementation = com.fasterxml.jackson.databind.JsonNode.class) @Override public JsonNode getAdditionalInfo() { return super.getAdditionalInfo(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java index e12aa43cbc..cdd5950fbb 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java @@ -15,14 +15,13 @@ */ package org.thingsboard.server.common.data.security; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.DeviceCredentialsId; import org.thingsboard.server.common.data.id.DeviceId; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class DeviceCredentials extends BaseData implements DeviceCredentialsFilter { @@ -48,7 +47,7 @@ public class DeviceCredentials extends BaseData implements this.credentialsValue = deviceCredentials.getCredentialsValue(); } - @ApiModelProperty(position = 1, required = true, accessMode = ApiModelProperty.AccessMode.READ_ONLY, value = "The Id is automatically generated during device creation. " + + @Schema(required = true, accessMode = Schema.AccessMode.READ_ONLY, description = "The Id is automatically generated during device creation. " + "Use 'getDeviceCredentialsByDeviceId' to obtain the id based on device id. " + "Use 'updateDeviceCredentials' to update device credentials. ", example = "784f394c-42b6-435a-983c-b7beff2784f9") @Override @@ -56,13 +55,13 @@ public class DeviceCredentials extends BaseData implements return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the device credentials creation, in milliseconds", example = "1609459200000") + @Schema(description = "Timestamp of the device credentials creation, in milliseconds", example = "1609459200000") @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, required = true, value = "JSON object with the device Id.") + @Schema(required = true, description = "JSON object with the device Id.") public DeviceId getDeviceId() { return deviceId; } @@ -71,7 +70,7 @@ public class DeviceCredentials extends BaseData implements this.deviceId = deviceId; } - @ApiModelProperty(position = 4, value = "Type of the credentials", allowableValues="ACCESS_TOKEN, X509_CERTIFICATE, MQTT_BASIC, LWM2M_CREDENTIALS") + @Schema(description = "Type of the credentials", allowableValues ="ACCESS_TOKEN, X509_CERTIFICATE, MQTT_BASIC, LWM2M_CREDENTIALS") @Override public DeviceCredentialsType getCredentialsType() { return credentialsType; @@ -81,7 +80,7 @@ public class DeviceCredentials extends BaseData implements this.credentialsType = credentialsType; } - @ApiModelProperty(position = 5, required = true, value = "Unique Credentials Id per platform instance. " + + @Schema(required = true, description = "Unique Credentials Id per platform instance. " + "Used to lookup credentials from the database. " + "By default, new access token for your device. " + "Depends on the type of the credentials." @@ -95,7 +94,7 @@ public class DeviceCredentials extends BaseData implements this.credentialsId = credentialsId; } - @ApiModelProperty(position = 6, value = "Value of the credentials. " + + @Schema(description = "Value of the credentials. " + "Null in case of ACCESS_TOKEN credentials type. Base64 value in case of X509_CERTIFICATE. " + "Complex object in case of MQTT_BASIC and LWM2M_CREDENTIALS", example = "Null in case of ACCESS_TOKEN. See model definition.") public String getCredentialsValue() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java index 62f15499e3..af2962f314 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtPair.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.security.Authority; -@ApiModel(value = "JWT Pair") +@Schema(description = "JWT Pair") @Data @NoArgsConstructor public class JwtPair { - @ApiModelProperty(position = 1, value = "The JWT Access Token. Used to perform API calls.", example = "AAB254FF67D..") + @Schema(description = "The JWT Access Token. Used to perform API calls.", example = "AAB254FF67D..") private String token; - @ApiModelProperty(position = 1, value = "The JWT Refresh Token. Used to get new JWT Access Token if old one has expired.", example = "AAB254FF67D..") + @Schema(description = "The JWT Refresh Token. Used to get new JWT Access Token if old one has expired.", example = "AAB254FF67D..") private String refreshToken; private Authority scope; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java index 33bbca468b..53c0096a22 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/JwtSettings.java @@ -15,13 +15,12 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -@ApiModel(value = "JWT Settings") +@Schema(description = "JWT Settings") @AllArgsConstructor @NoArgsConstructor @Data @@ -30,26 +29,26 @@ public class JwtSettings { /** * {@link JwtToken} will expire after this time. */ - @ApiModelProperty(position = 1, value = "The JWT will expire after seconds.", example = "9000") + @Schema(description = "The JWT will expire after seconds.", example = "9000") private Integer tokenExpirationTime; /** * {@link JwtToken} can be refreshed during this timeframe. */ - @ApiModelProperty(position = 2, value = "The JWT can be refreshed during seconds.", example = "604800") + @Schema(description = "The JWT can be refreshed during seconds.", example = "604800") private Integer refreshTokenExpTime; /** * Token issuer. */ - @ApiModelProperty(position = 3, value = "The JWT issuer.", example = "thingsboard.io") + @Schema(description = "The JWT issuer.", example = "thingsboard.io") private String tokenIssuer; /** * Key is used to sign {@link JwtToken}. * Base64 encoded */ - @ApiModelProperty(position = 4, value = "The JWT key is used to sing token. Base64 encoded.", example = "cTU4WnNqemI2aU5wbWVjdm1vYXRzanhjNHRUcXliMjE=") + @Schema(description = "The JWT key is used to sing token. Base64 encoded.", example = "cTU4WnNqemI2aU5wbWVjdm1vYXRzanhjNHRUcXliMjE=") private String tokenSigningKey; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java index 4c19b1fa5d..bdfbf975ad 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/SecuritySettings.java @@ -15,22 +15,21 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class SecuritySettings implements Serializable { private static final long serialVersionUID = -1307613974597312465L; - @ApiModelProperty(position = 1, value = "The user password policy object." ) + @Schema(description = "The user password policy object." ) private UserPasswordPolicy passwordPolicy; - @ApiModelProperty(position = 2, value = "Maximum number of failed login attempts allowed before user account is locked." ) + @Schema(description = "Maximum number of failed login attempts allowed before user account is locked." ) private Integer maxFailedLoginAttempts; - @ApiModelProperty(position = 3, value = "Email to use for notifications about locked users." ) + @Schema(description = "Email to use for notifications about locked users." ) private String userLockoutNotificationEmail; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java index 881af89e27..d94183ba02 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/UserPasswordPolicy.java @@ -15,32 +15,31 @@ */ package org.thingsboard.server.common.data.security.model; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.io.Serializable; -@ApiModel +@Schema @Data public class UserPasswordPolicy implements Serializable { - @ApiModelProperty(position = 1, value = "Minimum number of symbols in the password." ) + @Schema(description = "Minimum number of symbols in the password." ) private Integer minimumLength; - @ApiModelProperty(position = 1, value = "Minimum number of uppercase letters in the password." ) + @Schema(description = "Minimum number of uppercase letters in the password." ) private Integer minimumUppercaseLetters; - @ApiModelProperty(position = 1, value = "Minimum number of lowercase letters in the password." ) + @Schema(description = "Minimum number of lowercase letters in the password." ) private Integer minimumLowercaseLetters; - @ApiModelProperty(position = 1, value = "Minimum number of digits in the password." ) + @Schema(description = "Minimum number of digits in the password." ) private Integer minimumDigits; - @ApiModelProperty(position = 1, value = "Minimum number of special in the password." ) + @Schema(description = "Minimum number of special in the password." ) private Integer minimumSpecialCharacters; - @ApiModelProperty(position = 1, value = "Allow whitespaces") + @Schema(description = "Allow whitespaces") private Boolean allowWhitespaces = true; - @ApiModelProperty(position = 1, value = "Password expiration period (days). Force expiration of the password." ) + @Schema(description = "Password expiration period (days). Force expiration of the password." ) private Integer passwordExpirationPeriodDays; - @ApiModelProperty(position = 1, value = "Password reuse frequency (days). Disallow to use the same password for the defined number of days" ) + @Schema(description = "Password reuse frequency (days). Disallow to use the same password for the defined number of days" ) private Integer passwordReuseFrequencyDays; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java index ce214cb603..21ab795f1d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/AbstractUserDashboardInfo.java @@ -15,23 +15,22 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.HasTitle; import java.io.Serializable; import java.util.UUID; -@ApiModel +@Schema @Data public abstract class AbstractUserDashboardInfo implements HasTitle, Serializable { private static final long serialVersionUID = -6461562426034242608L; - @ApiModelProperty(position = 1, value = "JSON object with Dashboard id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Dashboard id.", accessMode = Schema.AccessMode.READ_ONLY) private UUID id; - @ApiModelProperty(position = 2, value = "Title of the dashboard.") + @Schema(description = "Title of the dashboard.") private String title; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java index e49910eb43..0085f059f0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/LastVisitedDashboardInfo.java @@ -15,23 +15,22 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema @Data public class LastVisitedDashboardInfo extends AbstractUserDashboardInfo implements Serializable { private static final long serialVersionUID = -6461562426034242608L; - @ApiModelProperty(position = 3, value = "Starred flag") + @Schema(description = "Starred flag") private boolean starred; - @ApiModelProperty(position = 4, value = "Last visit timestamp") + @Schema(description = "Last visit timestamp") private long lastVisited; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java index e71404c392..6fba8798e8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/StarredDashboardInfo.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; @EqualsAndHashCode(callSuper = true) -@ApiModel +@Schema @Data public class StarredDashboardInfo extends AbstractUserDashboardInfo implements Serializable { private static final long serialVersionUID = -7830828696329673361L; - @ApiModelProperty(position = 4, value = "Starred timestamp") + @Schema(description = "Starred timestamp") private long starredAt; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java index ef0b01889c..61056a3ae0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserDashboardsInfo.java @@ -15,8 +15,7 @@ */ package org.thingsboard.server.common.data.settings; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; @@ -25,7 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -@ApiModel +@Schema @Data @AllArgsConstructor public class UserDashboardsInfo implements Serializable { @@ -33,10 +32,10 @@ public class UserDashboardsInfo implements Serializable { private static final long serialVersionUID = 2628320657987010348L; public static final UserDashboardsInfo EMPTY = new UserDashboardsInfo(Collections.emptyList(), Collections.emptyList()); - @ApiModelProperty(position = 1, value = "List of last visited dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "List of last visited dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private List last; - @ApiModelProperty(position = 2, value = "List of starred dashboards.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "List of starred dashboards.", accessMode = Schema.AccessMode.READ_ONLY) private List starred; public UserDashboardsInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java index cf48d9c215..34e80ae1d5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/settings/UserSettings.java @@ -17,8 +17,7 @@ package org.thingsboard.server.common.data.settings; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.validation.Length; @@ -29,21 +28,21 @@ import java.io.Serializable; import static org.thingsboard.server.common.data.BaseDataWithAdditionalInfo.getJson; import static org.thingsboard.server.common.data.BaseDataWithAdditionalInfo.setJson; -@ApiModel +@Schema @Data public class UserSettings implements Serializable { private static final long serialVersionUID = 2628320657987010348L; - @ApiModelProperty(position = 1, value = "JSON object with User id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with User id.", accessMode = Schema.AccessMode.READ_ONLY) private UserId userId; - @ApiModelProperty(position = 2, value = "Type of the settings.") + @Schema(description = "Type of the settings.") @NoXss @Length(fieldName = "type", max = 50) private UserSettingsType type; - @ApiModelProperty(position = 3, value = "JSON object with user settings.", dataType = "com.fasterxml.jackson.databind.JsonNode") + @Schema(description = "JSON object with user settings.",implementation = com.fasterxml.jackson.databind.JsonNode.class) @NoXss @Length(fieldName = "settings", max = 100000) private transient JsonNode settings; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java index c153c7a0a0..7c76f01807 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/AwsSnsSmsProviderConfiguration.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class AwsSnsSmsProviderConfiguration implements SmsProviderConfiguration { - @ApiModelProperty(position = 1, value = "The AWS SNS Access Key ID.") + @Schema(description = "The AWS SNS Access Key ID.") private String accessKeyId; - @ApiModelProperty(position = 2, value = "The AWS SNS Access Key.") + @Schema(description = "The AWS SNS Access Key.") private String secretAccessKey; - @ApiModelProperty(position = 3, value = "The AWS region.") + @Schema(description = "The AWS region.") private String region; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java index fddb4016b1..ba1f4461d4 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/SmppSmsProviderConfiguration.java @@ -15,34 +15,34 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @Data public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { - @ApiModelProperty(value = "SMPP version", allowableValues = "3.3, 3.4", required = true) + @Schema(description = "SMPP version", allowableValues = "3.3, 3.4", required = true) private String protocolVersion; - @ApiModelProperty(value = "SMPP host", required = true) + @Schema(description = "SMPP host", required = true) private String host; - @ApiModelProperty(value = "SMPP port", required = true) + @Schema(description = "SMPP port", required = true) private Integer port; - @ApiModelProperty(value = "System ID", required = true) + @Schema(description = "System ID", required = true) private String systemId; - @ApiModelProperty(value = "Password", required = true) + @Schema(description = "Password", required = true) private String password; - @ApiModelProperty(value = "System type", required = false) + @Schema(description = "System type", required = false) private String systemType; - @ApiModelProperty(value = "TX - Transmitter, RX - Receiver, TRX - Transciever. By default TX is used", required = false) + @Schema(description = "TX - Transmitter, RX - Receiver, TRX - Transciever. By default TX is used", required = false) private SmppBindType bindType; - @ApiModelProperty(value = "Service type", required = false) + @Schema(description = "Service type", required = false) private String serviceType; - @ApiModelProperty(value = "Source address", required = false) + @Schema(description = "Source address", required = false) private String sourceAddress; - @ApiModelProperty(value = "Source TON (Type of Number). Needed is source address is set. 5 by default.\n" + + @Schema(description = "Source TON (Type of Number). Needed is source address is set. 5 by default.\n" + "0 - Unknown\n" + "1 - International\n" + "2 - National\n" + @@ -51,7 +51,7 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "5 - Alphanumeric\n" + "6 - Abbreviated", required = false) private Byte sourceTon; - @ApiModelProperty(value = "Source NPI (Numbering Plan Identification). Needed is source address is set. 0 by default.\n" + + @Schema(description = "Source NPI (Numbering Plan Identification). Needed is source address is set. 0 by default.\n" + "0 - Unknown\n" + "1 - ISDN/telephone numbering plan (E163/E164)\n" + "3 - Data numbering plan (X.121)\n" + @@ -64,7 +64,7 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "18 - WAP Client Id (to be defined by WAP Forum)", required = false) private Byte sourceNpi; - @ApiModelProperty(value = "Destination TON (Type of Number). 5 by default.\n" + + @Schema(description = "Destination TON (Type of Number). 5 by default.\n" + "0 - Unknown\n" + "1 - International\n" + "2 - National\n" + @@ -73,7 +73,7 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "5 - Alphanumeric\n" + "6 - Abbreviated", required = false) private Byte destinationTon; - @ApiModelProperty(value = "Destination NPI (Numbering Plan Identification). 0 by default.\n" + + @Schema(description = "Destination NPI (Numbering Plan Identification). 0 by default.\n" + "0 - Unknown\n" + "1 - ISDN/telephone numbering plan (E163/E164)\n" + "3 - Data numbering plan (X.121)\n" + @@ -86,11 +86,11 @@ public class SmppSmsProviderConfiguration implements SmsProviderConfiguration { "18 - WAP Client Id (to be defined by WAP Forum)", required = false) private Byte destinationNpi; - @ApiModelProperty(value = "Address range", required = false) + @Schema(description = "Address range", required = false) private String addressRange; - @ApiModelProperty(allowableValues = "0-10,13-14", - value = "0 - SMSC Default Alphabet (ASCII for short and long code and to GSM for toll-free, used as default)\n" + + @Schema(allowableValues = "0-10,13-14", + description = "0 - SMSC Default Alphabet (ASCII for short and long code and to GSM for toll-free, used as default)\n" + "1 - IA5 (ASCII for short and long code, Latin 9 for toll-free (ISO-8859-9))\n" + "2 - Octet Unspecified (8-bit binary)\n" + "3 - Latin 1 (ISO-8859-1)\n" + diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java index 9a7e5fbfbf..5f792fc869 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TestSmsRequest.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class TestSmsRequest { - @ApiModelProperty(position = 1, value = "The SMS provider configuration") + @Schema(description = "The SMS provider configuration") private SmsProviderConfiguration providerConfiguration; - @ApiModelProperty(position = 2, value = "The phone number or other identifier to specify as a recipient of the SMS.") + @Schema(description = "The phone number or other identifier to specify as a recipient of the SMS.") private String numberTo; - @ApiModelProperty(position = 3, value = "The test message") + @Schema(description = "The test message") private String message; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java index 55cce68703..f9a5fb5c77 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sms/config/TwilioSmsProviderConfiguration.java @@ -15,19 +15,18 @@ */ package org.thingsboard.server.common.data.sms.config; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@ApiModel +@Schema @Data public class TwilioSmsProviderConfiguration implements SmsProviderConfiguration { - @ApiModelProperty(position = 1, value = "Twilio account Sid.") + @Schema(description = "Twilio account Sid.") private String accountSid; - @ApiModelProperty(position = 2, value = "Twilio account Token.") + @Schema(description = "Twilio account Token.") private String accountToken; - @ApiModelProperty(position = 3, value = "The number/id of a sender.") + @Schema(description = "The number/id of a sender.") private String numberFrom; @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java index 1def815cff..67427ac29d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/tenant/profile/TenantProfileData.java @@ -15,20 +15,19 @@ */ package org.thingsboard.server.common.data.tenant.profile; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; -@ApiModel +@Schema @Data public class TenantProfileData { - @ApiModelProperty(position = 1, value = "Complex JSON object that contains profile settings: max devices, max assets, rate limits, etc.") + @Schema(description = "Complex JSON object that contains profile settings: max devices, max assets, rate limits, etc.") private TenantProfileConfiguration configuration; - @ApiModelProperty(position = 2, value = "JSON array of queue configuration per tenant profile") + @Schema(description = "JSON array of queue configuration per tenant profile") private List queueConfiguration; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java index a7e9fee82a..7580bca240 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/BaseWidgetType.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.widget; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.HasName; @@ -30,19 +30,19 @@ public class BaseWidgetType extends BaseData implements HasName, H private static final long serialVersionUID = 8388684344603660756L; - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "bundleAlias") - @ApiModelProperty(position = 4, value = "Reference to widget bundle", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Reference to widget bundle", accessMode = Schema.AccessMode.READ_ONLY) private String bundleAlias; @NoXss @Length(fieldName = "alias") - @ApiModelProperty(position = 5, value = "Unique alias that is used in dashboards as a reference widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Unique alias that is used in dashboards as a reference widget type", accessMode = Schema.AccessMode.READ_ONLY) private String alias; @NoXss @Length(fieldName = "name") - @ApiModelProperty(position = 6, value = "Widget name used in search and UI", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Widget name used in search and UI", accessMode = Schema.AccessMode.READ_ONLY) private String name; public BaseWidgetType() { @@ -61,7 +61,7 @@ public class BaseWidgetType extends BaseData implements HasName, H this.name = widgetType.getName(); } - @ApiModelProperty(position = 1, value = "JSON object with the Widget Type Id. " + + @Schema(description = "JSON object with the Widget Type Id. " + "Specify this field to update the Widget Type. " + "Referencing non-existing Widget Type Id will cause error. " + "Omit this field to create new Widget Type." ) @@ -70,7 +70,7 @@ public class BaseWidgetType extends BaseData implements HasName, H return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Widget Type creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the Widget Type creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java index f726cfb71a..de6421c24c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java @@ -16,14 +16,14 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.databind.JsonNode; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.WidgetTypeId; @Data public class WidgetType extends BaseWidgetType { - @ApiModelProperty(position = 7, value = "Complex JSON object that describes the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Complex JSON object that describes the widget type", accessMode = Schema.AccessMode.READ_ONLY) private transient JsonNode descriptor; public WidgetType() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java index e6faece85d..0e06012c70 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.validation.Length; @@ -27,11 +27,11 @@ import org.thingsboard.server.common.data.validation.NoXss; public class WidgetTypeDetails extends WidgetType { @Length(fieldName = "image", max = 1000000) - @ApiModelProperty(position = 8, value = "Base64 encoded thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Base64 encoded thumbnail", accessMode = Schema.AccessMode.READ_ONLY) private String image; @NoXss @Length(fieldName = "description") - @ApiModelProperty(position = 9, value = "Description of the widget", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Description of the widget", accessMode = Schema.AccessMode.READ_ONLY) private String description; public WidgetTypeDetails() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java index f5c4abd66d..0ba8761af6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeInfo.java @@ -15,7 +15,7 @@ */ package org.thingsboard.server.common.data.widget; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.validation.NoXss; @@ -23,13 +23,13 @@ import org.thingsboard.server.common.data.validation.NoXss; @Data public class WidgetTypeInfo extends BaseWidgetType { - @ApiModelProperty(position = 7, value = "Base64 encoded widget thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Base64 encoded widget thumbnail", accessMode = Schema.AccessMode.READ_ONLY) private String image; @NoXss - @ApiModelProperty(position = 7, value = "Description of the widget type", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Description of the widget type", accessMode = Schema.AccessMode.READ_ONLY) private String description; @NoXss - @ApiModelProperty(position = 8, value = "Type of the widget (timeseries, latest, control, alarm or static)", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Type of the widget (timeseries, latest, control, alarm or static)", accessMode = Schema.AccessMode.READ_ONLY) private String widgetType; public WidgetTypeInfo() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java index 0ceef991ad..c93d08612f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java @@ -16,8 +16,7 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -32,7 +31,7 @@ import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.validation.Length; import org.thingsboard.server.common.data.validation.NoXss; -@ApiModel +@Schema @EqualsAndHashCode(callSuper = true) public class WidgetsBundle extends BaseData implements HasName, HasTenantId, ExportableEntity, HasTitle { @@ -40,34 +39,34 @@ public class WidgetsBundle extends BaseData implements HasName, @Getter @Setter - @ApiModelProperty(position = 3, value = "JSON object with Tenant Id.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "JSON object with Tenant Id.", accessMode = Schema.AccessMode.READ_ONLY) private TenantId tenantId; @NoXss @Length(fieldName = "alias") @Getter @Setter - @ApiModelProperty(position = 4, value = "Unique alias that is used in widget types as a reference widget bundle", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Unique alias that is used in widget types as a reference widget bundle", accessMode = Schema.AccessMode.READ_ONLY) private String alias; @NoXss @Length(fieldName = "title") @Getter @Setter - @ApiModelProperty(position = 5, value = "Title used in search and UI", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Title used in search and UI", accessMode = Schema.AccessMode.READ_ONLY) private String title; @Length(fieldName = "image", max = 1000000) @Getter @Setter - @ApiModelProperty(position = 6, value = "Base64 encoded thumbnail", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Base64 encoded thumbnail", accessMode = Schema.AccessMode.READ_ONLY) private String image; @NoXss @Length(fieldName = "description") @Getter @Setter - @ApiModelProperty(position = 7, value = "Description", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Description", accessMode = Schema.AccessMode.READ_ONLY) private String description; @Getter @@ -92,7 +91,7 @@ public class WidgetsBundle extends BaseData implements HasName, this.externalId = widgetsBundle.getExternalId(); } - @ApiModelProperty(position = 1, value = "JSON object with the Widget Bundle Id. " + + @Schema(description = "JSON object with the Widget Bundle Id. " + "Specify this field to update the Widget Bundle. " + "Referencing non-existing Widget Bundle Id will cause error. " + "Omit this field to create new Widget Bundle." ) @@ -101,13 +100,13 @@ public class WidgetsBundle extends BaseData implements HasName, return super.getId(); } - @ApiModelProperty(position = 2, value = "Timestamp of the Widget Bundle creation, in milliseconds", example = "1609459200000", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Timestamp of the Widget Bundle creation, in milliseconds", example = "1609459200000", accessMode = Schema.AccessMode.READ_ONLY) @Override public long getCreatedTime() { return super.getCreatedTime(); } - @ApiModelProperty(position = 3, value = "Same as title of the Widget Bundle. Read-only field. Update the 'title' to change the 'name' of the Widget Bundle.", accessMode = ApiModelProperty.AccessMode.READ_ONLY) + @Schema(description = "Same as title of the Widget Bundle. Read-only field. Update the 'title' to change the 'name' of the Widget Bundle.", accessMode = Schema.AccessMode.READ_ONLY) @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) public String getName() { diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index cf0b25ec90..a5e4f2af54 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -17,8 +17,11 @@ package org.thingsboard.server.transport.http; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -127,22 +130,22 @@ public class DeviceApiController implements TbTransportService { @Autowired private HttpTransportContext transportContext; - @ApiOperation(value = "Get attributes (getDeviceAttributes)", - notes = "Returns all attributes that belong to device. " + @Operation(summary = "Get attributes (getDeviceAttributes)", + description = "Returns all attributes that belong to device. " + "Use optional 'clientKeys' and/or 'sharedKeys' parameter to return specific attributes. " + "\n Example of the result: " + MARKDOWN_CODE_BLOCK_START + ATTRIBUTE_PAYLOAD_EXAMPLE + MARKDOWN_CODE_BLOCK_END + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) - @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.GET, produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) + @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public DeferredResult getDeviceAttributes( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Comma separated key names for attribute with client scope", required = true, defaultValue = "state") + @Parameter(description = "Comma separated key names for attribute with client scope", required = true , schema = @Schema(defaultValue = "state")) @RequestParam(value = "clientKeys", required = false, defaultValue = "") String clientKeys, - @ApiParam(value = "Comma separated key names for attribute with shared scope", required = true, defaultValue = "configuration") + @Parameter(description = "Comma separated key names for attribute with shared scope", required = true , schema = @Schema(defaultValue = "configuration")) @RequestParam(value = "sharedKeys", required = false, defaultValue = "") String sharedKeys) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -165,19 +168,19 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Post attributes (postDeviceAttributes)", - notes = "Post client attribute updates on behalf of device. " + @Operation(summary = "Post attributes (postDeviceAttributes)", + description = "Post client attribute updates on behalf of device. " + "\n Example of the request: " + MARKDOWN_CODE_BLOCK_START + ATTRIBUTE_PAYLOAD_EXAMPLE + MARKDOWN_CODE_BLOCK_END + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/attributes", method = RequestMethod.POST) public DeferredResult postDeviceAttributes( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "JSON with attribute key-value pairs. See API call description for example.") + @Parameter(description = "JSON with attribute key-value pairs. See API call description for example.") @RequestBody String json) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -189,15 +192,15 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Post time-series data (postTelemetry)", - notes = "Post time-series data on behalf of device. " + @Operation(summary = "Post time-series data (postTelemetry)", + description = "Post time-series data on behalf of device. " + "\n Example of the request: " + TS_PAYLOAD + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/telemetry", method = RequestMethod.POST) public DeferredResult postTelemetry( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, @RequestBody String json, HttpServletRequest request) { DeferredResult responseWriter = new DeferredResult(); @@ -210,8 +213,8 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Save claiming information (claimDevice)", - notes = "Saves the information required for user to claim the device. " + + @Operation(summary = "Save claiming information (claimDevice)", + description = "Saves the information required for user to claim the device. " + "See more info about claiming in the corresponding 'Claiming devices' platform documentation." + "\n Example of the request payload: " + MARKDOWN_CODE_BLOCK_START @@ -220,10 +223,10 @@ public class DeviceApiController implements TbTransportService { + "Note: both 'secretKey' and 'durationMs' is optional parameters. " + "In case the secretKey is not specified, the empty string as a default value is used. In case the durationMs is not specified, the system parameter device.claim.duration is used.\n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/claim", method = RequestMethod.POST) public DeferredResult claimDevice( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, @RequestBody(required = false) String json) { DeferredResult responseWriter = new DeferredResult<>(); @@ -237,17 +240,17 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Subscribe to RPC commands (subscribeToCommands) (Deprecated)", - notes = "Subscribes to RPC commands using http long polling. " + + @Operation(summary = "Subscribe to RPC commands (subscribeToCommands) (Deprecated)", + description = "Subscribes to RPC commands using http long polling. " + "Deprecated, since long polling is resource and network consuming. " + "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) - @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.GET, produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) + @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public DeferredResult subscribeToCommands( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") + @Parameter(description = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -263,17 +266,17 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Reply to RPC commands (replyToCommand)", - notes = "Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON.\n\n" + + @Operation(summary = "Reply to RPC commands (replyToCommand)", + description = "Replies to server originated RPC command identified by 'requestId' parameter. The response is arbitrary JSON.\n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/rpc/{requestId}", method = RequestMethod.POST) public DeferredResult replyToCommand( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "RPC request id from the incoming RPC request", required = true, defaultValue = "123") + @Parameter(description = "RPC request id from the incoming RPC request", required = true , schema = @Schema(defaultValue = "123")) @PathVariable("requestId") Integer requestId, - @ApiParam(value = "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", required = true) + @Parameter(description = "Reply to the RPC request, JSON. For example: {\"status\":\"success\"}", required = true) @RequestBody String json) { DeferredResult responseWriter = new DeferredResult(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -284,8 +287,8 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Send the RPC command (postRpcRequest)", - notes = "Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example:" + + @Operation(summary = "Send the RPC command (postRpcRequest)", + description = "Send the RPC request to server. The request payload is a JSON document that contains 'method' and 'params'. For example:" + MARKDOWN_CODE_BLOCK_START + "{\"method\": \"sumOnServer\", \"params\":{\"a\":2, \"b\":2}}" + MARKDOWN_CODE_BLOCK_END + @@ -294,12 +297,12 @@ public class DeviceApiController implements TbTransportService { "{\"result\": 4}" + MARKDOWN_CODE_BLOCK_END + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/rpc", method = RequestMethod.POST) public DeferredResult postRpcRequest( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "The RPC request JSON", required = true) + @Parameter(description = "The RPC request JSON", required = true) @RequestBody String json) { DeferredResult responseWriter = new DeferredResult(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -317,17 +320,17 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Subscribe to attribute updates (subscribeToAttributes) (Deprecated)", - notes = "Subscribes to client and shared scope attribute updates using http long polling. " + + @Operation(summary = "Subscribe to attribute updates (subscribeToAttributes) (Deprecated)", + description = "Subscribes to client and shared scope attribute updates using http long polling. " + "Deprecated, since long polling is resource and network consuming. " + "Consider using MQTT or CoAP protocol for light-weight real-time updates. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) - @RequestMapping(value = "/{deviceToken}/attributes/updates", method = RequestMethod.GET, produces = "application/json") + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) + @RequestMapping(value = "/{deviceToken}/attributes/updates", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public DeferredResult subscribeToAttributes( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") + @Parameter(description = "Optional timeout of the long poll. Typically less then 60 seconds, since limited on the server side.") @RequestParam(value = "timeout", required = false, defaultValue = "0") long timeout) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(DeviceTransportType.DEFAULT, ValidateDeviceTokenRequestMsg.newBuilder().setToken(deviceToken).build(), @@ -343,8 +346,8 @@ public class DeviceApiController implements TbTransportService { return responseWriter; } - @ApiOperation(value = "Get Device Firmware (getFirmware)", - notes = "Downloads the current firmware package." + + @Operation(summary = "Get Device Firmware (getFirmware)", + description = "Downloads the current firmware package." + "When the platform initiates firmware update, " + "it informs the device by updating the 'fw_title', 'fw_version', 'fw_checksum' and 'fw_checksum_algorithm' shared attributes." + "The 'fw_title' and 'fw_version' parameters must be supplied in this request to double-check " + @@ -354,24 +357,24 @@ public class DeviceApiController implements TbTransportService { "For example, device may request first 16 KB of firmware using 'chunk'=0 and 'size'=16384. " + "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/firmware", method = RequestMethod.GET) public DeferredResult getFirmware( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Title of the firmware, corresponds to the value of 'fw_title' attribute.", required = true) + @Parameter(description = "Title of the firmware, corresponds to the value of 'fw_title' attribute.", required = true) @RequestParam(value = "title") String title, - @ApiParam(value = "Version of the firmware, corresponds to the value of 'fw_version' attribute.", required = true) + @Parameter(description = "Version of the firmware, corresponds to the value of 'fw_version' attribute.", required = true) @RequestParam(value = "version") String version, - @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without chunks.") + @Parameter(description = "Size of the chunk. Optional. Omit to download the entire file without chunks.") @RequestParam(value = "size", required = false, defaultValue = "0") int size, - @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without chunks.") + @Parameter(description = "Index of the chunk. Optional. Omit to download the entire file without chunks.") @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.FIRMWARE); } - @ApiOperation(value = "Get Device Software (getSoftware)", - notes = "Downloads the current software package." + + @Operation(summary = "Get Device Software (getSoftware)", + description = "Downloads the current software package." + "When the platform initiates software update, " + "it informs the device by updating the 'sw_title', 'sw_version', 'sw_checksum' and 'sw_checksum_algorithm' shared attributes." + "The 'sw_title' and 'sw_version' parameters must be supplied in this request to double-check " + @@ -381,24 +384,24 @@ public class DeviceApiController implements TbTransportService { "For example, device may request first 16 KB of software using 'chunk'=0 and 'size'=16384. " + "Next 16KB using 'chunk'=1 and 'size'=16384. The last chunk should have less bytes then requested using 'size' parameter. \n\n" + REQUIRE_ACCESS_TOKEN, - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/{deviceToken}/software", method = RequestMethod.GET) public DeferredResult getSoftware( - @ApiParam(value = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true, defaultValue = "YOUR_DEVICE_ACCESS_TOKEN") + @Parameter(description = ACCESS_TOKEN_PARAM_DESCRIPTION, required = true , schema = @Schema(defaultValue = "YOUR_DEVICE_ACCESS_TOKEN")) @PathVariable("deviceToken") String deviceToken, - @ApiParam(value = "Title of the software, corresponds to the value of 'sw_title' attribute.", required = true) + @Parameter(description = "Title of the software, corresponds to the value of 'sw_title' attribute.", required = true) @RequestParam(value = "title") String title, - @ApiParam(value = "Version of the software, corresponds to the value of 'sw_version' attribute.", required = true) + @Parameter(description = "Version of the software, corresponds to the value of 'sw_version' attribute.", required = true) @RequestParam(value = "version") String version, - @ApiParam(value = "Size of the chunk. Optional. Omit to download the entire file without using chunks.") + @Parameter(description = "Size of the chunk. Optional. Omit to download the entire file without using chunks.") @RequestParam(value = "size", required = false, defaultValue = "0") int size, - @ApiParam(value = "Index of the chunk. Optional. Omit to download the entire file without using chunks.") + @Parameter(description = "Index of the chunk. Optional. Omit to download the entire file without using chunks.") @RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk) { return getOtaPackageCallback(deviceToken, title, version, size, chunk, OtaPackageType.SOFTWARE); } - @ApiOperation(value = "Provision new device (provisionDevice)", - notes = "Exchange the provision request to the device credentials. " + + @Operation(summary = "Provision new device (provisionDevice)", + description = "Exchange the provision request to the device credentials. " + "See more info about provisioning in the corresponding 'Device provisioning' platform documentation." + "Requires valid JSON request with the following format: " + MARKDOWN_CODE_BLOCK_START + @@ -417,10 +420,10 @@ public class DeviceApiController implements TbTransportService { " \"status\":\"SUCCESS\"\n" + "}" + MARKDOWN_CODE_BLOCK_END , - produces = MediaType.APPLICATION_JSON_VALUE) + responses = @ApiResponse(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))) @RequestMapping(value = "/provision", method = RequestMethod.POST) public DeferredResult provisionDevice( - @ApiParam(value = "JSON with provision request. See API call description for example.") + @Parameter(description = "JSON with provision request. See API call description for example.") @RequestBody String json) { DeferredResult responseWriter = new DeferredResult<>(); transportContext.getTransportService().process(JsonConverter.convertToProvisionRequestMsg(json), diff --git a/pom.xml b/pom.xml index b5475cc655..9d0fc4fe15 100755 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 3.11.14 31.1-jre 2.6.1 - 3.4 + 3.12.0 1.15 2.11.0 1.2 @@ -92,8 +92,8 @@ 4.8.0 3.0.0-M9 3.0.2 - 3.0.4 - 1.6.3 + 2.1.0 + 2.2.9 0.7 1.18.2 1.69 @@ -135,7 +135,7 @@ 1.5.2 5.9.3 2.6.0 - 5.13.1 + 5.15.0 1.3.0 1.2.7 @@ -143,7 +143,7 @@ 3.23.1 5.2.0 1.3 - 1.17.3 + 1.18.3 1.12 3.0.0 6.1.0.202203080745-r @@ -1768,13 +1768,13 @@ ${curator.version} - org.thingsboard - springfox-boot-starter - ${springfox-swagger.version} + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc-swagger.version} - io.swagger - swagger-annotations + io.swagger.core.v3 + swagger-annotations-jakarta ${swagger-annotations.version} @@ -2010,6 +2010,16 @@ mockserver-netty ${mock-server.version} test + + + io.swagger.parser.v3 + swagger-parser-v2-converter + + + io.swagger.parser.v3 + swagger-parser + + org.mock-server From 0e72c36628168e8c0362bbeb7948621e0a8613a5 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 12 Jun 2023 14:42:50 +0200 Subject: [PATCH 14/61] minor improvements --- pom.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pom.xml b/pom.xml index 9d0fc4fe15..9419e1aede 100755 --- a/pom.xml +++ b/pom.xml @@ -2010,16 +2010,6 @@ mockserver-netty ${mock-server.version} test - - - io.swagger.parser.v3 - swagger-parser-v2-converter - - - io.swagger.parser.v3 - swagger-parser - - org.mock-server From c6771d9fc90e8297b9fed320b2f979c305e6c807 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 12 Jun 2023 23:02:43 +0200 Subject: [PATCH 15/61] fixed TestRestClient, swagger config improvements --- .../server/config/SwaggerConfiguration.java | 46 +++++++++++-------- .../server/controller/AlarmController.java | 23 ++++------ .../server/msa/TestRestClient.java | 2 +- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java index 50104e866d..4de7cee7c4 100644 --- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java @@ -89,7 +89,7 @@ public class SwaggerConfiguration { private String appVersion; @Bean - public OpenAPI tbOpenAPI() { + public OpenAPI thingsboardApi() { Contact contact = new Contact() .name(contactName) .url(contactUrl) @@ -193,7 +193,7 @@ public class SwaggerConfiguration { } @Bean - public GroupedOpenApi thingsboardApi() { + public GroupedOpenApi groupedApi() { return GroupedOpenApi.builder() .group("thingsboard") .pathsToMatch(apiPath) @@ -230,24 +230,32 @@ public class SwaggerConfiguration { } public OpenApiCustomizer customOpenApiCustomizer() { - SecurityRequirement loginForm = new SecurityRequirement().addList("HTTP login form"); - + var loginForm = new SecurityRequirement().addList("HTTP login form"); return openAPI -> openAPI.getPaths().entrySet().stream().peek(entry -> { - if (!(entry.getKey().matches(nonSecurityPathRegex) || entry.getKey().equals(LOGIN_ENDPOINT))) { - entry.getValue() - .readOperationsMap() - .values() - .forEach(operation -> operation.addSecurityItem(loginForm)); - } - - entry.getValue().readOperationsMap().forEach(((httpMethod, operation) -> { - operation.setResponses(getResponses(operation.getResponses(), httpMethod.equals(PathItem.HttpMethod.POST))); - })); - - }).map(entry -> { - String tagItem = entry.getValue().readOperationsMap().values().stream().findAny().get().getTags().get(0); - return tagFromTagItem(tagItem); - }).forEach(openAPI::addTagsItem); + securityCustomization(loginForm, entry); + defaultErrorResponsesCustomization(entry.getValue()); + }).map(this::tagsCustomization).forEach(openAPI::addTagsItem); + } + + private Tag tagsCustomization(Map.Entry entry) { + var operations = entry.getValue().readOperationsMap().values(); + var tagItem = operations.stream().findAny().get().getTags().get(0); + return tagFromTagItem(tagItem); + } + + private void defaultErrorResponsesCustomization(PathItem pathItem) { + pathItem.readOperationsMap().forEach(((httpMethod, operation) -> { + operation.setResponses(getResponses(operation.getResponses(), httpMethod.equals(PathItem.HttpMethod.POST))); + })); + } + + private void securityCustomization(SecurityRequirement loginForm, Map.Entry entry) { + if (!(entry.getKey().matches(nonSecurityPathRegex) || entry.getKey().equals(LOGIN_ENDPOINT))) { + entry.getValue() + .readOperationsMap() + .values() + .forEach(operation -> operation.addSecurityItem(loginForm)); + } } private Tag tagFromTagItem(String tagItem) { diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 18ad89f1a0..183ffbd0de 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -90,11 +90,8 @@ public class AlarmController extends BaseController { private static final String ALARM_QUERY_SEARCH_STATUS_DESCRIPTION = "A string value representing one of the AlarmSearchStatus enumeration value"; private static final String ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION = "A list of string values separated by comma ',' representing one of the AlarmSearchStatus enumeration value"; - private static final String ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES = "ANY, ACTIVE, CLEARED, ACK, UNACK"; private static final String ALARM_QUERY_STATUS_DESCRIPTION = "A string value representing one of the AlarmStatus enumeration value"; - private static final String ALARM_QUERY_STATUS_ALLOWABLE_VALUES = "ACTIVE_UNACK, ACTIVE_ACK, CLEARED_UNACK, CLEARED_ACK"; private static final String ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION = "A list of string values separated by comma ',' representing one of the AlarmSeverity enumeration value"; - private static final String ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES = "CRITICAL, MAJOR, MINOR, WARNING, INDETERMINATE"; private static final String ALARM_QUERY_TYPE_ARRAY_DESCRIPTION = "A list of string values separated by comma ',' representing alarm types"; private static final String ALARM_QUERY_ASSIGNEE_DESCRIPTION = "A string value representing the assignee user id. For example, '784f394c-42b6-435a-983c-b7beff2784f9'"; @@ -246,9 +243,9 @@ public class AlarmController extends BaseController { @PathVariable(ENTITY_TYPE) String strEntityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = {"ANY", "ACTIVE", "CLEARED", "ACK", "UNACK"})) @RequestParam(required = false) String searchStatus, - @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = {"ACTIVE_UNACK", "ACTIVE_ACK", "CLEARED_UNACK", "CLEARED_ACK"})) @RequestParam(required = false) String status, @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, @@ -298,9 +295,9 @@ public class AlarmController extends BaseController { @RequestMapping(value = "/alarms", method = RequestMethod.GET) @ResponseBody public PageData getAllAlarms( - @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = {"ANY", "ACTIVE", "CLEARED", "ACK", "UNACK"})) @RequestParam(required = false) String searchStatus, - @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = {"ACTIVE_UNACK", "ACTIVE_ACK", "CLEARED_UNACK", "CLEARED_ACK"})) @RequestParam(required = false) String status, @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId, @@ -351,9 +348,9 @@ public class AlarmController extends BaseController { @PathVariable(ENTITY_TYPE) String strEntityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = {"ANY", "ACTIVE", "CLEARED", "ACK", "UNACK"})) @RequestParam(required = false) String[] statusList, - @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = {"CRITICAL", "MAJOR", "MINOR", "WARNING", "INDETERMINATE"})) @RequestParam(required = false) String[] severityList, @Parameter(description = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) @RequestParam(required = false) String[] typeList, @@ -413,9 +410,9 @@ public class AlarmController extends BaseController { @RequestMapping(value = "/v2/alarms", method = RequestMethod.GET) @ResponseBody public PageData getAllAlarmsV2( - @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = {"ANY", "ACTIVE", "CLEARED", "ACK", "UNACK"})) @RequestParam(required = false) String[] statusList, - @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEVERITY_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_SEVERITY_ARRAY_DESCRIPTION, schema = @Schema(allowableValues = {"CRITICAL", "MAJOR", "MINOR", "WARNING", "INDETERMINATE"})) @RequestParam(required = false) String[] severityList, @Parameter(description = ALARM_QUERY_TYPE_ARRAY_DESCRIPTION) @RequestParam(required = false) String[] typeList, @@ -478,9 +475,9 @@ public class AlarmController extends BaseController { @PathVariable(ENTITY_TYPE) String strEntityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable(ENTITY_ID) String strEntityId, - @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_SEARCH_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_SEARCH_STATUS_DESCRIPTION, schema = @Schema(allowableValues = {"ANY", "ACTIVE", "CLEARED", "ACK", "UNACK"})) @RequestParam(required = false) String searchStatus, - @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = ALARM_QUERY_STATUS_ALLOWABLE_VALUES)) + @Parameter(description = ALARM_QUERY_STATUS_DESCRIPTION, schema = @Schema(allowableValues = {"ACTIVE_UNACK", "ACTIVE_ACK", "CLEARED_UNACK", "CLEARED_ACK"})) @RequestParam(required = false) String status, @Parameter(description = ALARM_QUERY_ASSIGNEE_DESCRIPTION) @RequestParam(required = false) String assigneeId diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java index f04331e01e..4d489b116e 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestRestClient.java @@ -183,7 +183,7 @@ public class TestRestClient { public ValidatableResponse postAttribute(String accessToken, JsonNode attribute) { return given().spec(requestSpec).body(attribute) - .post("/api/v1/{accessToken}/attributes/", accessToken) + .post("/api/v1/{accessToken}/attributes", accessToken) .then() .statusCode(HTTP_OK); } From d67d15b0d755dc7ceae0a0d6e6e2c1d99ba64303 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Wed, 14 Jun 2023 23:25:51 +0200 Subject: [PATCH 16/61] added ssl context for TbHttpClient --- .../java/org/thingsboard/rule/engine/rest/TbHttpClient.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java index 7a5ca407af..e7e76aa52e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java @@ -16,6 +16,7 @@ package org.thingsboard.rule.engine.rest; import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; import io.netty.handler.timeout.ReadTimeoutHandler; import lombok.Data; import lombok.extern.slf4j.Slf4j; @@ -113,6 +114,8 @@ public class TbHttpClient { o.username(proxyUser).password(u -> proxyPassword); } }); + SslContext sslContext = SslContextBuilder.forClient().build(); + httpClient.secure(t -> t.sslContext(sslContext)); } } else if (!config.isUseSimpleClientHttpFactory()) { if (CredentialsType.CERT_PEM == config.getCredentials().getType()) { From 85887fa9af8dfd42b800aba558759e28ca99920c Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 16 Jun 2023 11:25:32 +0200 Subject: [PATCH 17/61] remove default error responses from login endpoint --- .../org/thingsboard/server/config/SwaggerConfiguration.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java index 4de7cee7c4..7be938274e 100644 --- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java @@ -233,7 +233,9 @@ public class SwaggerConfiguration { var loginForm = new SecurityRequirement().addList("HTTP login form"); return openAPI -> openAPI.getPaths().entrySet().stream().peek(entry -> { securityCustomization(loginForm, entry); - defaultErrorResponsesCustomization(entry.getValue()); + if (!entry.getKey().equals(LOGIN_ENDPOINT)) { + defaultErrorResponsesCustomization(entry.getValue()); + } }).map(this::tagsCustomization).forEach(openAPI::addTagsItem); } From 16c639b8a5b5d4ff3cd171a9240512619700c58e Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 30 Jun 2023 11:47:08 +0200 Subject: [PATCH 18/61] improvements --- .../server/service/mail/DefaultTbMailConfigTemplateService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java index cb502e7e51..e671a146b4 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultTbMailConfigTemplateService.java @@ -21,7 +21,7 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; -import javax.annotation.PostConstruct; +import jakarta.annotation.PostConstruct; import java.io.IOException; @Service From e00e67c9c7a2c4ff4771d4bda9561191c4c5141e Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Fri, 30 Jun 2023 15:07:27 +0200 Subject: [PATCH 19/61] TbHttpClient EventLoop inprovements --- .../java/org/thingsboard/rule/engine/rest/TbHttpClient.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java index 20d43a021c..1a71124054 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java @@ -125,12 +125,9 @@ public class TbHttpClient { if (CredentialsType.CERT_PEM == config.getCredentials().getType()) { throw new TbNodeException("Simple HTTP Factory does not support CERT PEM credentials!"); } - - httpClient = HttpClient.create(); - } else { SslContext sslContext = config.getCredentials().initSslContext(); - httpClient = HttpClient.create().secure(t -> t.sslContext(sslContext)); + httpClient = httpClient.secure(t -> t.sslContext(sslContext)); } this.webClient = WebClient.builder() From b194f98ebf8ec6adc4fe78b10010c78b681fe553 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 3 Jul 2023 14:26:10 +0200 Subject: [PATCH 20/61] fixed resource cache --- .../server/cache/resourceInfo/ResourceInfoRedisCache.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoRedisCache.java b/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoRedisCache.java index fee14e1ca1..f17bbd2797 100644 --- a/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoRedisCache.java +++ b/common/cache/src/main/java/org/thingsboard/server/cache/resourceInfo/ResourceInfoRedisCache.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.CacheSpecsMap; import org.thingsboard.server.cache.RedisTbTransactionalCache; import org.thingsboard.server.cache.TBRedisCacheConfiguration; -import org.thingsboard.server.cache.TbFSTRedisSerializer; +import org.thingsboard.server.cache.TbJavaRedisSerializer; import org.thingsboard.server.common.data.CacheConstants; import org.thingsboard.server.common.data.TbResourceInfo; @@ -30,6 +30,6 @@ import org.thingsboard.server.common.data.TbResourceInfo; public class ResourceInfoRedisCache extends RedisTbTransactionalCache { public ResourceInfoRedisCache(TBRedisCacheConfiguration configuration, CacheSpecsMap cacheSpecsMap, RedisConnectionFactory connectionFactory) { - super(CacheConstants.RESOURCE_INFO_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbFSTRedisSerializer<>()); + super(CacheConstants.RESOURCE_INFO_CACHE, cacheSpecsMap, connectionFactory, configuration, new TbJavaRedisSerializer<>()); } } From 1bcea1a3fc9ebb6c937704e07a867d8944a10f35 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 11 Jul 2023 12:19:01 +0200 Subject: [PATCH 21/61] swagger improvements --- .../org/thingsboard/server/config/SwaggerConfiguration.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java index 7be938274e..946d2cf2a2 100644 --- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java @@ -33,6 +33,7 @@ import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; import io.swagger.v3.oas.models.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springdoc.core.customizers.OpenApiCustomizer; @@ -52,6 +53,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.rest.LoginRequest; import org.thingsboard.server.service.security.auth.rest.LoginResponse; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -113,12 +115,13 @@ public class SwaggerConfiguration { SecurityScheme securityScheme = new SecurityScheme() .type(SecurityScheme.Type.HTTP) - .scheme("basic") + .scheme("bearer") .bearerFormat("JWT") .in(SecurityScheme.In.HEADER) .description("Enter Username / Password"); var openApi = new OpenAPI() + .addServersItem(new Server().url("/").description("Default Server URL")) .components(new Components().addSecuritySchemes("HTTP login form", securityScheme)) .info(info); addLoginOperation(openApi); From dd4b874b5f4328e6a7384a222e1a804fe2385646 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Wed, 27 Sep 2023 17:38:27 +0300 Subject: [PATCH 22/61] Version set to 3.6.1-SNAPSHOT --- application/pom.xml | 2 +- common/actor/pom.xml | 2 +- common/cache/pom.xml | 2 +- common/cluster-api/pom.xml | 2 +- common/coap-server/pom.xml | 2 +- common/dao-api/pom.xml | 2 +- common/data/pom.xml | 2 +- common/edge-api/pom.xml | 2 +- common/message/pom.xml | 2 +- common/pom.xml | 2 +- common/proto/pom.xml | 2 +- common/queue/pom.xml | 2 +- common/script/pom.xml | 2 +- common/script/remote-js-client/pom.xml | 2 +- common/script/script-api/pom.xml | 2 +- common/stats/pom.xml | 2 +- common/transport/coap/pom.xml | 2 +- common/transport/http/pom.xml | 2 +- common/transport/lwm2m/pom.xml | 2 +- common/transport/mqtt/pom.xml | 2 +- common/transport/pom.xml | 2 +- common/transport/snmp/pom.xml | 2 +- common/transport/transport-api/pom.xml | 2 +- common/util/pom.xml | 2 +- common/version-control/pom.xml | 2 +- dao/pom.xml | 2 +- monitoring/pom.xml | 2 +- msa/black-box-tests/pom.xml | 2 +- msa/js-executor/pom.xml | 2 +- msa/monitoring/pom.xml | 2 +- msa/pom.xml | 2 +- msa/tb-node/pom.xml | 2 +- msa/tb/pom.xml | 2 +- msa/transport/coap/pom.xml | 2 +- msa/transport/http/pom.xml | 2 +- msa/transport/lwm2m/pom.xml | 2 +- msa/transport/mqtt/pom.xml | 2 +- msa/transport/pom.xml | 2 +- msa/transport/snmp/pom.xml | 2 +- msa/vc-executor-docker/pom.xml | 2 +- msa/vc-executor/pom.xml | 2 +- msa/web-ui/pom.xml | 2 +- netty-mqtt/pom.xml | 4 ++-- pom.xml | 2 +- rest-client/pom.xml | 2 +- rule-engine/pom.xml | 2 +- rule-engine/rule-engine-api/pom.xml | 2 +- rule-engine/rule-engine-components/pom.xml | 2 +- tools/pom.xml | 2 +- transport/coap/pom.xml | 2 +- transport/http/pom.xml | 2 +- transport/lwm2m/pom.xml | 2 +- transport/mqtt/pom.xml | 2 +- transport/pom.xml | 2 +- transport/snmp/pom.xml | 2 +- ui-ngx/pom.xml | 2 +- 56 files changed, 57 insertions(+), 57 deletions(-) diff --git a/application/pom.xml b/application/pom.xml index fe235cc85c..bcdd55e6bf 100644 --- a/application/pom.xml +++ b/application/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard application diff --git a/common/actor/pom.xml b/common/actor/pom.xml index 2de85be932..7fa770c811 100644 --- a/common/actor/pom.xml +++ b/common/actor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/cache/pom.xml b/common/cache/pom.xml index a14c84d3f4..47e2800538 100644 --- a/common/cache/pom.xml +++ b/common/cache/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/cluster-api/pom.xml b/common/cluster-api/pom.xml index e940f246c8..cddc33e7fa 100644 --- a/common/cluster-api/pom.xml +++ b/common/cluster-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/coap-server/pom.xml b/common/coap-server/pom.xml index 420fc4dae6..d4b54af0b5 100644 --- a/common/coap-server/pom.xml +++ b/common/coap-server/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml index 6cfb7706a8..bde363c6dd 100644 --- a/common/dao-api/pom.xml +++ b/common/dao-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/data/pom.xml b/common/data/pom.xml index 9aa6aed2c0..49623ccc26 100644 --- a/common/data/pom.xml +++ b/common/data/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/edge-api/pom.xml b/common/edge-api/pom.xml index 60562efbf2..71d6a42819 100644 --- a/common/edge-api/pom.xml +++ b/common/edge-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/message/pom.xml b/common/message/pom.xml index e64d4676ce..2a8171ec72 100644 --- a/common/message/pom.xml +++ b/common/message/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/pom.xml b/common/pom.xml index 0c80189acf..4dcf1d737a 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard common diff --git a/common/proto/pom.xml b/common/proto/pom.xml index ab2cdf91c9..cccac11145 100644 --- a/common/proto/pom.xml +++ b/common/proto/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/queue/pom.xml b/common/queue/pom.xml index 59e96d210d..a0d0f55559 100644 --- a/common/queue/pom.xml +++ b/common/queue/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/script/pom.xml b/common/script/pom.xml index 26f60bd358..dcd5c6bc55 100644 --- a/common/script/pom.xml +++ b/common/script/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/script/remote-js-client/pom.xml b/common/script/remote-js-client/pom.xml index 8fa852d977..e0ad5ec3b1 100644 --- a/common/script/remote-js-client/pom.xml +++ b/common/script/remote-js-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT script org.thingsboard.common.script diff --git a/common/script/script-api/pom.xml b/common/script/script-api/pom.xml index ff835d6335..b2ddd48f86 100644 --- a/common/script/script-api/pom.xml +++ b/common/script/script-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT script org.thingsboard.common.script diff --git a/common/stats/pom.xml b/common/stats/pom.xml index 0869243e7a..6514b65b2a 100644 --- a/common/stats/pom.xml +++ b/common/stats/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/coap/pom.xml b/common/transport/coap/pom.xml index 2ac15d3e42..52758820cf 100644 --- a/common/transport/coap/pom.xml +++ b/common/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/http/pom.xml b/common/transport/http/pom.xml index 8cf3e0efe8..bcd05edba4 100644 --- a/common/transport/http/pom.xml +++ b/common/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/lwm2m/pom.xml b/common/transport/lwm2m/pom.xml index 4433eae2b9..c2a5d8bd4b 100644 --- a/common/transport/lwm2m/pom.xml +++ b/common/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/mqtt/pom.xml b/common/transport/mqtt/pom.xml index bb4767640c..0baf8be935 100644 --- a/common/transport/mqtt/pom.xml +++ b/common/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/transport/pom.xml b/common/transport/pom.xml index 6879a4924d..be175ae817 100644 --- a/common/transport/pom.xml +++ b/common/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/transport/snmp/pom.xml b/common/transport/snmp/pom.xml index 1865f498fa..be95664251 100644 --- a/common/transport/snmp/pom.xml +++ b/common/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml index b45cd28e52..619b65daf7 100644 --- a/common/transport/transport-api/pom.xml +++ b/common/transport/transport-api/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.common - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.common.transport diff --git a/common/util/pom.xml b/common/util/pom.xml index 59669b11fd..275fbf3842 100644 --- a/common/util/pom.xml +++ b/common/util/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/common/version-control/pom.xml b/common/version-control/pom.xml index 370ecc24a9..a5e1d437c8 100644 --- a/common/version-control/pom.xml +++ b/common/version-control/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT common org.thingsboard.common diff --git a/dao/pom.xml b/dao/pom.xml index b63990109a..30bd6c9ba3 100644 --- a/dao/pom.xml +++ b/dao/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard dao diff --git a/monitoring/pom.xml b/monitoring/pom.xml index 399e34092d..989cd113af 100644 --- a/monitoring/pom.xml +++ b/monitoring/pom.xml @@ -21,7 +21,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml index 12d36272c0..341bdbb560 100644 --- a/msa/black-box-tests/pom.xml +++ b/msa/black-box-tests/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index 0bd7bf4d60..128479e5eb 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/monitoring/pom.xml b/msa/monitoring/pom.xml index ba96ada39c..092bcfccc8 100644 --- a/msa/monitoring/pom.xml +++ b/msa/monitoring/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa diff --git a/msa/pom.xml b/msa/pom.xml index bf4e15d9d4..fde5244ddf 100644 --- a/msa/pom.xml +++ b/msa/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard msa diff --git a/msa/tb-node/pom.xml b/msa/tb-node/pom.xml index 8437cc35c3..61185f4eda 100644 --- a/msa/tb-node/pom.xml +++ b/msa/tb-node/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index 527d96766e..8955d32a40 100644 --- a/msa/tb/pom.xml +++ b/msa/tb/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/coap/pom.xml b/msa/transport/coap/pom.xml index 386b91ea76..404006d2fa 100644 --- a/msa/transport/coap/pom.xml +++ b/msa/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/http/pom.xml b/msa/transport/http/pom.xml index 344219a660..2ba1a5cb73 100644 --- a/msa/transport/http/pom.xml +++ b/msa/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/lwm2m/pom.xml b/msa/transport/lwm2m/pom.xml index 8dfef617cd..3db99773c8 100644 --- a/msa/transport/lwm2m/pom.xml +++ b/msa/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/mqtt/pom.xml b/msa/transport/mqtt/pom.xml index e1d740c877..3b67d74fee 100644 --- a/msa/transport/mqtt/pom.xml +++ b/msa/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard.msa - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.msa.transport diff --git a/msa/transport/pom.xml b/msa/transport/pom.xml index e0bd5a9457..445ee31bf7 100644 --- a/msa/transport/pom.xml +++ b/msa/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/transport/snmp/pom.xml b/msa/transport/snmp/pom.xml index b6a4e15b04..af3dc31629 100644 --- a/msa/transport/snmp/pom.xml +++ b/msa/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard.msa transport - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT org.thingsboard.msa.transport diff --git a/msa/vc-executor-docker/pom.xml b/msa/vc-executor-docker/pom.xml index 9b6fc493cd..3bca1a5c8d 100644 --- a/msa/vc-executor-docker/pom.xml +++ b/msa/vc-executor-docker/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/vc-executor/pom.xml b/msa/vc-executor/pom.xml index 9bd2befa90..4e6b6c4e11 100644 --- a/msa/vc-executor/pom.xml +++ b/msa/vc-executor/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index e9500cf5e0..cbee67c12e 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT msa org.thingsboard.msa diff --git a/netty-mqtt/pom.xml b/netty-mqtt/pom.xml index 3e09ac6b98..213ed62a05 100644 --- a/netty-mqtt/pom.xml +++ b/netty-mqtt/pom.xml @@ -19,11 +19,11 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard netty-mqtt - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT jar Netty MQTT Client diff --git a/pom.xml b/pom.xml index 3167435c32..1782614c34 100755 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT pom Thingsboard diff --git a/rest-client/pom.xml b/rest-client/pom.xml index 638dc42009..8651656744 100644 --- a/rest-client/pom.xml +++ b/rest-client/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard rest-client diff --git a/rule-engine/pom.xml b/rule-engine/pom.xml index fe8cb3fab5..39e395b756 100644 --- a/rule-engine/pom.xml +++ b/rule-engine/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard rule-engine diff --git a/rule-engine/rule-engine-api/pom.xml b/rule-engine/rule-engine-api/pom.xml index eb57b59c3f..ae06117259 100644 --- a/rule-engine/rule-engine-api/pom.xml +++ b/rule-engine/rule-engine-api/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/rule-engine/rule-engine-components/pom.xml b/rule-engine/rule-engine-components/pom.xml index c449b590fe..9565c6566c 100644 --- a/rule-engine/rule-engine-components/pom.xml +++ b/rule-engine/rule-engine-components/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT rule-engine org.thingsboard.rule-engine diff --git a/tools/pom.xml b/tools/pom.xml index c0b74bb0a9..5417f12119 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard tools diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml index 3b1e0a9e62..c4b52361b7 100644 --- a/transport/coap/pom.xml +++ b/transport/coap/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/http/pom.xml b/transport/http/pom.xml index 3d4b806d03..4e3abea0d1 100644 --- a/transport/http/pom.xml +++ b/transport/http/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/lwm2m/pom.xml b/transport/lwm2m/pom.xml index efe76111f3..5bac4f5973 100644 --- a/transport/lwm2m/pom.xml +++ b/transport/lwm2m/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml index 75daa483a1..67f27f8ab4 100644 --- a/transport/mqtt/pom.xml +++ b/transport/mqtt/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport org.thingsboard.transport diff --git a/transport/pom.xml b/transport/pom.xml index 203ea6cbbb..4e0182928c 100644 --- a/transport/pom.xml +++ b/transport/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard transport diff --git a/transport/snmp/pom.xml b/transport/snmp/pom.xml index c04e7d1f1f..da4c8c23d3 100644 --- a/transport/snmp/pom.xml +++ b/transport/snmp/pom.xml @@ -21,7 +21,7 @@ org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT transport diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index d6dc28490f..84b5f8b98c 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -20,7 +20,7 @@ 4.0.0 org.thingsboard - 3.6.0-SNAPSHOT + 3.6.1-SNAPSHOT thingsboard org.thingsboard From a61e9d94c5cb3a56e5783a45a71f75213fe529ea Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 28 Sep 2023 12:55:36 +0200 Subject: [PATCH 23/61] merge improvements --- .../ThingsboardSecurityConfiguration.java | 22 ++++-- .../DeviceConnectivityController.java | 77 ++++++++++++------- .../common/data/widget/WidgetTypeDetails.java | 2 +- .../dao/sql/widget/WidgetTypeRepository.java | 6 +- .../engine/rest/TbRestApiCallNodeTest.java | 1 - 5 files changed, 71 insertions(+), 37 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java index 49f812944c..d07ef4e2d8 100644 --- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java @@ -31,10 +31,9 @@ import org.springframework.security.config.annotation.authentication.builders.Au import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.annotation.web.configurers.RequestCacheConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.AuthenticationFailureHandler; @@ -136,8 +135,8 @@ public class ThingsboardSecurityConfiguration { ShallowEtagHeaderFilter etagFilter = new ShallowEtagHeaderFilter(); etagFilter.setWriteWeakETag(true); FilterRegistrationBean filterRegistrationBean - = new FilterRegistrationBean<>( etagFilter); - filterRegistrationBean.addUrlPatterns("*.js","*.css","*.ico","/assets/*","/static/*"); + = new FilterRegistrationBean<>(etagFilter); + filterRegistrationBean.addUrlPatterns("*.js", "*.css", "*.ico", "/assets/*", "/static/*"); filterRegistrationBean.setName("etagFilter"); return filterRegistrationBean; } @@ -200,8 +199,19 @@ public class ThingsboardSecurityConfiguration { private OAuth2AuthorizationRequestResolver oAuth2AuthorizationRequestResolver; @Bean - public WebSecurityCustomizer webSecurityCustomizer() { - return (web) -> web.ignoring().requestMatchers("/*.js", "/*.css", "/*.ico", "/assets/**", "/static/**"); + @Order(0) + SecurityFilterChain resources(HttpSecurity http) throws Exception { + http + .securityMatchers(matchers -> matchers + .requestMatchers("/*.js", "/*.css", "/*.ico", "/assets/**", "/static/**")) + .headers(header -> header + .defaultsDisabled() + .addHeaderWriter(new StaticHeadersWriter(HttpHeaders.CACHE_CONTROL, "max-age=0, public"))) + .authorizeHttpRequests((authorize) -> authorize.anyRequest().permitAll()) + .requestCache(RequestCacheConfigurer::disable) + .securityContext(AbstractHttpConfigurer::disable) + .sessionManagement(AbstractHttpConfigurer::disable); + return http.build(); } @Bean diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java index 7346cda9fc..0faa743bf2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceConnectivityController.java @@ -17,6 +17,10 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpHeaders; @@ -36,10 +40,8 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.config.annotations.ApiOperation; import org.thingsboard.server.dao.device.DeviceConnectivityService; import org.thingsboard.server.queue.util.TbCoreComponent; -import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.system.SystemSecurityService; -import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.net.URISyntaxException; @@ -64,16 +66,30 @@ public class DeviceConnectivityController extends BaseController { notes = "Fetch the list of commands to publish device telemetry based on device profile " + "If the user has the authority of 'Tenant Administrator', the server checks that the device is owned by the same tenant. " + "If the user has the authority of 'Customer User', the server checks that the device is assigned to the same customer. " + - TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) -// @ApiResponses(value = { -// @ApiResponse(code = 200, message = "OK", -// examples = @io.swagger.annotations.Example( -// value = { -// @io.swagger.annotations.ExampleProperty( -// mediaType = "application/json", -// value = "{\"http\":\"curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}\"," + -// "\"mqtt\":\"mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}\"," + -// "\"coap\":\"coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}\"}")}))}) + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + examples = { + @ExampleObject( + name = "http", + value = "curl -v -X POST http://localhost:8080/api/v1/0ySs4FTOn5WU15XLmal8/telemetry --header Content-Type:application/json --data {temperature:25}" + ), + @ExampleObject( + name = "mqtt", + value = "mosquitto_pub -d -q 1 -h localhost -t v1/devices/me/telemetry -i myClient1 -u myUsername1 -P myPassword -m {temperature:25}" + ), + @ExampleObject( + name = "coap", + value = "coap-client -m POST coap://localhost:5683/api/v1/0ySs4FTOn5WU15XLmal8/telemetry -t json -e {temperature:25}" + ) + } + ) + ) + }) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device-connectivity/{deviceId}", method = RequestMethod.GET) @ResponseBody @@ -81,7 +97,7 @@ public class DeviceConnectivityController extends BaseController { @PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); - Device device = checkDeviceId(deviceId, Operation.READ_CREDENTIALS); + Device device = checkDeviceId(deviceId, org.thingsboard.server.service.security.permission.Operation.READ_CREDENTIALS); String baseUrl = systemSecurityService.getBaseUrl(getTenantId(), getCurrentUser().getCustomerId(), request); return deviceConnectivityService.findDevicePublishTelemetryCommands(baseUrl, device); @@ -89,25 +105,34 @@ public class DeviceConnectivityController extends BaseController { @ApiOperation(value = "Get commands to launch gateway (getGatewayLaunchCommands)", notes = "Fetch the list of commands for different operation systems to launch a gateway using docker." + - TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) -// @ApiResponses(value = { -// @ApiResponse(code = 200, message = "OK", -// examples = @io.swagger.annotations.Example( -// value = { -// @io.swagger.annotations.ExampleProperty( -// mediaType = "application/json", -// value = "{\"mqtt\": {\n" + -// " \"linux\": \"docker run --rm -it -v ~/.tb-gateway/logs:/thingsboard_gateway/logs -v ~/.tb-gateway/extensions:/thingsboard_gateway/extensions -v ~/.tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway\",\n" + -// " \"windows\": \"docker run --rm -it -v %HOMEPATH%/tb-gateway/logs:/thingsboard_gateway/logs -v %HOMEPATH%/tb-gateway/extensions:/thingsboard_gateway/extensions -v %HOMEPATH%/tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway\"}\n" + -// "}")}))}) + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH, + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = @Content( + mediaType = MediaType.APPLICATION_JSON_VALUE, + examples = { + @ExampleObject( + name = "mqtt-linux", + value = "docker run --rm -it -v ~/.tb-gateway/logs:/thingsboard_gateway/logs -v ~/.tb-gateway/extensions:/thingsboard_gateway/extensions -v ~/.tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway" + ), + @ExampleObject( + name = "mqtt-windows", + value = "docker run --rm -it -v %HOMEPATH%/tb-gateway/logs:/thingsboard_gateway/logs -v %HOMEPATH%/tb-gateway/extensions:/thingsboard_gateway/extensions -v %HOMEPATH%/tb-gateway/config:/thingsboard_gateway/config --name tbGateway127001 -e host=localhost -e port=1883 -e accessToken=qTe5oDBHPJf0KCSKO8J3 --restart always thingsboard/tb-gateway" + ) + } + ) + ) + }) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device-connectivity/gateway-launch/{deviceId}", method = RequestMethod.GET) @ResponseBody public JsonNode getGatewayLaunchCommands(@Parameter(description = DEVICE_ID_PARAM_DESCRIPTION) - @PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException { + @PathVariable(DEVICE_ID) String strDeviceId, HttpServletRequest request) throws ThingsboardException, URISyntaxException { checkParameter(DEVICE_ID, strDeviceId); DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); - Device device = checkDeviceId(deviceId, Operation.READ_CREDENTIALS); + Device device = checkDeviceId(deviceId, org.thingsboard.server.service.security.permission.Operation.READ_CREDENTIALS); if (!checkIsGateway(device)) { throw new ThingsboardException("The device must be a gateway!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java index 88230aec94..2b80a3d0f3 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetTypeDetails.java @@ -35,7 +35,7 @@ public class WidgetTypeDetails extends WidgetType implements HasName, HasTenantI @Schema(description = "Base64 encoded thumbnail") private String image; @NoXss - @Length(fieldName = "description") + @Length(fieldName = "description", max = 1024) @Schema(description = "Description of the widget") private String description; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeRepository.java index 41fa293dd5..f85386b077 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/widget/WidgetTypeRepository.java @@ -39,7 +39,7 @@ public interface WidgetTypeRepository extends JpaRepository findSystemWidgetTypes(@Param("systemTenantId") UUID systemTenantId, @Param("searchText") String searchText, @Param("fullSearch") boolean fullSearch, @@ -47,7 +47,7 @@ public interface WidgetTypeRepository extends JpaRepository findAllTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId, @Param("nullTenantId") UUID nullTenantId, @Param("searchText") String searchText, @@ -56,7 +56,7 @@ public interface WidgetTypeRepository extends JpaRepository findTenantWidgetTypesByTenantId(@Param("tenantId") UUID tenantId, @Param("searchText") String searchText, @Param("fullSearch") boolean fullSearch, diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java index cb147020f1..de997ef45c 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/rest/TbRestApiCallNodeTest.java @@ -203,7 +203,6 @@ public class TbRestApiCallNodeTest { ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor metadataCaptor = ArgumentCaptor.forClass(TbMsgMetaData.class); ArgumentCaptor dataCaptor = ArgumentCaptor.forClass(String.class); - //verify(ctx).transformMsg(msgCaptor.capture(), typeCaptor.capture(), originatorCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture()); verify(ctx).transformMsg(msgCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture()); assertNotSame(metaData, metadataCaptor.getValue()); From 9970bffc2f0c69ccc4711856faf0387df5138be5 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 28 Sep 2023 16:11:25 +0300 Subject: [PATCH 24/61] TbDate test update according to Java 17 --- .../test/java/org/thingsboard/script/api/tbel/TbDateTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 87dd4f0ebf..e31641a4fe 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -244,7 +244,7 @@ class TbDateTest { Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleString("en-US", "America/New_York")); Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleString("ko-KR", "America/New_York")); Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleString( "uk-UA", "Europe/Kiev")); - Assert.assertEquals("5\u200F/9\u200F/2023 9:04:05 م", d.toLocaleString( "ar-EG", "America/New_York")); + Assert.assertEquals("5\u200F/9\u200F/2023, 9:04:05 م", d.toLocaleString( "ar-EG", "America/New_York")); Assert.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") @@ -261,7 +261,7 @@ class TbDateTest { .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") From db4ce97621f26ebb630977e1243050d64a115263 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 29 Sep 2023 11:49:35 +0300 Subject: [PATCH 25/61] tbDate: TbDate implements InstantSource --- .../thingsboard/script/api/tbel/TbDate.java | 152 +++++++++++------- .../script/api/tbel/TbDateTest.java | 129 +++++++++++---- 2 files changed, 192 insertions(+), 89 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 3f79dc2cf7..64ab9a1c76 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -15,71 +15,91 @@ */ package org.thingsboard.script.api.tbel; +import org.mvel2.ConversionException; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.StringUtils; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.time.Instant; -import java.time.LocalDate; +import java.time.InstantSource; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; -import java.time.temporal.ChronoUnit; -import java.time.temporal.TemporalAccessor; +import java.time.format.DateTimeParseException; +import java.util.Arrays; import java.util.Date; -import java.util.GregorianCalendar; import java.util.Locale; import java.util.function.BiFunction; -public class TbDate extends Date { +public class TbDate implements InstantSource { - private static final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( - "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); + private static Instant instant; - private static final ThreadLocal isoDateFormat = ThreadLocal.withInitial(() -> - new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); + private static String patternDefault = "%s-%s-%sT%s:%s:%s.%d%s"; + +// private static final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( +// "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); +// +// private static final ThreadLocal isoDateFormat = ThreadLocal.withInitial(() -> +// new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); public TbDate() { - super(); + instant = Instant.now(); } public TbDate(String s) { - super(parse(s)); + try{ + if (s.length() > 0 && Character.isDigit(s.charAt(0))) { + // assuming UTC instant a la "2007-12-03T10:15:30.00Z" + instant = Instant.parse(s); + } + else { + // assuming RFC-1123 value a la "Tue, 3 Jun 2008 11:05:30 GMT" + instant = Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(s)); + } + } catch (final DateTimeParseException ex) { + final ConversionException exception = new ConversionException("Cannot parse value [" + s + "] as instant", ex); + throw exception; + } + } + + public TbDate(long dateMilliSecond) { + instant = Instant.ofEpochMilli(dateMilliSecond); } - public TbDate(long date) { - super(date); + public TbDate(int year, int month, int date, String... tz) { + this(year, month, date, 0, 0, 0, 0, tz); } - public TbDate(int year, int month, int date) { - this(year, month, date, 0, 0, 0); + public TbDate(int year, int month, int date, int hrs, int min, String... tz) { + this(year, month, date, hrs, min, 0, 0, tz); } - public TbDate(int year, int month, int date, int hrs, int min) { - this(year, month, date, hrs, min, 0); + public TbDate(int year, int month, int date, int hrs, int min, int second, String... tz) { + this(year, month, date, hrs, min, second, 0, tz); } - public TbDate(int year, int month, int date, - int hrs, int min, int second) { - super(new GregorianCalendar(year, month, date, hrs, min, second).getTimeInMillis()); + public TbDate(int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { + this(createDateTimeFromPattern (year, month, date, hrs, min, second, secondMilli, tz)); + } + + @Override + public Instant instant() { + return instant; } public String toDateString() { - DateFormat formatter = DateFormat.getDateInstance(); - return formatter.format(this); + return toLocaleDateString(); } public String toTimeString() { - DateFormat formatter = DateFormat.getTimeInstance(DateFormat.LONG); - return formatter.format(this); + return toLocaleTimeString(); } public String toISOString() { - return isoDateFormat.get().format(this); + return instant.toString(); } public String toLocaleDateString() { @@ -106,9 +126,13 @@ public class TbDate extends Date { return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); } - @Override public String toLocaleString() { - return toLocaleString(null, null); + LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + return localDateTime.toString(); + } + + public LocalDateTime getLocalDateTime() { + return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); } public String toLocaleString(String locale) { @@ -130,7 +154,7 @@ public class TbDate extends Date { public String toLocaleString(String localeStr, String optionsStr, BiFunction formatterBuilder) { Locale locale = StringUtils.isNotEmpty(localeStr) ? Locale.forLanguageTag(localeStr) : Locale.getDefault(); DateTimeFormatOptions options = getDateFormattingOptions(optionsStr); - ZonedDateTime zdt = this.toInstant().atZone(options.getTimeZone().toZoneId()); + ZonedDateTime zdt = this.instant().atZone(options.getTimeZone().toZoneId()); DateTimeFormatter formatter; if (StringUtils.isNotEmpty(options.getPattern())) { formatter = new DateTimeFormatterBuilder().appendPattern(options.getPattern()).toFormatter(locale); @@ -159,35 +183,53 @@ public class TbDate extends Date { return System.currentTimeMillis(); } - public static long parse(String value, String format) { - try { - DateFormat dateFormat = new SimpleDateFormat(format); - return dateFormat.parse(value).getTime(); - } catch (Exception e) { - return -1; - } - } - - public static long parse(String value) { - try { - TemporalAccessor accessor = isoDateFormatter.parseBest(value, - ZonedDateTime::from, - LocalDateTime::from, - LocalDate::from); - Instant instant = Instant.from(accessor); - return Instant.EPOCH.until(instant, ChronoUnit.MILLIS); - } catch (Exception e) { - try { - return Date.parse(value); - } catch (IllegalArgumentException e2) { - return -1; - } - } - } +// public static long parse(String value, String format) { +// try { +// DateFormat dateFormat = new SimpleDateFormat(format); +// return dateFormat.parse(value).getTime(); +// } catch (Exception e) { +// return -1; +// } +// } + public static long parseSecond() { + return instant.getEpochSecond(); + } + + public static long parseSecondMilli() { + return instant.toEpochMilli(); + } + +// public static long parse(String value) { +// try { +// TemporalAccessor accessor = isoDateFormatter.parseBest(value, +// ZonedDateTime::from, +// LocalDateTime::from, +// LocalDate::from); +// Instant instant = Instant.from(accessor); +// return Instant.EPOCH.until(instant, ChronoUnit.MILLIS); +// } catch (Exception e) { +// try { +// return Date.parse(value); +// } catch (IllegalArgumentException e2) { +// return -1; +// } +// } +// } public static long UTC(int year, int month, int date, int hrs, int min, int sec) { return Date.UTC(year - 1900, month, date, hrs, min, sec); } + private static String createDateTimeFromPattern (int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { + String yearStr = String.format("%04d", year); + if (yearStr.substring(0, 2).equals("00")) yearStr = "20" + yearStr.substring(2,4); + String monthStr = String.format("%02d", month); + String dateStr = String.format("%02d", date); + String hrsStr = String.format("%02d", hrs); + String minStr = String.format("%02d", min); + String secondStr = String.format("%02d", second); + String tzStr = tz.length > 0 ? Arrays.stream(tz).findFirst().get() : "Z"; + return String.format(patternDefault, yearStr, monthStr, dateStr, hrsStr, minStr, secondStr, secondMilli, tzStr); + } } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index e31641a4fe..34643a2f86 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -24,10 +24,13 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.mvel2.ConversionException; import org.thingsboard.common.util.JacksonUtil; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.InstantSource; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.chrono.IsoChronology; @@ -46,6 +49,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; @Slf4j class TbDateTest { @@ -121,7 +126,7 @@ class TbDateTest { long ts = 1709217342987L; //Thu Feb 29 2024 14:35:42.987 GMT+0000 int offset = Calendar.getInstance().get(Calendar.ZONE_OFFSET); // for example 3600000 for GMT + 1 TbDate tbDate = new TbDate(ts - offset); - String datePrefix = "2024-02-29T14:35:42.987"; //without time zone + String datePrefix = "2024-02-29T12:35:42.987Z"; //without time zone assertThat(tbDate.toISOString()) .as("format in main thread") .startsWith(datePrefix); @@ -140,59 +145,63 @@ class TbDateTest { void testToLocaleDateString() { TbDate d = new TbDate(1693962245000L); + Assert.assertEquals("2023-09-06T01:04:05Z", d.instant().toString()); + Assert.assertEquals("06.09.23", d.toDateString()); + // Depends on time zone, so we just check it works; Assert.assertNotNull(d.toLocaleDateString()); Assert.assertNotNull(d.toLocaleDateString("en-US")); - Assert.assertEquals("9/5/23", d.toLocaleDateString("en-US", "America/New_York")); - Assert.assertEquals("23. 9. 5.", d.toLocaleDateString("ko-KR", "America/New_York")); - Assert.assertEquals("06.09.23", d.toLocaleDateString( "uk-UA", "Europe/Kiev")); - Assert.assertEquals("5\u200F/9\u200F/2023", d.toLocaleDateString( "ar-EG", "America/New_York")); + Assert.assertEquals("9/5/23", d.toLocaleDateString("en-US", "America/New_York")); + Assert.assertEquals("23. 9. 5.", d.toLocaleDateString("ko-KR", "America/New_York")); + Assert.assertEquals("06.09.23", d.toLocaleDateString( "uk-UA", "Europe/Kiev")); + Assert.assertEquals("5\u200F/9\u200F/2023", d.toLocaleDateString( "ar-EG", "America/New_York")); Assert.assertEquals("Tuesday, September 5, 2023", d.toLocaleDateString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") - .toString())); + .toString())); Assert.assertEquals("2023년 9월 5일 화요일", d.toLocaleDateString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") - .toString())); + .toString())); Assert.assertEquals("середа, 6 вересня 2023 р.", d.toLocaleDateString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("dateStyle", "full") - .toString())); + .toString())); Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023", d.toLocaleDateString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") - .toString())); + .toString())); Assert.assertEquals("Tuesday 9/5/2023", d.toLocaleDateString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "EEEE M/d/yyyy") - .toString())); + .toString())); Assert.assertEquals("화요일 9/5/2023", d.toLocaleDateString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "EEEE M/d/yyyy") - .toString())); + .toString())); Assert.assertEquals("середа 9/6/2023", d.toLocaleDateString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("pattern", "EEEE M/d/yyyy") - .toString())); + .toString())); Assert.assertEquals("الثلاثاء 9/5/2023", d.toLocaleDateString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "EEEE M/d/yyyy") - .toString())); + .toString())); } @Test void testToLocaleTimeString() { TbDate d = new TbDate(1693962245000L); + Assert.assertEquals("04:04:05", d.toTimeString()); + // Depends on time zone, so we just check it works; Assert.assertNotNull(d.toLocaleTimeString()); Assert.assertNotNull(d.toLocaleTimeString("en-US")); - Assert.assertEquals("9:04:05 PM", d.toLocaleTimeString("en-US", "America/New_York")); Assert.assertEquals("오후 9:04:05", d.toLocaleTimeString("ko-KR", "America/New_York")); Assert.assertEquals("04:04:05", d.toLocaleTimeString( "uk-UA", "Europe/Kiev")); @@ -201,36 +210,36 @@ class TbDateTest { Assert.assertEquals("9:04:05 PM Eastern Daylight Time", d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleTimeString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("04:04:05 за східноєвропейським літнім часом", d.toLocaleTimeString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleTimeString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("9:04:05 PM", d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") - .toString())); + .toString())); Assert.assertEquals("9:04:05 오후", d.toLocaleTimeString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") - .toString())); + .toString())); Assert.assertEquals("4:04:05 дп", d.toLocaleTimeString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("pattern", "h:mm:ss a") - .toString())); + .toString())); Assert.assertEquals("9:04:05 م", d.toLocaleTimeString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") - .toString())); + .toString())); } @Test @@ -241,52 +250,104 @@ class TbDateTest { Assert.assertNotNull(d.toLocaleString()); Assert.assertNotNull(d.toLocaleString("en-US")); - Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleString("en-US", "America/New_York")); - Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleString("ko-KR", "America/New_York")); - Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleString( "uk-UA", "Europe/Kiev")); + Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleString("en-US", "America/New_York")); + Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleString("ko-KR", "America/New_York")); + Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleString( "uk-UA", "Europe/Kiev")); Assert.assertEquals("5\u200F/9\u200F/2023, 9:04:05 م", d.toLocaleString( "ar-EG", "America/New_York")); Assert.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("2023년 9월 5일 화요일 오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("середа, 6 вересня 2023 р. о 04:04:05 за східноєвропейським літнім часом", d.toLocaleString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("dateStyle", "full") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") - .toString())); + .toString())); Assert.assertEquals("9/5/2023, 9:04:05 PM", d.toLocaleString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") - .toString())); + .toString())); Assert.assertEquals("9/5/2023, 9:04:05 오후", d.toLocaleString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") - .toString())); + .toString())); Assert.assertEquals("9/6/2023, 4:04:05 дп", d.toLocaleString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("pattern", "M/d/yyyy, h:mm:ss a") - .toString())); + .toString())); Assert.assertEquals("9/5/2023, 9:04:05 م", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") - .toString())); + .toString())); + } + + @Test + void TestFromString () { + String stringDateUTC = "2023-09-06T01:04:05.00Z"; + TbDate d = new TbDate(stringDateUTC); + Assert.assertEquals("2023-09-06T01:04:05Z", d.instant().toString()); + String stringDateTZ = "2023-09-06T01:04:05.00+04:00"; + d = new TbDate(stringDateTZ); + Assert.assertEquals("2023-09-05T21:04:05Z", d.instant().toString()); + stringDateTZ = "2023-09-06T01:04:05.00-02:00"; + d = new TbDate(stringDateTZ); + Assert.assertEquals("2023-09-06T03:04:05Z", d.instant().toString()); + String stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 GMT"; + d = new TbDate(stringDateRFC_1123); + Assert.assertEquals("2023-06-03T11:05:30Z", d.instant().toString()); + + String stringDateRFC_1123_error = "Tue, 3 Jun 2023 11:05:30 GMT"; + Exception exception = assertThrows(ConversionException.class, () -> { + new TbDate(stringDateRFC_1123_error); + }); + String expectedMessage = "Cannot parse value [Tue, 3 Jun 2023 11:05:30 GMT] as instant"; + String actualMessage = exception.getMessage(); + assertTrue(actualMessage.contains(expectedMessage)); + } + + @Test + void TestParse () { + String stringDateUTC = "2023-09-06T01:04:05.345Z"; + TbDate d = new TbDate(stringDateUTC); + Assert.assertEquals(1693962245345L, d.parseSecondMilli()); + Assert.assertEquals(1693962245L, d.parseSecond()); + } + + @Test + void TestDate_Year_Moth_Date_Hs_Min_Sec () { + TbDate d = new TbDate(2023, 8, 18); + Assert.assertEquals("2023-08-18T00:00:00Z", d.instant().toString()); + d = new TbDate(2023, 9, 17, 17, 34); + Assert.assertEquals("2023-09-17T17:34:00Z", d.instant().toString()); + d = new TbDate(23, 9, 7, 8, 4); + Assert.assertEquals("2023-09-07T08:04:00Z", d.instant().toString()); + d = new TbDate(23, 9, 7, 8, 4, 5); + Assert.assertEquals("2023-09-07T08:04:05Z", d.instant().toString()); + d = new TbDate(23, 9, 7, 8, 4, 5, "+04:00"); + Assert.assertEquals("2023-09-07T04:04:05Z", d.instant().toString()); + d = new TbDate(23, 9, 7, 8, 4, 5, "-03:00"); + Assert.assertEquals("2023-09-07T11:04:05Z", d.instant().toString()); + d = new TbDate(23, 9, 7, 23, 4, 5, "-03:00"); + Assert.assertEquals("2023-09-08T02:04:05Z", d.instant().toString()); + d = new TbDate(23, 9, 7, 23, 4, 5, 567,"-03:00"); + Assert.assertEquals("2023-09-08T02:04:05.567Z", d.instant().toString()); } private static String toLocalString(TbDate d, Locale locale, ZoneId tz) { - LocalDateTime ldt = d.toInstant().atZone(tz).toLocalDateTime(); + LocalDateTime ldt = d.getLocalDateTime(); // new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale) From 47d1dc5fcf0d5b8a9866dfd6f08e635fed94f85f Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 29 Sep 2023 11:53:38 +0300 Subject: [PATCH 26/61] tbDate: class TbDate implements InstantSource --- .../test/java/org/thingsboard/script/api/tbel/TbDateTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 34643a2f86..594047e1cc 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -29,8 +29,6 @@ import org.thingsboard.common.util.JacksonUtil; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.time.Instant; -import java.time.InstantSource; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.chrono.IsoChronology; From ab2976292b08c20b0b7f00338c4f2dc947b0c18e Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 29 Sep 2023 17:22:36 +0300 Subject: [PATCH 27/61] tbDate: fix bug tests --- .../script/api/tbel/TbDateTest.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 594047e1cc..c415f59508 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -121,22 +121,29 @@ class TbDateTest { @Test void testToISOStringThreadLocalStaticFormatter() throws ExecutionException, InterruptedException, TimeoutException { executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1)); + int hrs = 14; + String pattern = "2024-02-29T%s:35:42.987Z"; + String tsStr = String.format(pattern, hrs); //Thu Feb 29 2024 14:35:42.987 GMT+0000 + TbDate tbDate = new TbDate(tsStr); long ts = 1709217342987L; //Thu Feb 29 2024 14:35:42.987 GMT+0000 + Assert.assertEquals(ts, tbDate.millis()); int offset = Calendar.getInstance().get(Calendar.ZONE_OFFSET); // for example 3600000 for GMT + 1 - TbDate tbDate = new TbDate(ts - offset); - String datePrefix = "2024-02-29T12:35:42.987Z"; //without time zone + + String datePrefix = tsStr; //without time zone assertThat(tbDate.toISOString()) .as("format in main thread") .startsWith(datePrefix); assertThat(executor.submit(tbDate::toISOString).get(30, TimeUnit.SECONDS)) .as("format in executor thread") .startsWith(datePrefix); + int offsetHrs = offset/1000/60/60; + String datePrefixLocal = String.format(pattern, (hrs - offsetHrs)); assertThat(new TbDate(ts - offset).toISOString()) .as("new instance format in main thread") - .startsWith(datePrefix); + .startsWith(datePrefixLocal); assertThat(executor.submit(() -> new TbDate(ts - offset).toISOString()).get(30, TimeUnit.SECONDS)) .as("new instance format in executor thread") - .startsWith(datePrefix); + .startsWith(datePrefixLocal); } @Test @@ -144,7 +151,6 @@ class TbDateTest { TbDate d = new TbDate(1693962245000L); Assert.assertEquals("2023-09-06T01:04:05Z", d.instant().toString()); - Assert.assertEquals("06.09.23", d.toDateString()); // Depends on time zone, so we just check it works; Assert.assertNotNull(d.toLocaleDateString()); @@ -194,8 +200,6 @@ class TbDateTest { void testToLocaleTimeString() { TbDate d = new TbDate(1693962245000L); - Assert.assertEquals("04:04:05", d.toTimeString()); - // Depends on time zone, so we just check it works; Assert.assertNotNull(d.toLocaleTimeString()); Assert.assertNotNull(d.toLocaleTimeString("en-US")); @@ -306,6 +310,9 @@ class TbDateTest { String stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 GMT"; d = new TbDate(stringDateRFC_1123); Assert.assertEquals("2023-06-03T11:05:30Z", d.instant().toString()); + stringDateRFC_1123 = "Thu, 29 Feb 2024 11:05:30 GMT"; + d = new TbDate(stringDateRFC_1123); + Assert.assertEquals("2024-02-29T11:05:30Z", d.instant().toString()); String stringDateRFC_1123_error = "Tue, 3 Jun 2023 11:05:30 GMT"; Exception exception = assertThrows(ConversionException.class, () -> { From f3d258e60a7c688db3bb16aa3c030d8dd8c0f4e6 Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 2 Oct 2023 15:32:38 +0300 Subject: [PATCH 28/61] tbDate: tests comments1 --- .../script/api/tbel/TbDateTest.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index c415f59508..5115940a6b 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -150,7 +150,7 @@ class TbDateTest { void testToLocaleDateString() { TbDate d = new TbDate(1693962245000L); - Assert.assertEquals("2023-09-06T01:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-06T01:04:05Z", d.toISOString()); // Depends on time zone, so we just check it works; Assert.assertNotNull(d.toLocaleDateString()); @@ -300,19 +300,19 @@ class TbDateTest { void TestFromString () { String stringDateUTC = "2023-09-06T01:04:05.00Z"; TbDate d = new TbDate(stringDateUTC); - Assert.assertEquals("2023-09-06T01:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-06T01:04:05Z", d.toISOString()); String stringDateTZ = "2023-09-06T01:04:05.00+04:00"; d = new TbDate(stringDateTZ); - Assert.assertEquals("2023-09-05T21:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-05T21:04:05Z", d.toISOString()); stringDateTZ = "2023-09-06T01:04:05.00-02:00"; d = new TbDate(stringDateTZ); - Assert.assertEquals("2023-09-06T03:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-06T03:04:05Z", d.toISOString()); String stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 GMT"; d = new TbDate(stringDateRFC_1123); - Assert.assertEquals("2023-06-03T11:05:30Z", d.instant().toString()); + Assert.assertEquals("2023-06-03T11:05:30Z", d.toISOString()); stringDateRFC_1123 = "Thu, 29 Feb 2024 11:05:30 GMT"; d = new TbDate(stringDateRFC_1123); - Assert.assertEquals("2024-02-29T11:05:30Z", d.instant().toString()); + Assert.assertEquals("2024-02-29T11:05:30Z", d.toISOString()); String stringDateRFC_1123_error = "Tue, 3 Jun 2023 11:05:30 GMT"; Exception exception = assertThrows(ConversionException.class, () -> { @@ -334,21 +334,21 @@ class TbDateTest { @Test void TestDate_Year_Moth_Date_Hs_Min_Sec () { TbDate d = new TbDate(2023, 8, 18); - Assert.assertEquals("2023-08-18T00:00:00Z", d.instant().toString()); + Assert.assertEquals("2023-08-18T00:00:00Z", d.toISOString()); d = new TbDate(2023, 9, 17, 17, 34); - Assert.assertEquals("2023-09-17T17:34:00Z", d.instant().toString()); + Assert.assertEquals("2023-09-17T17:34:00Z", d.toISOString()); d = new TbDate(23, 9, 7, 8, 4); - Assert.assertEquals("2023-09-07T08:04:00Z", d.instant().toString()); + Assert.assertEquals("2023-09-07T08:04:00Z", d.toISOString()); d = new TbDate(23, 9, 7, 8, 4, 5); - Assert.assertEquals("2023-09-07T08:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-07T08:04:05Z", d.toISOString()); d = new TbDate(23, 9, 7, 8, 4, 5, "+04:00"); - Assert.assertEquals("2023-09-07T04:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-07T04:04:05Z", d.toISOString()); d = new TbDate(23, 9, 7, 8, 4, 5, "-03:00"); - Assert.assertEquals("2023-09-07T11:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-07T11:04:05Z", d.toISOString()); d = new TbDate(23, 9, 7, 23, 4, 5, "-03:00"); - Assert.assertEquals("2023-09-08T02:04:05Z", d.instant().toString()); + Assert.assertEquals("2023-09-08T02:04:05Z", d.toISOString()); d = new TbDate(23, 9, 7, 23, 4, 5, 567,"-03:00"); - Assert.assertEquals("2023-09-08T02:04:05.567Z", d.instant().toString()); + Assert.assertEquals("2023-09-08T02:04:05.567Z", d.toISOString()); } private static String toLocalString(TbDate d, Locale locale, ZoneId tz) { From 73f8a7f537909e5d5d6912e61ee8792aa652ab49 Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 2 Oct 2023 15:46:58 +0300 Subject: [PATCH 29/61] tbDate: tests comments12 --- .../thingsboard/script/api/tbel/TbDate.java | 31 ----------------- .../thingsboard/script/api/tbel/TbUtils.java | 33 +++++++++++++++++++ 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 64ab9a1c76..42c5a228cf 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -39,12 +39,6 @@ public class TbDate implements InstantSource { private static String patternDefault = "%s-%s-%sT%s:%s:%s.%d%s"; -// private static final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( -// "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); -// -// private static final ThreadLocal isoDateFormat = ThreadLocal.withInitial(() -> -// new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")); - public TbDate() { instant = Instant.now(); } @@ -183,14 +177,6 @@ public class TbDate implements InstantSource { return System.currentTimeMillis(); } -// public static long parse(String value, String format) { -// try { -// DateFormat dateFormat = new SimpleDateFormat(format); -// return dateFormat.parse(value).getTime(); -// } catch (Exception e) { -// return -1; -// } -// } public static long parseSecond() { return instant.getEpochSecond(); } @@ -199,23 +185,6 @@ public class TbDate implements InstantSource { return instant.toEpochMilli(); } -// public static long parse(String value) { -// try { -// TemporalAccessor accessor = isoDateFormatter.parseBest(value, -// ZonedDateTime::from, -// LocalDateTime::from, -// LocalDate::from); -// Instant instant = Instant.from(accessor); -// return Instant.EPOCH.until(instant, ChronoUnit.MILLIS); -// } catch (Exception e) { -// try { -// return Date.parse(value); -// } catch (IllegalArgumentException e2) { -// return -1; -// } -// } -// } - public static long UTC(int year, int month, int date, int hrs, int min, int sec) { return Date.UTC(year - 1900, month, date, hrs, min, sec); diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index bd14871fe2..1e71795f97 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -32,6 +32,16 @@ import java.math.RoundingMode; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAccessor; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; @@ -649,4 +659,27 @@ public class TbUtils { return true; } + public static long parse(String value, String format) { + try { + DateFormat dateFormat = new SimpleDateFormat(format); + return dateFormat.parse(value).getTime(); + } catch (Exception e) { + return -1; + } + } + public static long parse(String value) { + DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( + "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); + try { + TemporalAccessor accessor = isoDateFormatter.parseBest(value, + ZonedDateTime::from, + LocalDateTime::from, + LocalDate::from); + Instant instant = Instant.from(accessor); + return Instant.EPOCH.until(instant, ChronoUnit.MILLIS); + } catch (Exception e) { + return -1; + } + } + } From 42e5f063a4857d4b4a9489bef5161a476c4b7570 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 6 Oct 2023 10:52:36 +0300 Subject: [PATCH 30/61] tbDate: tests add method as Date JS --- .../thingsboard/script/api/tbel/TbDate.java | 374 ++++++++++++++++-- .../thingsboard/script/api/tbel/TbUtils.java | 25 +- .../script/api/tbel/TbDateTest.java | 371 +++++++++++++++-- 3 files changed, 665 insertions(+), 105 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 42c5a228cf..0dba460686 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -19,8 +19,11 @@ import org.mvel2.ConversionException; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.StringUtils; +import java.io.Serializable; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.time.Instant; -import java.time.InstantSource; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -28,39 +31,47 @@ import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAccessor; import java.util.Arrays; -import java.util.Date; import java.util.Locale; import java.util.function.BiFunction; -public class TbDate implements InstantSource { +public class TbDate implements Serializable, Cloneable { - private static Instant instant; + private Instant instant; + private ZonedDateTime zonedDateTime; + private LocalDateTime localDateTime; + private final ZoneId zoneIdUTC = ZoneId.of("UTC"); - private static String patternDefault = "%s-%s-%sT%s:%s:%s.%d%s"; + private static String patternDefault = "%s-%s-%sT%s:%s:%s.%s%s"; public TbDate() { - instant = Instant.now(); + this.instant = Instant.now(); + initZonedLocalDateTime(); } public TbDate(String s) { - try{ - if (s.length() > 0 && Character.isDigit(s.charAt(0))) { - // assuming UTC instant a la "2007-12-03T10:15:30.00Z" - instant = Instant.parse(s); - } - else { - // assuming RFC-1123 value a la "Tue, 3 Jun 2008 11:05:30 GMT" - instant = Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(s)); - } - } catch (final DateTimeParseException ex) { - final ConversionException exception = new ConversionException("Cannot parse value [" + s + "] as instant", ex); - throw exception; - } + parseInstant(s); + } + + /** + * String s = "09:15:30 PM, Sun 10/09/2022"; + * String pattern = "hh:mm:ss a, EEE M/d/uuuu"; + * @param s + * @param pattern + */ + public TbDate(String s, String pattern, Locale locale) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, locale); + LocalDateTime localDateTime = LocalDateTime.parse(s, dateTimeFormatter); + ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault()); + instant = zonedDateTime.toInstant(); + initZonedLocalDateTime(); } public TbDate(long dateMilliSecond) { instant = Instant.ofEpochMilli(dateMilliSecond); + initZonedLocalDateTime(); } public TbDate(int year, int month, int date, String... tz) { @@ -76,25 +87,75 @@ public class TbDate implements InstantSource { } public TbDate(int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { - this(createDateTimeFromPattern (year, month, date, hrs, min, second, secondMilli, tz)); + this(createDateTimeFromPattern(year, month, date, hrs, min, second, secondMilli, tz)); } - @Override - public Instant instant() { + public Instant getInstant() { return instant; } - public String toDateString() { - return toLocaleDateString(); + public void setInstant(Instant instant) { + this.instant = instant; + } + public ZonedDateTime getZonedDateTime() { + return zonedDateTime; } - public String toTimeString() { - return toLocaleTimeString(); + private void initZonedLocalDateTime() { + setZonedDateTime(zoneIdUTC); + setLocalDateTime(); + } + public void setZonedDateTime(ZoneId z) { + this.zonedDateTime = instant.atZone(z);; + } + + public void setLocalDateTime() { + this.localDateTime = LocalDateTime.ofInstant(this.getInstant(), ZoneId.systemDefault()); + } + public LocalDateTime getLocalDateTime() { + return this.localDateTime ; } + public String toDateString() { + return toLocaleDateString("UTC", JacksonUtil.newObjectNode().put("dateStyle", "full").toString()); + } + public String toDateString(String locale) { + return toLocaleDateString(locale, JacksonUtil.newObjectNode().put("dateStyle", "full").toString()); + } + public String toTimeString() { + return toLocaleTimeString("UTC", JacksonUtil.newObjectNode().put("timeStyle", "full").toString()); + } + public String toTimeString(String locale) { + return toLocaleTimeString(locale, JacksonUtil.newObjectNode().put("timeStyle", "full").toString()); + } + /** + * "2011-10-05T14:48:00.000Z" + * @return + */ public String toISOString() { return instant.toString(); } + public String toJSON() { + return toISOString(); + } + public String toUTCString() { + return toLocaleString("UTC", JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "medium").toString()); + } + + public String toUTCString(String locale) { + return toLocaleString(locale, JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "medium").toString()); + } + + /** + * "Tue Aug 19 1975 23:15:30 GMT+0300 (за східноєвропейським стандартним часом)" + * @return + */ + public String toString() { + return toLocaleString(Locale.getDefault().toString(), JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "full").toString()); + } + public String toString(String locale) { + return toLocaleString(locale, JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "full").toString()); + } public String toLocaleDateString() { return toLocaleDateString(null, null); @@ -125,10 +186,6 @@ public class TbDate implements InstantSource { return localDateTime.toString(); } - public LocalDateTime getLocalDateTime() { - return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); - } - public String toLocaleString(String locale) { return toLocaleString(locale, null); } @@ -148,7 +205,7 @@ public class TbDate implements InstantSource { public String toLocaleString(String localeStr, String optionsStr, BiFunction formatterBuilder) { Locale locale = StringUtils.isNotEmpty(localeStr) ? Locale.forLanguageTag(localeStr) : Locale.getDefault(); DateTimeFormatOptions options = getDateFormattingOptions(optionsStr); - ZonedDateTime zdt = this.instant().atZone(options.getTimeZone().toZoneId()); + ZonedDateTime zdt = this.getInstant().atZone(options.getTimeZone().toZoneId()); DateTimeFormatter formatter; if (StringUtils.isNotEmpty(options.getPattern())) { formatter = new DateTimeFormatterBuilder().appendPattern(options.getPattern()).toFormatter(locale); @@ -158,7 +215,7 @@ public class TbDate implements InstantSource { return formatter.format(zdt); } - private static DateTimeFormatOptions getDateFormattingOptions(String options) { + private DateTimeFormatOptions getDateFormattingOptions(String options) { DateTimeFormatOptions opt = null; if (StringUtils.isNotEmpty(options)) { try { @@ -173,32 +230,265 @@ public class TbDate implements InstantSource { return opt; } - public static long now() { - return System.currentTimeMillis(); + public long now() { + return Instant.now().toEpochMilli(); } - public static long parseSecond() { + public long parseSecond() { return instant.getEpochSecond(); } - public static long parseSecondMilli() { + public long parseSecondMilli() { + return instant.toEpochMilli(); + } + + public static long UTC(int year) { + return UTC(year, 0, 0, 0, 0, 0, 0); + } + public static long UTC(int year, int month) { + return UTC(year, month, 0, 0, 0, 0, 0); + } + public static long UTC(int year, int month, int date) { + return UTC(year, month, date, 0, 0, 0, 0); + } + public static long UTC(int year, int month, int date, int hrs) { + return UTC(year, month, date, hrs, 0, 0, 0); + } + public static long UTC(int year, int month, int date, int hrs, int min) { + return UTC(year, month, date, hrs, min, 0, 0); + } + public static long UTC(int year, int month, int date, int hrs, int min, int sec) { + return UTC(year, month, date, hrs, min, sec, 0); + } + public static long UTC(int year, int month, int date, int hrs, int min, int sec, int ms) { + year = year == 0 ? year = 1899 : year; + month = month == 0 ? month = 12 : month; + date = date == 0 ? date = 31 : date; + return Instant.parse(createDateTimeFromPattern (year, month, date, hrs, min, sec, ms)).toEpochMilli(); + } + public int getUTCFullYear() { + return zonedDateTime.getYear(); + } + + public int getUTCMonth() { + return zonedDateTime.getMonthValue(); + } + // day in month + public int getUTCDate() { + return zonedDateTime.getDayOfMonth(); + } + // day in week + public int getUTCDay() { + return zonedDateTime.getDayOfWeek().getValue(); + } + + public int getUTCHours() { + return zonedDateTime.getHour(); + } + + public int getUTCMinutes() { + return zonedDateTime.getMinute(); + } + + public int getUTCSeconds() { + return zonedDateTime.getSecond(); + } + public int getUTCMilliseconds() { + return zonedDateTime.getNano()/1000000; + } + + public void setUTCFullYear(int year) { + parseInstant(createDateTimeFromPattern(year, getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCFullYear(int year, int month) { + parseInstant(createDateTimeFromPattern(year, month, getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCFullYear(int year, int month, int date) { + parseInstant(createDateTimeFromPattern(year, month, date, getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCMonth(int month) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), month, getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCMonth(int month, int date) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), month, date, getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCDate(int date) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), date, getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCHours(int hrs) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCHours(int hrs, int minutes) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, minutes, getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCHours(int hrs, int minutes, int seconds) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, minutes, seconds, getUTCMilliseconds())); + } + public void setUTCHours(int hrs, int minutes, int seconds, int ms) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, minutes, seconds, ms)); + } + public void setUTCMinutes(int minutes) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), minutes, getUTCSeconds(), getUTCMilliseconds())); + } + public void setUTCMinutes(int minutes, int seconds) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), minutes, seconds, getUTCMilliseconds())); + } + public void setUTCMinutes(int minutes, int seconds, int ms) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), minutes, seconds, ms)); + } + public void setUTCSeconds(int seconds) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), seconds, getUTCMilliseconds())); + } + public void setUTCSeconds(int seconds, int ms) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), seconds, ms)); + } + public void setUTCMilliseconds(int ms) { + parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), ms)); + } + public int getFullYear() { + return localDateTime.getYear(); + } + + public int getMonth() { + return localDateTime.getMonthValue(); + } + // day in month + public int getDate() { + return localDateTime.getDayOfMonth(); + } + // day in week + public int getDay() { + return localDateTime.getDayOfWeek().getValue(); + } + + public int getHours() { + return localDateTime.getHour(); + } + + public int getMinutes() { + return localDateTime.getMinute(); + } + + public int getSeconds() { + return localDateTime.getSecond(); + } + public int getMilliseconds() { + return localDateTime.getNano()/1000000; + } + // Milliseconds since Jan 1, 1970, 00:00:00.000 GMT + public long getTime() { return instant.toEpochMilli(); } + public long valueOf(){ + return getTime() ; + } + public void setFullYear(int year) { + setUTCFullYear(year); + } + public void setFullYear(int year, int month) { + setUTCFullYear(year, month); + } public void setFullYear(int year, int month, int date) { + setUTCFullYear(year, month, date); + } + public void setMonth(int month) { + setUTCMonth(month); + } + public void setMonth(int month, int date) { + setUTCMonth(month, date) ; + } + public void setDate(int date) { + setUTCDate(date); + } + public void setHours(int hrs) { + setUTCHours(hrs); + } + public void setHours(int hrs, int minutes) { + setUTCHours(hrs, minutes); + } + public void setHours(int hrs, int minutes, int seconds) { + setUTCHours(hrs, minutes, seconds); + } + public void setHours(int hrs, int minutes, int seconds, int ms) { + setUTCHours(hrs, minutes, seconds, ms); + } + public void setMinutes(int minutes) { + setUTCMinutes(minutes); + } + public void setMinutes(int minutes, int seconds) { + setUTCMinutes(minutes, seconds); + } + public void setMinutes(int minutes, int seconds, int ms) { + setUTCMinutes(minutes, seconds, ms); + } + public void setSeconds(int seconds) { + setUTCSeconds(seconds); + } + public void setSeconds(int seconds, int ms) { + setUTCSeconds(seconds, ms); + } + public void setMilliseconds(int ms) { + setUTCMilliseconds(ms); + } - public static long UTC(int year, int month, int date, - int hrs, int min, int sec) { - return Date.UTC(year - 1900, month, date, hrs, min, sec); + // Milliseconds since Jan 1, 1970, 00:00:00.000 GMT + public void setTime(long dateMilliSecond) { + instant = Instant.ofEpochMilli(dateMilliSecond); + initZonedLocalDateTime(); + } + public int getTimezoneOffset() { + int seconds = ZoneId.systemDefault().getRules().getOffset(instant).getTotalSeconds(); + return -seconds/60; } - private static String createDateTimeFromPattern (int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { + public static long parse(String value, String format) { + try { + DateFormat dateFormat = new SimpleDateFormat(format); + return dateFormat.parse(value).getTime(); + } catch (Exception e) { + return -1; + } + } + public static long parse(String value) { + DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( + "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); + try { + TemporalAccessor accessor = isoDateFormatter.parseBest(value, + ZonedDateTime::from, + LocalDateTime::from, + LocalDate::from); + Instant instant = Instant.from(accessor); + return Instant.EPOCH.until(instant, ChronoUnit.MILLIS); + } catch (Exception e) { + return -1; + } + } + private static String createDateTimeFromPattern(int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { String yearStr = String.format("%04d", year); - if (yearStr.substring(0, 2).equals("00")) yearStr = "20" + yearStr.substring(2,4); + yearStr = yearStr.substring(0, 2).equals("00") ? year < 70 ? "20" + yearStr.substring(2,4) : "19" + yearStr.substring(2,4) : yearStr; String monthStr = String.format("%02d", month); String dateStr = String.format("%02d", date); String hrsStr = String.format("%02d", hrs); String minStr = String.format("%02d", min); String secondStr = String.format("%02d", second); + String secondMilliStr = String.format("%03d", secondMilli); String tzStr = tz.length > 0 ? Arrays.stream(tz).findFirst().get() : "Z"; - return String.format(patternDefault, yearStr, monthStr, dateStr, hrsStr, minStr, secondStr, secondMilli, tzStr); + return String.format(patternDefault, yearStr, monthStr, dateStr, hrsStr, minStr, secondStr, secondMilliStr, tzStr); + } + + private void parseInstant(String s) { + try{ + if (s.length() > 0 && Character.isDigit(s.charAt(0))) { + // assuming UTC instant "2007-12-03T10:15:30.00Z" + instant = Instant.parse(s); + } + else { + // assuming RFC-1123 value "Tue, 3 Jun 2008 11:05:30 GMT-02:00" + instant = Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(s)); + } + initZonedLocalDateTime(); + } catch (final DateTimeParseException ex) { + final ConversionException exception = new ConversionException("Cannot parse value [" + s + "] as instant", ex); + throw exception; + } } } diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java index 1e71795f97..3c803f1eff 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbUtils.java @@ -658,28 +658,5 @@ public class TbUtils { } return true; } - - public static long parse(String value, String format) { - try { - DateFormat dateFormat = new SimpleDateFormat(format); - return dateFormat.parse(value).getTime(); - } catch (Exception e) { - return -1; - } - } - public static long parse(String value) { - DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( - "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); - try { - TemporalAccessor accessor = isoDateFormatter.parseBest(value, - ZonedDateTime::from, - LocalDateTime::from, - LocalDate::from); - Instant instant = Instant.from(accessor); - return Instant.EPOCH.until(instant, ChronoUnit.MILLIS); - } catch (Exception e) { - return -1; - } - } - } + diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 5115940a6b..75027247b1 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -27,19 +27,10 @@ import org.junit.jupiter.api.Test; import org.mvel2.ConversionException; import org.thingsboard.common.util.JacksonUtil; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.chrono.IsoChronology; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; -import java.time.format.FormatStyle; +import java.time.format.DateTimeParseException; import java.util.ArrayList; -import java.util.Calendar; import java.util.List; import java.util.Locale; -import java.util.TimeZone; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; @@ -126,8 +117,8 @@ class TbDateTest { String tsStr = String.format(pattern, hrs); //Thu Feb 29 2024 14:35:42.987 GMT+0000 TbDate tbDate = new TbDate(tsStr); long ts = 1709217342987L; //Thu Feb 29 2024 14:35:42.987 GMT+0000 - Assert.assertEquals(ts, tbDate.millis()); - int offset = Calendar.getInstance().get(Calendar.ZONE_OFFSET); // for example 3600000 for GMT + 1 + Assert.assertEquals(ts, tbDate.parseSecondMilli()); + int offsetMin = tbDate.getTimezoneOffset(); // for example 3600000 for GMT + 1 String datePrefix = tsStr; //without time zone assertThat(tbDate.toISOString()) @@ -136,20 +127,29 @@ class TbDateTest { assertThat(executor.submit(tbDate::toISOString).get(30, TimeUnit.SECONDS)) .as("format in executor thread") .startsWith(datePrefix); - int offsetHrs = offset/1000/60/60; + int offsetHrs = offsetMin/60; String datePrefixLocal = String.format(pattern, (hrs - offsetHrs)); - assertThat(new TbDate(ts - offset).toISOString()) + long offsetMilli = offsetMin*60*1000; + assertThat(new TbDate(ts - offsetMilli).toISOString()) .as("new instance format in main thread") .startsWith(datePrefixLocal); - assertThat(executor.submit(() -> new TbDate(ts - offset).toISOString()).get(30, TimeUnit.SECONDS)) + assertThat(executor.submit(() -> new TbDate(ts - offsetMilli).toISOString()).get(30, TimeUnit.SECONDS)) .as("new instance format in executor thread") .startsWith(datePrefixLocal); } @Test void testToLocaleDateString() { - TbDate d = new TbDate(1693962245000L); - + String s = "09:15:30 PM, Sun 10/09/2022"; + String pattern = "hh:mm:ss a, EEE M/d/uuuu"; + TbDate d = new TbDate(s, pattern, Locale.US); + Assert.assertEquals("2022-10-09T18:15:30Z", d.toISOString()); + s = "09:15:30 пп, середа, 4 жовтня 2023 р."; + pattern = "hh:mm:ss a, EEEE, d MMMM y 'р.'"; + d = new TbDate(s, pattern, Locale.forLanguageTag("uk-UA")); + Assert.assertEquals("2023-10-04T18:15:30Z", d.toISOString()); + + d = new TbDate(1693962245000L); Assert.assertEquals("2023-09-06T01:04:05Z", d.toISOString()); // Depends on time zone, so we just check it works; @@ -309,18 +309,19 @@ class TbDateTest { Assert.assertEquals("2023-09-06T03:04:05Z", d.toISOString()); String stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 GMT"; d = new TbDate(stringDateRFC_1123); - Assert.assertEquals("2023-06-03T11:05:30Z", d.toISOString()); - stringDateRFC_1123 = "Thu, 29 Feb 2024 11:05:30 GMT"; + stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 +0400"; + d = new TbDate(stringDateRFC_1123); + Assert.assertEquals("2023-06-03T07:05:30Z", d.toISOString()); + stringDateRFC_1123 = "Thu, 29 Feb 2024 11:05:30 -03"; d = new TbDate(stringDateRFC_1123); - Assert.assertEquals("2024-02-29T11:05:30Z", d.toISOString()); + Assert.assertEquals("2024-02-29T14:05:30Z", d.toISOString()); String stringDateRFC_1123_error = "Tue, 3 Jun 2023 11:05:30 GMT"; - Exception exception = assertThrows(ConversionException.class, () -> { + Exception actual = assertThrows(ConversionException.class, () -> { new TbDate(stringDateRFC_1123_error); }); - String expectedMessage = "Cannot parse value [Tue, 3 Jun 2023 11:05:30 GMT] as instant"; - String actualMessage = exception.getMessage(); - assertTrue(actualMessage.contains(expectedMessage)); + String expectedMessage = "Cannot parse value"; + assertTrue(actual.getMessage().contains(expectedMessage)); } @Test @@ -329,6 +330,13 @@ class TbDateTest { TbDate d = new TbDate(stringDateUTC); Assert.assertEquals(1693962245345L, d.parseSecondMilli()); Assert.assertEquals(1693962245L, d.parseSecond()); + String stringDateStart = "1970-01-01T00:00:00Z"; + d = new TbDate(stringDateStart); + long actualMillis = TbDate.parse("1970-01-01 T00:00:00"); + Assert.assertEquals(d.getTimezoneOffset(), actualMillis/60/1000); + String pattern = "yyyy-MM-dd HH:mm:ss.SSS"; + String stringDate = "1995-12-04 00:12:00.000"; + Assert.assertNotEquals(-1L, TbDate.parse(stringDate, pattern)); } @Test @@ -351,25 +359,310 @@ class TbDateTest { Assert.assertEquals("2023-09-08T02:04:05.567Z", d.toISOString()); } - private static String toLocalString(TbDate d, Locale locale, ZoneId tz) { - LocalDateTime ldt = d.getLocalDateTime(); + @Test + void TestMethodGetAsDateUTC () { + TbDate dd = new TbDate(TbDate.UTC(1996, 2, 2, 3, 4, 5)); + Assert.assertEquals(823230245000L, dd.valueOf()); + dd = new TbDate(1996, 2, 2, 3, 4, 5); + Assert.assertEquals(823230245000L, dd.valueOf()); + TbDate beforeStartUTC = new TbDate(1969, 7, 20, 20, 17, 40); + Assert.assertEquals(-14182940000L, beforeStartUTC.getTime()); + + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"+02:00"); + TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 567,"-02:00"); + + Assert.assertEquals(189292530567L, d1.getTime()); + Assert.assertEquals(189306930567L, d2.getTime()); + Assert.assertEquals(d1.getTimezoneOffset(), d2.getTimezoneOffset()); + + Assert.assertEquals(1975, d1.getUTCFullYear()); + Assert.assertEquals(1976, d2.getUTCFullYear()); + + Assert.assertEquals(12, d1.getUTCMonth()); + Assert.assertEquals(1, d2.getUTCMonth()); + + Assert.assertEquals(31, d1.getUTCDate()); + Assert.assertEquals(1, d2.getUTCDate()); + + Assert.assertEquals(3, d1.getUTCDay()); + Assert.assertEquals(4, d2.getUTCDay()); + + Assert.assertEquals(21, d1.getUTCHours()); + Assert.assertEquals(1, d2.getUTCHours()); + + Assert.assertEquals(15, d1.getUTCMinutes()); + Assert.assertEquals(15, d2.getUTCMinutes()); + + Assert.assertEquals(30, d1.getUTCSeconds()); + Assert.assertEquals(30, d2.getUTCSeconds()); + + Assert.assertEquals(567, d1.getUTCMilliseconds()); + Assert.assertEquals(567, d2.getUTCMilliseconds()); + } @Test + void TestMethodGetAsDateLocal () { + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"+02:00"); + TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 567,"-02:00"); + TbDate dLocal1 = new TbDate(d1.parseSecondMilli()-d1.getTimezoneOffset()*60*1000); + TbDate dLocal2 = new TbDate(d2.parseSecondMilli()-d2.getTimezoneOffset()*60*1000); + + Assert.assertEquals(dLocal1.getUTCFullYear(), d1.getFullYear()); + Assert.assertEquals(dLocal2.getUTCFullYear(), d2.getFullYear()); + + Assert.assertEquals(dLocal1.getUTCMonth(), d1.getMonth()); + Assert.assertEquals(dLocal2.getUTCMonth(), d2.getMonth()); + + Assert.assertEquals(dLocal1.getUTCDate(), d1.getDate()); + Assert.assertEquals(dLocal2.getUTCDate(), d2.getDate()); + + Assert.assertEquals(dLocal1.getUTCDay(), d1.getDay()); + Assert.assertEquals(dLocal1.getUTCDay(), d2.getDay()); + + Assert.assertEquals(dLocal1.getUTCHours(), d1.getHours()); + Assert.assertEquals(dLocal2.getUTCHours(), d2.getHours()); + + Assert.assertEquals(dLocal1.getUTCMinutes(), d1.getMinutes()); + Assert.assertEquals(dLocal2.getUTCMinutes(), d2.getMinutes()); -// new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale) + Assert.assertEquals(dLocal1.getUTCSeconds(), d1.getSeconds()); + Assert.assertEquals(dLocal2.getUTCSeconds(), d2.getSeconds()); - String formatPattern = - DateTimeFormatterBuilder.getLocalizedDateTimePattern( - FormatStyle.SHORT, - FormatStyle.MEDIUM, - IsoChronology.INSTANCE, - locale); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, locale); - return formatter.format(ldt); + Assert.assertEquals(dLocal1.getUTCMilliseconds(), d1.getMilliseconds()); + Assert.assertEquals(dLocal2.getUTCMilliseconds(), d2.getMilliseconds()); } - private static String toLocalString2(TbDate d, Locale locale, ZoneId tz) { - DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale); - dateFormat.setTimeZone(TimeZone.getTimeZone(tz)); - return dateFormat.format(d); + @Test + void TestMethodSetUTCFullYearMonthDate() { + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-03:00"); + Assert.assertEquals(1976, d1.getUTCFullYear()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCFullYear(1969); + Assert.assertEquals(1969, d1.getUTCFullYear()); + d1.setUTCFullYear(1975); + Assert.assertEquals(1975, d1.getUTCFullYear()); + Assert.assertEquals(3, d1.getUTCDay()); + d1.setUTCFullYear(1977, 4); + Assert.assertEquals(1977, d1.getUTCFullYear()); + Assert.assertEquals(4, d1.getUTCMonth()); + Assert.assertEquals(5, d1.getUTCDay()); + d1.setUTCFullYear(2023, 2, 24); + Assert.assertEquals(2023, d1.getUTCFullYear()); + Assert.assertEquals(2, d1.getUTCMonth()); + Assert.assertEquals(24, d1.getUTCDate()); + Assert.assertEquals(5, d1.getUTCDay()); + + d1.setUTCMonth(11); + Assert.assertEquals(11, d1.getUTCMonth()); + Assert.assertEquals(5, d1.getUTCDay()); + d1.setUTCMonth(2, 28); + Assert.assertEquals(2, d1.getUTCMonth()); + Assert.assertEquals(28, d1.getUTCDate()); + Assert.assertEquals(2, d1.getUTCDay()); + + d1.setUTCDate(11); + Assert.assertEquals(11, d1.getUTCDate()); + Assert.assertEquals(6, d1.getUTCDay()); + } + + @Test + void TestMethodSetUTCHoursMinutesSecondsMilliSec() { + TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-03:00"); + Assert.assertEquals(2, d1.getUTCHours()); + Assert.assertEquals(4, d1.getUTCDay()); + + d1.setUTCHours(5); + Assert.assertEquals(5, d1.getUTCHours()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCHours(12, 45); + Assert.assertEquals(12, d1.getUTCHours()); + Assert.assertEquals(45, d1.getUTCMinutes()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCHours(0, 12, 59); + Assert.assertEquals(0, d1.getUTCHours()); + Assert.assertEquals(12, d1.getUTCMinutes()); + Assert.assertEquals(59, d1.getUTCSeconds()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCHours(4, 58, 2, 456); + Assert.assertEquals(4, d1.getUTCHours()); + Assert.assertEquals(58, d1.getUTCMinutes()); + Assert.assertEquals(2, d1.getUTCSeconds()); + Assert.assertEquals(456, d1.getUTCMilliseconds()); + Assert.assertEquals(4, d1.getUTCDay()); + + d1.setUTCMinutes(5); + Assert.assertEquals(5, d1.getUTCMinutes()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCMinutes(15, 32); + Assert.assertEquals(15, d1.getUTCMinutes()); + Assert.assertEquals(32, d1.getUTCSeconds()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCMinutes(10, 42, 321); + Assert.assertEquals(10, d1.getUTCMinutes()); + Assert.assertEquals(42, d1.getUTCSeconds()); + Assert.assertEquals(321, d1.getUTCMilliseconds()); + Assert.assertEquals(4, d1.getUTCDay()); + + d1.setUTCSeconds(5); + Assert.assertEquals(5, d1.getUTCSeconds()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCSeconds(15, 32); + Assert.assertEquals(15, d1.getUTCSeconds()); + Assert.assertEquals(32, d1.getUTCMilliseconds()); + Assert.assertEquals(4, d1.getUTCDay()); + + d1.setUTCMilliseconds(5); + Assert.assertEquals(5, d1.getUTCMilliseconds()); + Assert.assertEquals(4, d1.getUTCDay()); + } + @Test + void TestMethodSetTome() { + TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-03:00"); + long dateMilliSecond = d1.getTime(); + int fiveMinutesInMillis = 5 * 60 * 1000; + Assert.assertEquals(15, d1.getUTCMinutes()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setTime(dateMilliSecond + fiveMinutesInMillis); + Assert.assertEquals(20, d1.getUTCMinutes()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setTime(-378682769433L); + Assert.assertEquals(1958, d1.getUTCFullYear()); + Assert.assertEquals(1, d1.getUTCMonth()); + Assert.assertEquals(1, d1.getUTCDate()); + Assert.assertEquals(2, d1.getUTCHours()); + Assert.assertEquals(20, d1.getUTCMinutes()); + Assert.assertEquals(30, d1.getUTCSeconds()); + Assert.assertEquals(567, d1.getUTCMilliseconds()); + Assert.assertEquals(3, d1.getUTCDay()); } + @Test + void TestMethodSeFullYearMonthDate() { + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-03:00"); + Assert.assertEquals(1976, d1.getFullYear()); + Assert.assertEquals(1, d1.getMonth()); + Assert.assertEquals(1, d1.getDate()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setFullYear(1969); + Assert.assertEquals(1969, d1.getFullYear()); + d1.setUTCFullYear(1975); + Assert.assertEquals(1975, d1.getFullYear()); + Assert.assertEquals(3, d1.getUTCDay()); + d1.setFullYear(1977, 4); + Assert.assertEquals(1977, d1.getFullYear()); + Assert.assertEquals(4, d1.getMonth()); + Assert.assertEquals(5, d1.getDay()); + d1.setFullYear(2023, 2, 24); + Assert.assertEquals(2023, d1.getFullYear()); + Assert.assertEquals(2, d1.getMonth()); + Assert.assertEquals(24, d1.getDate()); + Assert.assertEquals(5, d1.getDay()); + + d1.setMonth(11); + Assert.assertEquals(11, d1.getMonth()); + Assert.assertEquals(5, d1.getDay()); + d1.setMonth(2, 28); + Assert.assertEquals(2, d1.getMonth()); + Assert.assertEquals(28, d1.getDate()); + Assert.assertEquals(2, d1.getDay()); + + d1.setDate(11); + Assert.assertEquals(11, d1.getDate()); + Assert.assertEquals(6, d1.getDay()); + } + @Test + void TestMethodSeHoursMinutesSecondsMilliSec() { + TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-03:00"); + Assert.assertEquals(5, d1.getHours()); + Assert.assertEquals(4, d1.getDay()); + + d1.setHours(5); + Assert.assertEquals(8, d1.getHours()); + Assert.assertEquals(4, d1.getDay()); + d1.setHours(23, 45); + Assert.assertEquals(1, d1.getMonth()); + Assert.assertEquals(2, d1.getDate()); + Assert.assertEquals(2, d1.getHours()); + Assert.assertEquals(45, d1.getMinutes()); + Assert.assertEquals(5, d1.getDay()); + d1.setUTCHours(0, 12, 59); + Assert.assertEquals(3, d1.getHours()); + Assert.assertEquals(12, d1.getMinutes()); + Assert.assertEquals(59, d1.getSeconds()); + Assert.assertEquals(4, d1.getDay()); + d1.setUTCHours(4, 58, 2, 456); + Assert.assertEquals(7, d1.getHours()); + Assert.assertEquals(58, d1.getMinutes()); + Assert.assertEquals(2, d1.getSeconds()); + Assert.assertEquals(456, d1.getMilliseconds()); + Assert.assertEquals(4, d1.getDay()); + + d1.setMinutes(5); + Assert.assertEquals(5, d1.getMinutes()); + Assert.assertEquals(4, d1.getUTCDay()); + d1.setMinutes(15, 32); + Assert.assertEquals(15, d1.getMinutes()); + Assert.assertEquals(32, d1.getSeconds()); + Assert.assertEquals(4, d1.getDay()); + d1.setMinutes(10, 42, 321); + Assert.assertEquals(10, d1.getMinutes()); + Assert.assertEquals(42, d1.getSeconds()); + Assert.assertEquals(321, d1.getMilliseconds()); + Assert.assertEquals(4, d1.getDay()); + + d1.setSeconds(5); + Assert.assertEquals(5, d1.getSeconds()); + Assert.assertEquals(4, d1.getDay()); + d1.setSeconds(15, 32); + Assert.assertEquals(15, d1.getSeconds()); + Assert.assertEquals(32, d1.getMilliseconds()); + Assert.assertEquals(4, d1.getDay()); + + d1.setMilliseconds(5); + Assert.assertEquals(5, d1.getMilliseconds()); + Assert.assertEquals(4, d1.getDay()); + } + @Test + public void toStringAsJs() { + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-14:00"); + Assert.assertEquals("1976 Jan 1, Thu 16:15:30 Eastern European Time", d1.toString()); + Assert.assertEquals("1976 Jan 1, Thu 16:15:30 Eastern European Time", d1.toString("GMT")); + Assert.assertEquals("1976 Jan 1, Thu 16:15:30 Eastern European Time", d1.toString("UTC")); + Assert.assertEquals("Thursday, January 1, 1976 at 4:15:30 PM Eastern European Standard Time", d1.toString("en-US")); + Assert.assertEquals("1976 Jan 1, Thu 16:15:30", d1.toUTCString()); + Assert.assertEquals("четвер, 1 січня 1976 р., 16:15:30", d1.toUTCString("uk-UA")); + Assert.assertEquals("Thursday, January 1, 1976, 4:15:30 PM", d1.toUTCString("en-US")); + Assert.assertEquals("четвер, 1 січня 1976 р., 16:15:30", d1.toUTCString("uk-UA")); + Assert.assertEquals("Thursday, January 1, 1976, 4:15:30 PM", d1.toUTCString("en-US")); + Assert.assertEquals("1976 Jan 1, Thu", d1.toDateString()); + Assert.assertEquals("четвер, 1 січня 1976 р.", d1.toDateString("uk-UA")); + Assert.assertEquals("Thursday, January 1, 1976", d1.toDateString("en-US")); + Assert.assertEquals("16:15:30 Eastern European Time", d1.toTimeString()); + Assert.assertEquals("16:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA")); + Assert.assertEquals("4:15:30 PM Eastern European Standard Time", d1.toTimeString("en-US")); + Assert.assertEquals("1976-01-01T13:15:30.567Z", d1.toJSON()); + } + + /** + * Date.UTC(0) + * -2208988800000 + * > "Mon, 01 Jan 1900 00:00:00 GMT" + * new Date(Date.UTC(0, 0, 0, 0, 0, 0)); + * "Sun, 31 Dec 1899 00:00:00 GMT" + */ + @Test + public void toUTC() { + Assert.assertEquals(-2209075200000L, TbDate.UTC(0)); + Assert.assertEquals("1899-12-31T00:00:00Z", new TbDate(TbDate.UTC(0)).toJSON()); + Assert.assertEquals("1996-02-02T03:04:05Z", new TbDate(TbDate.UTC(96, 2, 2, 3, 4, 5)).toJSON()); + Assert.assertEquals("2022-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(22, 0, 0, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("0903-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(903, 0, 0, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("1958-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(1958, 0, 0, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("2032-04-05T03:04:05.678Z", new TbDate(TbDate.UTC(2032, 4, 5, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("2024-02-29T03:04:05.678Z", new TbDate(TbDate.UTC(2024, 2, 29, 3, 4, 5, 678)).toJSON()); + Exception actual = assertThrows(DateTimeParseException.class, () -> { + TbDate.UTC(2023, 2, 29, 3, 4, 5, 678); + }); + String expectedMessage = "could not be parsed"; + assertTrue(actual.getMessage().contains(expectedMessage)); + } } + From 5126c9abab6acff8a18e9bbb4b326aa5155287f5 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 17 Oct 2023 16:20:01 +0300 Subject: [PATCH 31/61] tbDate: delete timeZneId --- .../thingsboard/script/api/tbel/TbDate.java | 309 ++++---- .../script/api/tbel/TbDateTest.java | 673 +++++++++++------- .../script/api/tbel/TbDateTestEntity.java | 90 +++ 3 files changed, 663 insertions(+), 409 deletions(-) create mode 100644 common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTestEntity.java diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 0dba460686..146de4570f 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -26,11 +26,13 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; +import java.time.format.FormatStyle; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAccessor; import java.util.Arrays; @@ -40,38 +42,31 @@ import java.util.function.BiFunction; public class TbDate implements Serializable, Cloneable { private Instant instant; - private ZonedDateTime zonedDateTime; - private LocalDateTime localDateTime; - private final ZoneId zoneIdUTC = ZoneId.of("UTC"); - private static String patternDefault = "%s-%s-%sT%s:%s:%s.%s%s"; + private static final ZoneId zoneIdUTC = ZoneId.of("UTC"); + private static final Locale localeUTC = Locale.forLanguageTag("UTC"); public TbDate() { this.instant = Instant.now(); - initZonedLocalDateTime(); } public TbDate(String s) { - parseInstant(s); + this.instant = parseInstant(s); } - /** - * String s = "09:15:30 PM, Sun 10/09/2022"; - * String pattern = "hh:mm:ss a, EEE M/d/uuuu"; - * @param s - * @param pattern - */ public TbDate(String s, String pattern, Locale locale) { - DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, locale); - LocalDateTime localDateTime = LocalDateTime.parse(s, dateTimeFormatter); - ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault()); - instant = zonedDateTime.toInstant(); - initZonedLocalDateTime(); + instant = parseInstant(s, pattern, locale, zoneIdUTC); + } + public TbDate(String s, String pattern, Locale locale, String zoneIdStr) { + ZoneId zoneId = ZoneId.of(zoneIdStr); + instant = parseInstant(s, pattern, locale, zoneId); + } + public TbDate(String s, String pattern, Locale locale, ZoneId zoneId) { + instant = parseInstant(s, pattern, locale, zoneId); } public TbDate(long dateMilliSecond) { instant = Instant.ofEpochMilli(dateMilliSecond); - initZonedLocalDateTime(); } public TbDate(int year, int month, int date, String... tz) { @@ -87,51 +82,45 @@ public class TbDate implements Serializable, Cloneable { } public TbDate(int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { - this(createDateTimeFromPattern(year, month, date, hrs, min, second, secondMilli, tz)); + ZoneId zoneId = tz.length > 0 ? ZoneId.of(Arrays.stream(tz).findFirst().get()) : ZoneId.systemDefault(); + instant = parseInstant(year, month, date, hrs, min, second, secondMilli, zoneId); } public Instant getInstant() { return instant; } - public void setInstant(Instant instant) { - this.instant = instant; - } public ZonedDateTime getZonedDateTime() { - return zonedDateTime; + return instant.atZone(zoneIdUTC); } - private void initZonedLocalDateTime() { - setZonedDateTime(zoneIdUTC); - setLocalDateTime(); - } - public void setZonedDateTime(ZoneId z) { - this.zonedDateTime = instant.atZone(z);; + public LocalDateTime getLocalDateTime() { + return LocalDateTime.ofInstant(this.instant, ZoneId.systemDefault()); } - public void setLocalDateTime() { - this.localDateTime = LocalDateTime.ofInstant(this.getInstant(), ZoneId.systemDefault()); - } - public LocalDateTime getLocalDateTime() { - return this.localDateTime ; + public LocalDateTime getUTCDateTime() { + return LocalDateTime.ofInstant(this.instant, zoneIdUTC); } public String toDateString() { - return toLocaleDateString("UTC", JacksonUtil.newObjectNode().put("dateStyle", "full").toString()); + return toDateString(localeUTC.getLanguage()); } public String toDateString(String locale) { - return toLocaleDateString(locale, JacksonUtil.newObjectNode().put("dateStyle", "full").toString()); + return toDateString(locale, ZoneId.systemDefault().toString()); + } + public String toDateString(String locale, String zoneStr) { + return toLocaleDateString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeZone", zoneStr).toString()); } public String toTimeString() { - return toLocaleTimeString("UTC", JacksonUtil.newObjectNode().put("timeStyle", "full").toString()); + return toTimeString(Locale.getDefault().getLanguage()); } public String toTimeString(String locale) { - return toLocaleTimeString(locale, JacksonUtil.newObjectNode().put("timeStyle", "full").toString()); + return toTimeString(locale, ZoneId.systemDefault().toString()); + } + public String toTimeString(String locale, String zoneStr) { + return toLocaleTbTimeString(locale, JacksonUtil.newObjectNode().put("timeStyle", FormatStyle.FULL.name()).put("timeZone", zoneStr).toString()); } - /** - * "2011-10-05T14:48:00.000Z" - * @return - */ + public String toISOString() { return instant.toString(); } @@ -139,59 +128,73 @@ public class TbDate implements Serializable, Cloneable { return toISOString(); } public String toUTCString() { - return toLocaleString("UTC", JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "medium").toString()); + return toUTCString(localeUTC.getLanguage()); } public String toUTCString(String locale) { - return toLocaleString(locale, JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "medium").toString()); + return toLocaleTbString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeStyle", FormatStyle.MEDIUM.name()).put("timeZone", zoneIdUTC.getId()).toString()); } - /** - * "Tue Aug 19 1975 23:15:30 GMT+0300 (за східноєвропейським стандартним часом)" - * @return - */ public String toString() { - return toLocaleString(Locale.getDefault().toString(), JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "full").toString()); + return toString(Locale.getDefault().getLanguage()); } + public String toString(String locale) { - return toLocaleString(locale, JacksonUtil.newObjectNode().put("dateStyle", "full").put("timeStyle", "full").toString()); + return toString(locale, ZoneId.systemDefault().toString()); + } + + public String toString(String locale, String zoneStr) { + return toLocaleTbString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeStyle", FormatStyle.FULL.name()).put("timeZone", zoneStr).toString()); + } + public String toISOZonedDateTimeString() { + return getZonedDateTime().toString(); + } + public String toISOZonedDateTimeString(DateTimeFormatter formatter) { + return getZonedDateTime().format(formatter); } public String toLocaleDateString() { - return toLocaleDateString(null, null); + return toLocaleDateString(localeUTC.getLanguage()); } public String toLocaleDateString(String locale) { - return toLocaleDateString(locale, null); + return toLocaleDateString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeZone", ZoneId.systemDefault().toString()).toString()); } public String toLocaleDateString(String localeStr, String optionsStr) { - return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDate(options.getDateStyle()).withLocale(locale)); + return toLocaleTbString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDate(options.getDateStyle()).withLocale(locale)); } public String toLocaleTimeString() { - return toLocaleTimeString(null, null); + return toLocaleTimeString(Locale.getDefault().getLanguage()); } - public String toLocaleTimeString(String locale) { - return toLocaleTimeString(locale, null); + public String toLocaleTimeString(String localeStr) { + return toLocaleTimeString(localeStr, ZoneId.systemDefault().toString()); } - public String toLocaleTimeString(String localeStr, String optionsStr) { - return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); + public String toLocaleTimeString(String localeStr, String zoneStr) { + return toLocaleTbTimeString(localeStr, JacksonUtil.newObjectNode().put("timeStyle", FormatStyle.MEDIUM.name()).put("timeZone", zoneStr).toString()); + } + + public String toLocaleTbTimeString(String localeStr, String optionsStr) { + return toLocaleTbString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); } public String toLocaleString() { - LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); - return localDateTime.toString(); + return toLocaleString(localeUTC.getLanguage(), ZoneId.systemDefault().toString()); } public String toLocaleString(String locale) { - return toLocaleString(locale, null); + return toLocaleString(locale, ZoneId.systemDefault().toString()); } - public String toLocaleString(String localeStr, String optionsStr) { - return toLocaleString(localeStr, optionsStr, (locale, options) -> { + public String toLocaleString(String locale, String zoneStr) { + return toLocaleTbString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.SHORT.name()).put("timeStyle", FormatStyle.MEDIUM.name()).put("timeZone", zoneStr).toString()); + } + + public String toLocaleTbString(String localeStr, String optionsStr) { + return toLocaleTbString(localeStr, optionsStr, (locale, options) -> { String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern( options.getDateStyle(), @@ -202,7 +205,7 @@ public class TbDate implements Serializable, Cloneable { }); } - public String toLocaleString(String localeStr, String optionsStr, BiFunction formatterBuilder) { + public String toLocaleTbString(String localeStr, String optionsStr, BiFunction formatterBuilder) { Locale locale = StringUtils.isNotEmpty(localeStr) ? Locale.forLanguageTag(localeStr) : Locale.getDefault(); DateTimeFormatOptions options = getDateFormattingOptions(optionsStr); ZonedDateTime zdt = this.getInstant().atZone(options.getTimeZone().toZoneId()); @@ -264,116 +267,130 @@ public class TbDate implements Serializable, Cloneable { year = year == 0 ? year = 1899 : year; month = month == 0 ? month = 12 : month; date = date == 0 ? date = 31 : date; - return Instant.parse(createDateTimeFromPattern (year, month, date, hrs, min, sec, ms)).toEpochMilli(); + return parseInstant(year, month, date, hrs, min, sec, ms, zoneIdUTC).toEpochMilli(); } public int getUTCFullYear() { - return zonedDateTime.getYear(); + return getUTCDateTime().getYear(); } public int getUTCMonth() { - return zonedDateTime.getMonthValue(); + return getUTCDateTime().getMonthValue(); } // day in month public int getUTCDate() { - return zonedDateTime.getDayOfMonth(); + return getUTCDateTime().getDayOfMonth(); } // day in week public int getUTCDay() { - return zonedDateTime.getDayOfWeek().getValue(); + return getUTCDateTime().getDayOfWeek().getValue(); } public int getUTCHours() { - return zonedDateTime.getHour(); + return getUTCDateTime().getHour(); } public int getUTCMinutes() { - return zonedDateTime.getMinute(); + return getZonedDateTime().getMinute(); } public int getUTCSeconds() { - return zonedDateTime.getSecond(); + return getUTCDateTime().getSecond(); } public int getUTCMilliseconds() { - return zonedDateTime.getNano()/1000000; + return getUTCDateTime().getNano()/1000000; } public void setUTCFullYear(int year) { - parseInstant(createDateTimeFromPattern(year, getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + if (getUTCDate() > 28) { + long time = getZonedDateTime().withYear(year).withDayOfMonth(1).toInstant().toEpochMilli() + (getUTCDate() - 1) * 24 * 60 * 60 * 1000L; + this.instant = Instant.ofEpochMilli(time); + } else { + this.instant = getZonedDateTime().withYear(year).toInstant(); + } } public void setUTCFullYear(int year, int month) { - parseInstant(createDateTimeFromPattern(year, month, getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + if (getUTCDate() > 28) { + long time = getZonedDateTime().withYear(year).withMonth(month).withDayOfMonth(1).toInstant().toEpochMilli() + (getUTCDate() - 1) * 24 * 60 * 60 * 1000L; + this.instant = Instant.ofEpochMilli(time); + } else { + this.instant = getZonedDateTime().withYear(year).withMonth(month).toInstant(); + } } public void setUTCFullYear(int year, int month, int date) { - parseInstant(createDateTimeFromPattern(year, month, date, getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + this.instant = getZonedDateTime().withYear(year).withMonth(month).withDayOfMonth(date).toInstant(); } public void setUTCMonth(int month) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), month, getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + if (getUTCDate() > 28) { + long time = getZonedDateTime().withMonth(month).withDayOfMonth(1).toInstant().toEpochMilli() + (getUTCDate() - 1) * 24 * 60 * 60 * 1000L; + this.instant = Instant.ofEpochMilli(time); + } else { + this.instant = getZonedDateTime().withMonth(month).toInstant(); + } } public void setUTCMonth(int month, int date) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), month, date, getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + this.instant = getZonedDateTime().withMonth(month).withDayOfMonth(date).toInstant(); } public void setUTCDate(int date) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), date, getUTCHours(), getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + this.instant = getZonedDateTime().withDayOfMonth(date).toInstant(); } public void setUTCHours(int hrs) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, getUTCMinutes(), getUTCSeconds(), getUTCMilliseconds())); + this.instant = getZonedDateTime().withHour(hrs).toInstant(); } public void setUTCHours(int hrs, int minutes) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, minutes, getUTCSeconds(), getUTCMilliseconds())); + this.instant = getZonedDateTime().withHour(hrs).withMinute(minutes).toInstant(); } public void setUTCHours(int hrs, int minutes, int seconds) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, minutes, seconds, getUTCMilliseconds())); + this.instant = getZonedDateTime().withHour(hrs).withMinute(minutes).withSecond(seconds).toInstant(); } public void setUTCHours(int hrs, int minutes, int seconds, int ms) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), hrs, minutes, seconds, ms)); + this.instant = getZonedDateTime().withHour(hrs).withMinute(minutes).withSecond(seconds).withNano(ms*1000000).toInstant(); } public void setUTCMinutes(int minutes) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), minutes, getUTCSeconds(), getUTCMilliseconds())); + this.instant = getZonedDateTime().withMinute(minutes).toInstant(); } public void setUTCMinutes(int minutes, int seconds) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), minutes, seconds, getUTCMilliseconds())); - } + this.instant = getZonedDateTime().withMinute(minutes).withSecond(seconds).toInstant(); } public void setUTCMinutes(int minutes, int seconds, int ms) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), minutes, seconds, ms)); + this.instant = parseInstant(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), minutes, seconds, ms, zoneIdUTC); } public void setUTCSeconds(int seconds) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), seconds, getUTCMilliseconds())); + this.instant = getZonedDateTime().withSecond(seconds).toInstant(); } public void setUTCSeconds(int seconds, int ms) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), seconds, ms)); + this.instant = getZonedDateTime().withSecond(seconds).withNano(ms*1000000).toInstant(); } public void setUTCMilliseconds(int ms) { - parseInstant(createDateTimeFromPattern(getUTCFullYear(), getUTCMonth(), getUTCDate(), getUTCHours(), getUTCMinutes(), getUTCSeconds(), ms)); + this.instant = getZonedDateTime().withNano(ms*1000000).toInstant(); } public int getFullYear() { - return localDateTime.getYear(); + return getLocalDateTime().getYear(); } public int getMonth() { - return localDateTime.getMonthValue(); + return getLocalDateTime().getMonthValue(); } // day in month public int getDate() { - return localDateTime.getDayOfMonth(); + return getLocalDateTime().getDayOfMonth(); } // day in week public int getDay() { - return localDateTime.getDayOfWeek().getValue(); + return getLocalDateTime().getDayOfWeek().getValue(); } public int getHours() { - return localDateTime.getHour(); + return getLocalDateTime().getHour(); } public int getMinutes() { - return localDateTime.getMinute(); + return getLocalDateTime().getMinute(); } public int getSeconds() { - return localDateTime.getSecond(); + return getLocalDateTime().getSecond(); } public int getMilliseconds() { - return localDateTime.getNano()/1000000; + return getLocalDateTime().getNano()/1000000; } // Milliseconds since Jan 1, 1970, 00:00:00.000 GMT public long getTime() { @@ -383,61 +400,84 @@ public class TbDate implements Serializable, Cloneable { return getTime() ; } public void setFullYear(int year) { - setUTCFullYear(year); + Instant instantEpochWithYear = getZonedDateTime().withYear(year).toInstant(); + if (getDate() > 28) { + long time = getLocalDateTime().withYear(year).withDayOfMonth(1).toInstant(getLocaleZoneOffset(instantEpochWithYear)).toEpochMilli() + (getDate() - 1) * 24 * 60 * 60 * 1000L; + this.instant = Instant.ofEpochMilli(time); + } else { + this.instant = getLocalDateTime().withYear(year).toInstant(getLocaleZoneOffset(instantEpochWithYear)); + } } public void setFullYear(int year, int month) { - setUTCFullYear(year, month); - } public void setFullYear(int year, int month, int date) { - setUTCFullYear(year, month, date); + Instant instantEpochWithYear = getZonedDateTime().withYear(year).withMonth(month).toInstant(); + if (getDate() > 28) { + long time = getLocalDateTime().withYear(year).withMonth(month).withDayOfMonth(1).toInstant(getLocaleZoneOffset(instantEpochWithYear)).toEpochMilli() + (getDate() - 1) * 24 * 60 * 60 * 1000L; + this.instant = Instant.ofEpochMilli(time); + } else { + this.instant = getLocalDateTime().withYear(year).withMonth(month).toInstant(getLocaleZoneOffset(instantEpochWithYear)); + } + } + public void setFullYear(int year, int month, int date) { + Instant instantEpochWithYearMonthDate = getZonedDateTime().withYear(year).withMonth(month).withDayOfMonth(date).toInstant(); + this.instant = getLocalDateTime().withYear(year).withMonth(month).withDayOfMonth(date).toInstant(getLocaleZoneOffset(instantEpochWithYearMonthDate)); } public void setMonth(int month) { - setUTCMonth(month); + Instant instantEpochWithYear = getZonedDateTime().withMonth(month).toInstant(); + if (getDate() > 28) { + long time = getLocalDateTime().withMonth(month).withDayOfMonth(1).toInstant(getLocaleZoneOffset(instantEpochWithYear)).toEpochMilli() + (getDate() - 1) * 24 * 60 * 60 * 1000L; + this.instant = Instant.ofEpochMilli(time); + } else { + this.instant = getLocalDateTime().withMonth(month).toInstant(getLocaleZoneOffset(instantEpochWithYear)); + } + } public void setMonth(int month, int date) { - setUTCMonth(month, date) ; + Instant instantEpochWithMonthDate = getZonedDateTime().withMonth(month).withDayOfMonth(date).toInstant(); + this.instant = getLocalDateTime().withMonth(month).withDayOfMonth(date).toInstant(getLocaleZoneOffset(instantEpochWithMonthDate)); } public void setDate(int date) { - setUTCDate(date); + Instant instantEpochWithDate = getZonedDateTime().withDayOfMonth(date).toInstant(); + this.instant = getLocalDateTime().withDayOfMonth(date).toInstant(getLocaleZoneOffset(instantEpochWithDate)); } public void setHours(int hrs) { - setUTCHours(hrs); + this.instant = getLocalDateTime().withHour(hrs).toInstant(getLocaleZoneOffset(this.instant)); } public void setHours(int hrs, int minutes) { - setUTCHours(hrs, minutes); + this.instant = getLocalDateTime().withHour(hrs).withMinute(minutes).toInstant(getLocaleZoneOffset(this.instant)); } public void setHours(int hrs, int minutes, int seconds) { - setUTCHours(hrs, minutes, seconds); + this.instant = getLocalDateTime().withHour(hrs).withMinute(minutes).withSecond(seconds).toInstant(getLocaleZoneOffset(this.instant)); } public void setHours(int hrs, int minutes, int seconds, int ms) { - setUTCHours(hrs, minutes, seconds, ms); + this.instant = getLocalDateTime().withHour(hrs).withMinute(minutes).withSecond(seconds).withNano(ms*1000000).toInstant(getLocaleZoneOffset(this.instant)); } public void setMinutes(int minutes) { - setUTCMinutes(minutes); + this.instant = getLocalDateTime().withMinute(minutes).toInstant(getLocaleZoneOffset(this.instant)); } public void setMinutes(int minutes, int seconds) { - setUTCMinutes(minutes, seconds); + this.instant = getLocalDateTime().withMinute(minutes).withSecond(seconds).toInstant(getLocaleZoneOffset(this.instant)); + } public void setMinutes(int minutes, int seconds, int ms) { - setUTCMinutes(minutes, seconds, ms); + this.instant = getLocalDateTime().withMinute(minutes).withSecond(seconds).withNano(ms*1000000).toInstant(getLocaleZoneOffset(this.instant)); } public void setSeconds(int seconds) { - setUTCSeconds(seconds); + this.instant = getLocalDateTime().withSecond(seconds).toInstant(getLocaleZoneOffset(this.instant)); } public void setSeconds(int seconds, int ms) { - setUTCSeconds(seconds, ms); + this.instant = getLocalDateTime().withSecond(seconds).withNano(ms*1000000).toInstant(getLocaleZoneOffset(this.instant)); } public void setMilliseconds(int ms) { - setUTCMilliseconds(ms); + this.instant = getLocalDateTime().withNano(ms*1000000).toInstant(getLocaleZoneOffset(this.instant)); } // Milliseconds since Jan 1, 1970, 00:00:00.000 GMT public void setTime(long dateMilliSecond) { instant = Instant.ofEpochMilli(dateMilliSecond); - initZonedLocalDateTime(); } - public int getTimezoneOffset() { - int seconds = ZoneId.systemDefault().getRules().getOffset(instant).getTotalSeconds(); - return -seconds/60; + + public ZoneOffset getLocaleZoneOffset(Instant... instants){ + return ZoneId.systemDefault().getRules().getOffset(instants.length > 0 ? instants[0] : this.instant); } public static long parse(String value, String format) { @@ -462,33 +502,32 @@ public class TbDate implements Serializable, Cloneable { return -1; } } - private static String createDateTimeFromPattern(int year, int month, int date, int hrs, int min, int second, int secondMilli, String... tz) { - String yearStr = String.format("%04d", year); - yearStr = yearStr.substring(0, 2).equals("00") ? year < 70 ? "20" + yearStr.substring(2,4) : "19" + yearStr.substring(2,4) : yearStr; - String monthStr = String.format("%02d", month); - String dateStr = String.format("%02d", date); - String hrsStr = String.format("%02d", hrs); - String minStr = String.format("%02d", min); - String secondStr = String.format("%02d", second); - String secondMilliStr = String.format("%03d", secondMilli); - String tzStr = tz.length > 0 ? Arrays.stream(tz).findFirst().get() : "Z"; - return String.format(patternDefault, yearStr, monthStr, dateStr, hrsStr, minStr, secondStr, secondMilliStr, tzStr); - } - private void parseInstant(String s) { + private static Instant parseInstant(String s) { try{ if (s.length() > 0 && Character.isDigit(s.charAt(0))) { // assuming UTC instant "2007-12-03T10:15:30.00Z" - instant = Instant.parse(s); + return Instant.parse(s); } else { // assuming RFC-1123 value "Tue, 3 Jun 2008 11:05:30 GMT-02:00" - instant = Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(s)); + return Instant.from(DateTimeFormatter.RFC_1123_DATE_TIME.parse(s)); } - initZonedLocalDateTime(); } catch (final DateTimeParseException ex) { final ConversionException exception = new ConversionException("Cannot parse value [" + s + "] as instant", ex); throw exception; } } + + private static Instant parseInstant(int year, int month, int date, int hrs, int min, int second, int secondMilli, ZoneId zoneId) { + year = year < 70 ? 2000 + year : year <= 99 ? 1900 + year : year; + ZonedDateTime zonedDateTime = ZonedDateTime.of(year, month, date, hrs, min, second, secondMilli*1000000, zoneId); + return zonedDateTime.toInstant(); + } + private static Instant parseInstant(String s, String pattern, Locale locale, ZoneId zoneId) { + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern, locale); + LocalDateTime localDateTime = LocalDateTime.parse(s, dateTimeFormatter); + ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); + return zonedDateTime.toInstant(); + } } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 75027247b1..f020d3e092 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -27,7 +27,9 @@ import org.junit.jupiter.api.Test; import org.mvel2.ConversionException; import org.thingsboard.common.util.JacksonUtil; -import java.time.format.DateTimeParseException; +import java.time.DateTimeException; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -113,12 +115,14 @@ class TbDateTest { void testToISOStringThreadLocalStaticFormatter() throws ExecutionException, InterruptedException, TimeoutException { executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1)); int hrs = 14; - String pattern = "2024-02-29T%s:35:42.987Z"; - String tsStr = String.format(pattern, hrs); //Thu Feb 29 2024 14:35:42.987 GMT+0000 + int date = 29; + int month = 2; + String pattern = "2024-%s-%sT%s:35:42.987Z"; + String tsStr = String.format(pattern, String.format("%02d", month), date, hrs); //Thu Feb 29 2024 14:35:42.987 GMT+0000 TbDate tbDate = new TbDate(tsStr); long ts = 1709217342987L; //Thu Feb 29 2024 14:35:42.987 GMT+0000 Assert.assertEquals(ts, tbDate.parseSecondMilli()); - int offsetMin = tbDate.getTimezoneOffset(); // for example 3600000 for GMT + 1 + int offsetLocalSecond = tbDate.getLocaleZoneOffset().getTotalSeconds(); // for example 7200 for GMT + 2 String datePrefix = tsStr; //without time zone assertThat(tbDate.toISOString()) @@ -127,13 +131,13 @@ class TbDateTest { assertThat(executor.submit(tbDate::toISOString).get(30, TimeUnit.SECONDS)) .as("format in executor thread") .startsWith(datePrefix); - int offsetHrs = offsetMin/60; - String datePrefixLocal = String.format(pattern, (hrs - offsetHrs)); - long offsetMilli = offsetMin*60*1000; - assertThat(new TbDate(ts - offsetMilli).toISOString()) + TbDateTestEntity tbDateTest = new TbDateTestEntity(tbDate.getFullYear(), month, date,hrs + offsetLocalSecond/60/60); + String datePrefixLocal = String.format(pattern, tbDateTest.geMonthStr(), tbDateTest.geDateStr(), tbDateTest.geHoursStr()); + long offsetLocalMilli = offsetLocalSecond*1000; + assertThat(new TbDate(ts + offsetLocalMilli).toISOString()) .as("new instance format in main thread") .startsWith(datePrefixLocal); - assertThat(executor.submit(() -> new TbDate(ts - offsetMilli).toISOString()).get(30, TimeUnit.SECONDS)) + assertThat(executor.submit(() -> new TbDate(ts + offsetLocalMilli).toISOString()).get(30, TimeUnit.SECONDS)) .as("new instance format in executor thread") .startsWith(datePrefixLocal); } @@ -143,11 +147,21 @@ class TbDateTest { String s = "09:15:30 PM, Sun 10/09/2022"; String pattern = "hh:mm:ss a, EEE M/d/uuuu"; TbDate d = new TbDate(s, pattern, Locale.US); - Assert.assertEquals("2022-10-09T18:15:30Z", d.toISOString()); + Assert.assertEquals("2022-10-09T21:15:30Z", d.toISOString()); + // tz = "-04:00" + d = new TbDate(s, pattern, Locale.US, "-04:00"); + Assert.assertEquals("2022-10-10T01:15:30Z", d.toISOString()); + d = new TbDate(s, pattern, Locale.US, "America/New_York"); + Assert.assertEquals("2022-10-10T01:15:30Z", d.toISOString()); + // tz = "+02:00" + s = "09:15:30 PM, So. 10/09/2022"; + d = new TbDate(s, pattern, Locale.GERMAN, ZoneId.of("Europe/Berlin")); + Assert.assertEquals("2022-10-09T19:15:30Z", d.toISOString()); + s = "09:15:30 пп, середа, 4 жовтня 2023 р."; pattern = "hh:mm:ss a, EEEE, d MMMM y 'р.'"; d = new TbDate(s, pattern, Locale.forLanguageTag("uk-UA")); - Assert.assertEquals("2023-10-04T18:15:30Z", d.toISOString()); + Assert.assertEquals("2023-10-04T21:15:30Z", d.toISOString()); d = new TbDate(1693962245000L); Assert.assertEquals("2023-09-06T01:04:05Z", d.toISOString()); @@ -204,41 +218,41 @@ class TbDateTest { Assert.assertNotNull(d.toLocaleTimeString()); Assert.assertNotNull(d.toLocaleTimeString("en-US")); - Assert.assertEquals("9:04:05 PM", d.toLocaleTimeString("en-US", "America/New_York")); - Assert.assertEquals("오후 9:04:05", d.toLocaleTimeString("ko-KR", "America/New_York")); - Assert.assertEquals("04:04:05", d.toLocaleTimeString( "uk-UA", "Europe/Kiev")); - Assert.assertEquals("9:04:05 م", d.toLocaleTimeString( "ar-EG", "America/New_York")); + Assert.assertEquals("9:04:05 PM", d.toLocaleTbTimeString("en-US", "America/New_York")); + Assert.assertEquals("오후 9:04:05", d.toLocaleTbTimeString("ko-KR", "America/New_York")); + Assert.assertEquals("04:04:05", d.toLocaleTbTimeString( "uk-UA", "Europe/Kiev")); + Assert.assertEquals("9:04:05 م", d.toLocaleTbTimeString( "ar-EG", "America/New_York")); - Assert.assertEquals("9:04:05 PM Eastern Daylight Time", d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 PM Eastern Daylight Time", d.toLocaleTbTimeString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") .toString())); - Assert.assertEquals("오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleTimeString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleTbTimeString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") .toString())); - Assert.assertEquals("04:04:05 за східноєвропейським літнім часом", d.toLocaleTimeString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("04:04:05 за східноєвропейським літнім часом", d.toLocaleTbTimeString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("timeStyle", "full") .toString())); - Assert.assertEquals("9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleTimeString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleTbTimeString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") .toString())); - Assert.assertEquals("9:04:05 PM", d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 PM", d.toLocaleTbTimeString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") .toString())); - Assert.assertEquals("9:04:05 오후", d.toLocaleTimeString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 오후", d.toLocaleTbTimeString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") .toString())); - Assert.assertEquals("4:04:05 дп", d.toLocaleTimeString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("4:04:05 дп", d.toLocaleTbTimeString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("pattern", "h:mm:ss a") .toString())); - Assert.assertEquals("9:04:05 م", d.toLocaleTimeString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 م", d.toLocaleTbTimeString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") .toString())); @@ -252,45 +266,45 @@ class TbDateTest { Assert.assertNotNull(d.toLocaleString()); Assert.assertNotNull(d.toLocaleString("en-US")); - Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleString("en-US", "America/New_York")); - Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleString("ko-KR", "America/New_York")); - Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleString( "uk-UA", "Europe/Kiev")); - Assert.assertEquals("5\u200F/9\u200F/2023, 9:04:05 م", d.toLocaleString( "ar-EG", "America/New_York")); + Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleTbString("en-US", "America/New_York")); + Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleTbString("ko-KR", "America/New_York")); + Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleTbString( "uk-UA", "Europe/Kiev")); + Assert.assertEquals("5\u200F/9\u200F/2023, 9:04:05 م", d.toLocaleTbString( "ar-EG", "America/New_York")); - Assert.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleString("en-US", JacksonUtil.newObjectNode() + Assert.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleTbString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("2023년 9월 5일 화요일 오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("2023년 9월 5일 화요일 오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleTbString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("середа, 6 вересня 2023 р. о 04:04:05 за східноєвропейським літнім часом", d.toLocaleString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("середа, 6 вересня 2023 р. о 04:04:05 за східноєвропейським літнім часом", d.toLocaleTbString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleTbString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("9/5/2023, 9:04:05 PM", d.toLocaleString("en-US", JacksonUtil.newObjectNode() + Assert.assertEquals("9/5/2023, 9:04:05 PM", d.toLocaleTbString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); - Assert.assertEquals("9/5/2023, 9:04:05 오후", d.toLocaleString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("9/5/2023, 9:04:05 오후", d.toLocaleTbString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); - Assert.assertEquals("9/6/2023, 4:04:05 дп", d.toLocaleString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("9/6/2023, 4:04:05 дп", d.toLocaleTbString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); - Assert.assertEquals("9/5/2023, 9:04:05 م", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("9/5/2023, 9:04:05 م", d.toLocaleTbString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); @@ -301,27 +315,63 @@ class TbDateTest { String stringDateUTC = "2023-09-06T01:04:05.00Z"; TbDate d = new TbDate(stringDateUTC); Assert.assertEquals("2023-09-06T01:04:05Z", d.toISOString()); - String stringDateTZ = "2023-09-06T01:04:05.00+04:00"; + String stringDateTZ = "2023-09-06T01:04:05.00+04:00:00"; d = new TbDate(stringDateTZ); Assert.assertEquals("2023-09-05T21:04:05Z", d.toISOString()); + stringDateTZ = "2023-09-06T01:04:05.00-04:00"; + d = new TbDate(stringDateTZ); + Assert.assertEquals("2023-09-06T05:04:05Z", d.toISOString()); + stringDateTZ = "2023-09-06T01:04:05.00+04:30:56"; + d = new TbDate(stringDateTZ); + Assert.assertEquals("2023-09-05T20:33:09Z", d.toISOString()); stringDateTZ = "2023-09-06T01:04:05.00-02:00"; d = new TbDate(stringDateTZ); Assert.assertEquals("2023-09-06T03:04:05Z", d.toISOString()); String stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 GMT"; d = new TbDate(stringDateRFC_1123); - stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 +0400"; + Assert.assertEquals("2023-06-03T11:05:30Z", d.toISOString()); + stringDateRFC_1123 = "Sat, 3 Jun 2023 01:04:05 +043056"; + d = new TbDate(stringDateRFC_1123); + Assert.assertEquals("2023-06-02T20:33:09Z", d.toISOString()); + stringDateRFC_1123 = "Sat, 3 Jun 2023 11:05:30 +0400"; d = new TbDate(stringDateRFC_1123); Assert.assertEquals("2023-06-03T07:05:30Z", d.toISOString()); stringDateRFC_1123 = "Thu, 29 Feb 2024 11:05:30 -03"; d = new TbDate(stringDateRFC_1123); Assert.assertEquals("2024-02-29T14:05:30Z", d.toISOString()); - String stringDateRFC_1123_error = "Tue, 3 Jun 2023 11:05:30 GMT"; + String stringDateZ_error = "2023-09-06T01:04:05.00+04"; Exception actual = assertThrows(ConversionException.class, () -> { - new TbDate(stringDateRFC_1123_error); + new TbDate(stringDateZ_error); }); String expectedMessage = "Cannot parse value"; assertTrue(actual.getMessage().contains(expectedMessage)); + + String stringDateRFC_1123_error = "Tue, 3 Jun 2023 11:05:30 GMT"; + actual = assertThrows(ConversionException.class, () -> { + new TbDate(stringDateRFC_1123_error); + }); + assertTrue(actual.getMessage().contains(expectedMessage)); + } + + @Test + void TestDateTimeFormatterToString () { + TbDate d1 = new TbDate(23, 9, 7, 8, 4, 5, "+04:00"); + TbDate d2 = new TbDate(23, 9, 7, 8, 4, 5, "-03:00"); + + Assert.assertEquals("2023-09-07T04:04:05Z[UTC]", d1.toISOZonedDateTimeString()); + Assert.assertEquals("2023-09-07T04:04:05Z", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); + Assert.assertEquals("2023-09-07T04:04:05Z[UTC]", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + Assert.assertEquals("2023-09-07T04:04:05", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + Assert.assertEquals("Thu, 7 Sep 2023 04:04:05 GMT", d1.toISOZonedDateTimeString(DateTimeFormatter.RFC_1123_DATE_TIME)); + Assert.assertEquals("2023-09-07T04:04:05Z", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_INSTANT)); + + Assert.assertEquals("2023-09-07T11:04:05Z[UTC]", d2.toISOZonedDateTimeString()); + Assert.assertEquals("2023-09-07T11:04:05Z", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); + Assert.assertEquals("2023-09-07T11:04:05Z[UTC]", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + Assert.assertEquals("2023-09-07T11:04:05", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + Assert.assertEquals("Thu, 7 Sep 2023 11:04:05 GMT", d2.toISOZonedDateTimeString(DateTimeFormatter.RFC_1123_DATE_TIME)); + Assert.assertEquals("2023-09-07T11:04:05Z", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_INSTANT)); } @Test @@ -333,188 +383,231 @@ class TbDateTest { String stringDateStart = "1970-01-01T00:00:00Z"; d = new TbDate(stringDateStart); long actualMillis = TbDate.parse("1970-01-01 T00:00:00"); - Assert.assertEquals(d.getTimezoneOffset(), actualMillis/60/1000); + Assert.assertEquals(-d.getLocaleZoneOffset().getTotalSeconds() * 1000, actualMillis); String pattern = "yyyy-MM-dd HH:mm:ss.SSS"; String stringDate = "1995-12-04 00:12:00.000"; Assert.assertNotEquals(-1L, TbDate.parse(stringDate, pattern)); } @Test - void TestDate_Year_Moth_Date_Hs_Min_Sec () { - TbDate d = new TbDate(2023, 8, 18); - Assert.assertEquals("2023-08-18T00:00:00Z", d.toISOString()); - d = new TbDate(2023, 9, 17, 17, 34); - Assert.assertEquals("2023-09-17T17:34:00Z", d.toISOString()); - d = new TbDate(23, 9, 7, 8, 4); - Assert.assertEquals("2023-09-07T08:04:00Z", d.toISOString()); - d = new TbDate(23, 9, 7, 8, 4, 5); - Assert.assertEquals("2023-09-07T08:04:05Z", d.toISOString()); - d = new TbDate(23, 9, 7, 8, 4, 5, "+04:00"); - Assert.assertEquals("2023-09-07T04:04:05Z", d.toISOString()); - d = new TbDate(23, 9, 7, 8, 4, 5, "-03:00"); - Assert.assertEquals("2023-09-07T11:04:05Z", d.toISOString()); - d = new TbDate(23, 9, 7, 23, 4, 5, "-03:00"); - Assert.assertEquals("2023-09-08T02:04:05Z", d.toISOString()); - d = new TbDate(23, 9, 7, 23, 4, 5, 567,"-03:00"); - Assert.assertEquals("2023-09-08T02:04:05.567Z", d.toISOString()); - } - - @Test - void TestMethodGetAsDateUTC () { - TbDate dd = new TbDate(TbDate.UTC(1996, 2, 2, 3, 4, 5)); - Assert.assertEquals(823230245000L, dd.valueOf()); - dd = new TbDate(1996, 2, 2, 3, 4, 5); - Assert.assertEquals(823230245000L, dd.valueOf()); - TbDate beforeStartUTC = new TbDate(1969, 7, 20, 20, 17, 40); - Assert.assertEquals(-14182940000L, beforeStartUTC.getTime()); - - TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"+02:00"); - TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 567,"-02:00"); - - Assert.assertEquals(189292530567L, d1.getTime()); - Assert.assertEquals(189306930567L, d2.getTime()); - Assert.assertEquals(d1.getTimezoneOffset(), d2.getTimezoneOffset()); - - Assert.assertEquals(1975, d1.getUTCFullYear()); - Assert.assertEquals(1976, d2.getUTCFullYear()); - - Assert.assertEquals(12, d1.getUTCMonth()); - Assert.assertEquals(1, d2.getUTCMonth()); - - Assert.assertEquals(31, d1.getUTCDate()); - Assert.assertEquals(1, d2.getUTCDate()); - - Assert.assertEquals(3, d1.getUTCDay()); - Assert.assertEquals(4, d2.getUTCDay()); - - Assert.assertEquals(21, d1.getUTCHours()); - Assert.assertEquals(1, d2.getUTCHours()); - - Assert.assertEquals(15, d1.getUTCMinutes()); - Assert.assertEquals(15, d2.getUTCMinutes()); - - Assert.assertEquals(30, d1.getUTCSeconds()); - Assert.assertEquals(30, d2.getUTCSeconds()); - - Assert.assertEquals(567, d1.getUTCMilliseconds()); - Assert.assertEquals(567, d2.getUTCMilliseconds()); - } @Test - void TestMethodGetAsDateLocal () { - TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"+02:00"); - TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 567,"-02:00"); - TbDate dLocal1 = new TbDate(d1.parseSecondMilli()-d1.getTimezoneOffset()*60*1000); - TbDate dLocal2 = new TbDate(d2.parseSecondMilli()-d2.getTimezoneOffset()*60*1000); - + void TestMethodGetAsDateTimeLocal() { + TbDate d = new TbDate(1975, 12, 31, 23,15,30, 560); + TbDate d0 = new TbDate(1975, 12, 31, 23,15,30, 560,"UTC"); + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 561,"+03:00"); + TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 562,"-02:00"); + TbDate dLocal = new TbDate(d.parseSecondMilli() + d.getLocaleZoneOffset().getTotalSeconds()*1000); + TbDate dLocal0 = new TbDate(d0.parseSecondMilli() + d0.getLocaleZoneOffset().getTotalSeconds()*1000); + TbDate dLocal1 = new TbDate(d1.parseSecondMilli() + d1.getLocaleZoneOffset().getTotalSeconds()*1000); + TbDate dLocal2 = new TbDate(d2.parseSecondMilli() + d2.getLocaleZoneOffset().getTotalSeconds()*1000); + + Assert.assertEquals(dLocal.getUTCFullYear(), d.getFullYear()); + Assert.assertEquals(dLocal0.getUTCFullYear(), d0.getFullYear()); Assert.assertEquals(dLocal1.getUTCFullYear(), d1.getFullYear()); Assert.assertEquals(dLocal2.getUTCFullYear(), d2.getFullYear()); + Assert.assertEquals(dLocal.getUTCMonth(), d.getMonth()); + Assert.assertEquals(dLocal0.getUTCMonth(), d0.getMonth()); Assert.assertEquals(dLocal1.getUTCMonth(), d1.getMonth()); Assert.assertEquals(dLocal2.getUTCMonth(), d2.getMonth()); + Assert.assertEquals(dLocal.getUTCDate(), d.getDate()); + Assert.assertEquals(dLocal0.getUTCDate(), d0.getDate()); Assert.assertEquals(dLocal1.getUTCDate(), d1.getDate()); Assert.assertEquals(dLocal2.getUTCDate(), d2.getDate()); + Assert.assertEquals(dLocal.getUTCDay(), d.getDay()); + Assert.assertEquals(dLocal0.getUTCDay(), d0.getDay()); Assert.assertEquals(dLocal1.getUTCDay(), d1.getDay()); - Assert.assertEquals(dLocal1.getUTCDay(), d2.getDay()); + Assert.assertEquals(dLocal2.getUTCDay(), d2.getDay()); + Assert.assertEquals(dLocal.getUTCHours(), d.getHours()); + Assert.assertEquals(dLocal0.getUTCHours(), d0.getHours()); Assert.assertEquals(dLocal1.getUTCHours(), d1.getHours()); Assert.assertEquals(dLocal2.getUTCHours(), d2.getHours()); + Assert.assertEquals(dLocal.getUTCMinutes(), d.getMinutes()); + Assert.assertEquals(dLocal0.getUTCMinutes(), d0.getMinutes()); Assert.assertEquals(dLocal1.getUTCMinutes(), d1.getMinutes()); Assert.assertEquals(dLocal2.getUTCMinutes(), d2.getMinutes()); + Assert.assertEquals(dLocal.getUTCSeconds(), d.getSeconds()); + Assert.assertEquals(dLocal0.getUTCSeconds(), d0.getSeconds()); Assert.assertEquals(dLocal1.getUTCSeconds(), d1.getSeconds()); Assert.assertEquals(dLocal2.getUTCSeconds(), d2.getSeconds()); + Assert.assertEquals(dLocal.getUTCMilliseconds(), d.getMilliseconds()); + Assert.assertEquals(dLocal0.getUTCMilliseconds(), d0.getMilliseconds()); Assert.assertEquals(dLocal1.getUTCMilliseconds(), d1.getMilliseconds()); Assert.assertEquals(dLocal2.getUTCMilliseconds(), d2.getMilliseconds()); } + @Test + void Test_Year_Moth_Date_Hours_Min_Sec_Without_TZ() { + TbDate d = new TbDate(2023, 8, 18); + Assert.assertEquals("2023-08-18 00:00:00", d.toLocaleString()); + d = new TbDate(2023, 9, 17, 17, 34); + Assert.assertEquals("2023-09-17 17:34:00", d.toLocaleString()); + d = new TbDate(23, 9, 7, 8, 4); + Assert.assertEquals("2023-09-07 08:04:00", d.toLocaleString()); + d = new TbDate(23, 9, 7, 8, 4, 5); + Assert.assertEquals("2023-09-07 08:04:05", d.toLocaleString()); + d = new TbDate(23, 9, 7, 8, 4, 5, 567); + Assert.assertEquals("2023-09-07 08:04:05", d.toLocaleString()); + } + + /** + * Tests for: + * min TZ = "Etc/GMT+12" = '-12' + * max TZ = "Etc/GMT-14" = '+14' + */ + @Test + void Test_Get_LocalDateTime_With_TZ() { + int hrs = 8; + int date = 7; + int tz = 0; + String pattern = "2023-09-%s %s:04:05"; + String tzStr = "+00:00"; + TbDate d = new TbDate(23, 9, date, hrs, 4, 5, tzStr); + int localOffsetHrs = ZoneId.systemDefault().getRules().getOffset(d.getInstant()).getTotalSeconds()/60/60; + TbDateTestEntity tbDateTest = new TbDateTestEntity(23, 9, date, hrs + localOffsetHrs - tz); + String expected = String.format(pattern, tbDateTest.geDateStr(), tbDateTest.geHoursStr()); + Assert.assertEquals(expected, d.toLocaleString()); + + tz = 3; + tzStr = "+03:00"; + d = new TbDate(23, 9, date, hrs, 4, 5, tzStr); + localOffsetHrs = ZoneId.systemDefault().getRules().getOffset(d.getInstant()).getTotalSeconds()/60/60; + tbDateTest = new TbDateTestEntity(23, 9, date, hrs + localOffsetHrs - tz); + expected = String.format(pattern, tbDateTest.geDateStr(), tbDateTest.geHoursStr()); + Assert.assertEquals(expected, d.toLocaleString()); + + tz = -4; + tzStr = "-04:00"; + d = new TbDate(23, 9, date, hrs, 4, 5, tzStr); + localOffsetHrs = ZoneId.systemDefault().getRules().getOffset(d.getInstant()).getTotalSeconds()/60/60; + tbDateTest = new TbDateTestEntity(23, 9, date, hrs + localOffsetHrs - tz); + expected = String.format(pattern, tbDateTest.geDateStr(), tbDateTest.geHoursStr()); + Assert.assertEquals(expected, d.toLocaleString()); + } + + @Test + void TestMethodGetTimeUTC() { + TbDate dd = new TbDate(TbDate.UTC(1996, 1, 2, 3, 4, 5)); + Assert.assertEquals(820551845000L, dd.valueOf()); + dd = new TbDate(1996, 1, 2, 3, 4, 5); + Assert.assertEquals(820544645000L, dd.valueOf()); + TbDate beforeStartUTC = new TbDate(1969, 7, 20, 20, 17, 40); + Assert.assertEquals(-14193740000L, beforeStartUTC.getTime()); + + TbDate d = new TbDate(1975, 12, 31, 23,15,30, 560); + TbDate d0 = new TbDate(1975, 12, 31, 23,15,30, 560,"UTC"); + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 561,"+03:00"); + TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 562,"-04:00"); + + Assert.assertEquals(189288930560L, d.valueOf()); + Assert.assertEquals(189299730560L, d0.valueOf()); + Assert.assertEquals(189288930561L, d1.valueOf()); + Assert.assertEquals(189314130562L, d2.getTime()); + } + @Test void TestMethodSetUTCFullYearMonthDate() { - TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-03:00"); - Assert.assertEquals(1976, d1.getUTCFullYear()); - Assert.assertEquals(4, d1.getUTCDay()); + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-04:00"); + TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 567,"+04:00"); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + d1.setUTCFullYear(1969); - Assert.assertEquals(1969, d1.getUTCFullYear()); - d1.setUTCFullYear(1975); - Assert.assertEquals(1975, d1.getUTCFullYear()); - Assert.assertEquals(3, d1.getUTCDay()); - d1.setUTCFullYear(1977, 4); - Assert.assertEquals(1977, d1.getUTCFullYear()); - Assert.assertEquals(4, d1.getUTCMonth()); - Assert.assertEquals(5, d1.getUTCDay()); - d1.setUTCFullYear(2023, 2, 24); - Assert.assertEquals(2023, d1.getUTCFullYear()); - Assert.assertEquals(2, d1.getUTCMonth()); - Assert.assertEquals(24, d1.getUTCDate()); - Assert.assertEquals(5, d1.getUTCDay()); + d2.setUTCFullYear(1969); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCFullYear(1975, 5); + d2.setUTCFullYear(2023, 11); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCFullYear(2023, 2, 28); + d2.setUTCFullYear(2023, 12, 31); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); d1.setUTCMonth(11); - Assert.assertEquals(11, d1.getUTCMonth()); - Assert.assertEquals(5, d1.getUTCDay()); - d1.setUTCMonth(2, 28); - Assert.assertEquals(2, d1.getUTCMonth()); - Assert.assertEquals(28, d1.getUTCDate()); - Assert.assertEquals(2, d1.getUTCDay()); - - d1.setUTCDate(11); - Assert.assertEquals(11, d1.getUTCDate()); - Assert.assertEquals(6, d1.getUTCDay()); + d2.setUTCMonth(2); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCMonth(5, 20); + d2.setUTCMonth(2, 8); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCDate(6); + d2.setUTCDate(15); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); } @Test void TestMethodSetUTCHoursMinutesSecondsMilliSec() { - TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-03:00"); - Assert.assertEquals(2, d1.getUTCHours()); - Assert.assertEquals(4, d1.getUTCDay()); + TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "+02:00"); + TbDate d2 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-02:00"); + + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); d1.setUTCHours(5); - Assert.assertEquals(5, d1.getUTCHours()); - Assert.assertEquals(4, d1.getUTCDay()); - d1.setUTCHours(12, 45); - Assert.assertEquals(12, d1.getUTCHours()); - Assert.assertEquals(45, d1.getUTCMinutes()); - Assert.assertEquals(4, d1.getUTCDay()); + d2.setUTCHours(23); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCHours(23, 45); + d2.setUTCHours(1, 5); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + d1.setUTCHours(0, 12, 59); - Assert.assertEquals(0, d1.getUTCHours()); - Assert.assertEquals(12, d1.getUTCMinutes()); - Assert.assertEquals(59, d1.getUTCSeconds()); - Assert.assertEquals(4, d1.getUTCDay()); - d1.setUTCHours(4, 58, 2, 456); - Assert.assertEquals(4, d1.getUTCHours()); - Assert.assertEquals(58, d1.getUTCMinutes()); - Assert.assertEquals(2, d1.getUTCSeconds()); - Assert.assertEquals(456, d1.getUTCMilliseconds()); - Assert.assertEquals(4, d1.getUTCDay()); + d2.setUTCHours(4, 45, 01); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCHours(2, 32, 49, 123); + d2.setUTCHours(8, 45, 12, 234); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); d1.setUTCMinutes(5); - Assert.assertEquals(5, d1.getUTCMinutes()); - Assert.assertEquals(4, d1.getUTCDay()); - d1.setUTCMinutes(15, 32); - Assert.assertEquals(15, d1.getUTCMinutes()); - Assert.assertEquals(32, d1.getUTCSeconds()); - Assert.assertEquals(4, d1.getUTCDay()); - d1.setUTCMinutes(10, 42, 321); - Assert.assertEquals(10, d1.getUTCMinutes()); - Assert.assertEquals(42, d1.getUTCSeconds()); - Assert.assertEquals(321, d1.getUTCMilliseconds()); - Assert.assertEquals(4, d1.getUTCDay()); + d2.setUTCMinutes(15); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); - d1.setUTCSeconds(5); - Assert.assertEquals(5, d1.getUTCSeconds()); - Assert.assertEquals(4, d1.getUTCDay()); - d1.setUTCSeconds(15, 32); - Assert.assertEquals(15, d1.getUTCSeconds()); - Assert.assertEquals(32, d1.getUTCMilliseconds()); - Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCMinutes(5, 34); + d2.setUTCMinutes(25, 43); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); - d1.setUTCMilliseconds(5); - Assert.assertEquals(5, d1.getUTCMilliseconds()); - Assert.assertEquals(4, d1.getUTCDay()); + d1.setUTCMinutes(25, 14, 567); + d2.setUTCMinutes(45, 3, 876); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCSeconds(5); + d2.setUTCSeconds(23); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCSeconds(45, 987); + d2.setUTCSeconds(54, 842); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setUTCMilliseconds(675); + d1.setUTCMilliseconds(923); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); } @Test - void TestMethodSetTome() { + void TestMethodSetTime() { TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-03:00"); long dateMilliSecond = d1.getTime(); int fiveMinutesInMillis = 5 * 60 * 1000; @@ -533,121 +626,141 @@ class TbDateTest { Assert.assertEquals(567, d1.getUTCMilliseconds()); Assert.assertEquals(3, d1.getUTCDay()); } - - @Test + @Test void TestMethodSeFullYearMonthDate() { - TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-03:00"); - Assert.assertEquals(1976, d1.getFullYear()); - Assert.assertEquals(1, d1.getMonth()); - Assert.assertEquals(1, d1.getDate()); - Assert.assertEquals(4, d1.getUTCDay()); - d1.setFullYear(1969); - Assert.assertEquals(1969, d1.getFullYear()); - d1.setUTCFullYear(1975); - Assert.assertEquals(1975, d1.getFullYear()); - Assert.assertEquals(3, d1.getUTCDay()); - d1.setFullYear(1977, 4); - Assert.assertEquals(1977, d1.getFullYear()); - Assert.assertEquals(4, d1.getMonth()); - Assert.assertEquals(5, d1.getDay()); - d1.setFullYear(2023, 2, 24); - Assert.assertEquals(2023, d1.getFullYear()); - Assert.assertEquals(2, d1.getMonth()); - Assert.assertEquals(24, d1.getDate()); - Assert.assertEquals(5, d1.getDay()); - - d1.setMonth(11); - Assert.assertEquals(11, d1.getMonth()); - Assert.assertEquals(5, d1.getDay()); - d1.setMonth(2, 28); - Assert.assertEquals(2, d1.getMonth()); - Assert.assertEquals(28, d1.getDate()); - Assert.assertEquals(2, d1.getDay()); - - d1.setDate(11); - Assert.assertEquals(11, d1.getDate()); - Assert.assertEquals(6, d1.getDay()); - } - @Test + TbDate d = new TbDate(2024, 1, 1, 1, 15, 30, 567); + testResultChangeDateTime(d); + + d = new TbDate(2023, 12, 31, 22, 15, 30, 567); + testResultChangeDateTime(d); + + d = new TbDate(1975, 12, 31, 1, 15, 30, 567); + testResultChangeDateTime(d); + + d.setFullYear(1969); + testResultChangeDateTime(d); + + d.setFullYear(1975, 2); + testResultChangeDateTime(d); + + d.setFullYear(2023, 6, 30); + testResultChangeDateTime(d); + + d.setMonth(2); + testResultChangeDateTime(d); + + d.setMonth(1, 24); + testResultChangeDateTime(d); + + d.setDate(6); + testResultChangeDateTime(d); + } + @Test void TestMethodSeHoursMinutesSecondsMilliSec() { - TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-03:00"); - Assert.assertEquals(5, d1.getHours()); - Assert.assertEquals(4, d1.getDay()); + TbDate d1 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "+02:00"); + TbDate d2 = new TbDate(1975, 12, 31, 23, 15, 30, 567, "-02:00"); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); d1.setHours(5); - Assert.assertEquals(8, d1.getHours()); - Assert.assertEquals(4, d1.getDay()); + d2.setHours(23); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + d1.setHours(23, 45); - Assert.assertEquals(1, d1.getMonth()); - Assert.assertEquals(2, d1.getDate()); - Assert.assertEquals(2, d1.getHours()); - Assert.assertEquals(45, d1.getMinutes()); - Assert.assertEquals(5, d1.getDay()); - d1.setUTCHours(0, 12, 59); - Assert.assertEquals(3, d1.getHours()); - Assert.assertEquals(12, d1.getMinutes()); - Assert.assertEquals(59, d1.getSeconds()); - Assert.assertEquals(4, d1.getDay()); - d1.setUTCHours(4, 58, 2, 456); - Assert.assertEquals(7, d1.getHours()); - Assert.assertEquals(58, d1.getMinutes()); - Assert.assertEquals(2, d1.getSeconds()); - Assert.assertEquals(456, d1.getMilliseconds()); - Assert.assertEquals(4, d1.getDay()); + d2.setHours(1, 5); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setHours(0, 12, 59); + d2.setHours(4, 45, 1); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); + + d1.setHours(2, 32, 49, 123); + d2.setHours(8, 45, 12, 234); + testResultChangeDateTime(d1); + testResultChangeDateTime(d2); d1.setMinutes(5); + d2.setMinutes(15); Assert.assertEquals(5, d1.getMinutes()); - Assert.assertEquals(4, d1.getUTCDay()); - d1.setMinutes(15, 32); - Assert.assertEquals(15, d1.getMinutes()); - Assert.assertEquals(32, d1.getSeconds()); - Assert.assertEquals(4, d1.getDay()); - d1.setMinutes(10, 42, 321); - Assert.assertEquals(10, d1.getMinutes()); - Assert.assertEquals(42, d1.getSeconds()); - Assert.assertEquals(321, d1.getMilliseconds()); - Assert.assertEquals(4, d1.getDay()); + Assert.assertEquals(15, d2.getMinutes()); + + d1.setMinutes(5, 34); + d2.setMinutes(25, 43); + Assert.assertEquals(5, d1.getMinutes()); + Assert.assertEquals(34, d1.getSeconds()); + Assert.assertEquals(25, d2.getMinutes()); + Assert.assertEquals(43, d2.getSeconds()); + + d1.setMinutes(25, 14, 567); + d2.setMinutes(45, 3, 876); + Assert.assertEquals(25, d1.getMinutes()); + Assert.assertEquals(14, d1.getSeconds()); + Assert.assertEquals(567, d1.getMilliseconds()); + Assert.assertEquals(45, d2.getMinutes()); + Assert.assertEquals(3, d2.getSeconds()); + Assert.assertEquals(876, d2.getMilliseconds()); d1.setSeconds(5); + d2.setSeconds(23); Assert.assertEquals(5, d1.getSeconds()); - Assert.assertEquals(4, d1.getDay()); - d1.setSeconds(15, 32); - Assert.assertEquals(15, d1.getSeconds()); - Assert.assertEquals(32, d1.getMilliseconds()); - Assert.assertEquals(4, d1.getDay()); - - d1.setMilliseconds(5); - Assert.assertEquals(5, d1.getMilliseconds()); - Assert.assertEquals(4, d1.getDay()); + Assert.assertEquals(23, d2.getSeconds()); + + d1.setSeconds(45, 987); + d2.setSeconds(54, 842); + Assert.assertEquals(45, d1.getSeconds()); + Assert.assertEquals(987, d1.getMilliseconds()); + Assert.assertEquals(54, d2.getSeconds()); + Assert.assertEquals(842, d2.getMilliseconds()); + + d1.setMilliseconds(675); + d2.setMilliseconds(923); + Assert.assertEquals(675, d1.getMilliseconds()); + Assert.assertEquals(923, d2.getMilliseconds()); } @Test public void toStringAsJs() { - TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-14:00"); - Assert.assertEquals("1976 Jan 1, Thu 16:15:30 Eastern European Time", d1.toString()); - Assert.assertEquals("1976 Jan 1, Thu 16:15:30 Eastern European Time", d1.toString("GMT")); - Assert.assertEquals("1976 Jan 1, Thu 16:15:30 Eastern European Time", d1.toString("UTC")); - Assert.assertEquals("Thursday, January 1, 1976 at 4:15:30 PM Eastern European Standard Time", d1.toString("en-US")); - Assert.assertEquals("1976 Jan 1, Thu 16:15:30", d1.toUTCString()); - Assert.assertEquals("четвер, 1 січня 1976 р., 16:15:30", d1.toUTCString("uk-UA")); - Assert.assertEquals("Thursday, January 1, 1976, 4:15:30 PM", d1.toUTCString("en-US")); - Assert.assertEquals("четвер, 1 січня 1976 р., 16:15:30", d1.toUTCString("uk-UA")); - Assert.assertEquals("Thursday, January 1, 1976, 4:15:30 PM", d1.toUTCString("en-US")); - Assert.assertEquals("1976 Jan 1, Thu", d1.toDateString()); - Assert.assertEquals("четвер, 1 січня 1976 р.", d1.toDateString("uk-UA")); - Assert.assertEquals("Thursday, January 1, 1976", d1.toDateString("en-US")); - Assert.assertEquals("16:15:30 Eastern European Time", d1.toTimeString()); - Assert.assertEquals("16:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA")); - Assert.assertEquals("4:15:30 PM Eastern European Standard Time", d1.toTimeString("en-US")); - Assert.assertEquals("1976-01-01T13:15:30.567Z", d1.toJSON()); + TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 567,"-04:00"); + Assert.assertEquals("четвер, 1 січня 1976 р. о 06:15:30 за східноєвропейським стандартним часом", d1.toString("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("Thursday, January 1, 1976 at 6:15:30 AM Eastern European Standard Time", d1.toString("en-US", "Europe/Kyiv")); + Assert.assertEquals("1976 Jan 1, Thu 06:15:30 Eastern European Time", d1.toString("UTC", "Europe/Kyiv")); + Assert.assertEquals("Wednesday, December 31, 1975 at 10:15:30 PM Eastern Standard Time", d1.toString("en-US", "America/New_York")); + Assert.assertEquals("1975 Dec 31, Wed 22:15:30 Eastern Standard Time", d1.toString("GMT", "America/New_York")); + Assert.assertEquals("1975 Dec 31, Wed 22:15:30 Eastern Standard Time", d1.toString("UTC", "America/New_York")); + + Assert.assertEquals(d1.toUTCString("UTC"), d1.toUTCString()); + Assert.assertEquals("четвер, 1 січня 1976 р., 03:15:30", d1.toUTCString("uk-UA")); + Assert.assertEquals("Thursday, January 1, 1976, 3:15:30 AM", d1.toUTCString("en-US")); + + Assert.assertEquals("1976-01-01T03:15:30.567Z", d1.toJSON()); + Assert.assertEquals("1976-01-01T03:15:30.567Z", d1.toISOString()); + + Assert.assertEquals("1976-01-01 06:15:30", d1.toLocaleString("UTC", "Europe/Kyiv")); + Assert.assertEquals("01.01.76, 06:15:30", d1.toLocaleString("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("1975-12-31 22:15:30", d1.toLocaleString("UTC", "America/New_York")); + Assert.assertEquals("12/31/75, 10:15:30 PM", d1.toLocaleString("en-US", "America/New_York")); + + Assert.assertEquals("1976 Jan 1, Thu", d1.toDateString("UTC", "Europe/Kyiv")); + Assert.assertEquals("четвер, 1 січня 1976 р.", d1.toDateString("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("1975 Dec 31, Wed", d1.toDateString("UTC", "America/New_York")); + Assert.assertEquals("Wednesday, December 31, 1975", d1.toDateString("en-US", "America/New_York")); + + + Assert.assertEquals("06:15:30", d1.toLocaleTimeString("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("06:15:30", d1.toLocaleTimeString("UTC", "Europe/Kyiv")); + Assert.assertEquals("10:15:30 PM", d1.toLocaleTimeString("en-US", "America/New_York")); + Assert.assertEquals("22:15:30", d1.toLocaleTimeString("UTC", "America/New_York")); + + Assert.assertEquals("06:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("06:15:30 Eastern European Time", d1.toTimeString("UTC", "Europe/Kyiv")); + Assert.assertEquals("10:15:30 PM Eastern Standard Time", d1.toTimeString("en-US", "America/New_York")); + Assert.assertEquals("22:15:30 Eastern Standard Time", d1.toTimeString("UTC", "America/New_York")); + + } - /** - * Date.UTC(0) - * -2208988800000 - * > "Mon, 01 Jan 1900 00:00:00 GMT" - * new Date(Date.UTC(0, 0, 0, 0, 0, 0)); - * "Sun, 31 Dec 1899 00:00:00 GMT" - */ @Test public void toUTC() { Assert.assertEquals(-2209075200000L, TbDate.UTC(0)); @@ -658,11 +771,23 @@ class TbDateTest { Assert.assertEquals("1958-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(1958, 0, 0, 3, 4, 5, 678)).toJSON()); Assert.assertEquals("2032-04-05T03:04:05.678Z", new TbDate(TbDate.UTC(2032, 4, 5, 3, 4, 5, 678)).toJSON()); Assert.assertEquals("2024-02-29T03:04:05.678Z", new TbDate(TbDate.UTC(2024, 2, 29, 3, 4, 5, 678)).toJSON()); - Exception actual = assertThrows(DateTimeParseException.class, () -> { + Exception actual = assertThrows(DateTimeException.class, () -> { TbDate.UTC(2023, 2, 29, 3, 4, 5, 678); }); - String expectedMessage = "could not be parsed"; + String expectedMessage = "Invalid date 'February 29' as '2023' is not a leap year"; assertTrue(actual.getMessage().contains(expectedMessage)); } + + private void testResultChangeDateTime(TbDate d) { + int localOffset = ZoneId.systemDefault().getRules().getOffset(d.getInstant()).getTotalSeconds(); + TbDateTestEntity tbDateTestEntity = new TbDateTestEntity(d.getFullYear(), d.getMonth(), d.getDate(), (d.getHours() - (localOffset/60/60))); + Assert.assertEquals(tbDateTestEntity.getYear(), d.getUTCFullYear()); + Assert.assertEquals(tbDateTestEntity.getMonth(), d.getUTCMonth()); + Assert.assertEquals(tbDateTestEntity.getDate(), d.getUTCDate()); + Assert.assertEquals(tbDateTestEntity.getHours(), d.getUTCHours()); + Assert.assertEquals(d.getMinutes(), d.getUTCMinutes()); + Assert.assertEquals(d.getSeconds(), d.getUTCSeconds()); + Assert.assertEquals(d.getMilliseconds(), d.getUTCMilliseconds()); + } } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTestEntity.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTestEntity.java new file mode 100644 index 0000000000..771eba896b --- /dev/null +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTestEntity.java @@ -0,0 +1,90 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.script.api.tbel; + +import lombok.Data; +import java.time.chrono.IsoChronology; +@Data +public class TbDateTestEntity { + private int year; + private int month; + private int date; + private int hours; + public TbDateTestEntity(int year, int month, int date, int hours) { + this.year = year; + this.month = month; + this.date = date; + this.hours = hours; + if (hours > 23) { + if (date == 31) { + this.year++; + this.month = 1; + this.date = 1; + } else { + this.date++; + } + this.hours = hours - 24; + } else if (hours < 0) { + if (month== 1 && date == 1) { + this.year--; + this.month = 12; + this.date = 31; + } else { + this.date--; + } + this.hours = hours + 24; + } + + if (this.date > 28) { + int dom = 31; + switch (month) { + case 2: + dom = IsoChronology.INSTANCE.isLeapYear((long) year) ? 29 : 28; + case 3: + case 5: + case 7: + case 8: + case 10: + default: + break; + case 4: + case 6: + case 9: + case 11: + dom = 30; + } + if (this.date > dom) { + this.date = this.date - dom; + this.month++; + } + } + } + public int getYear(){ + return year < 70 ? 2000 + year : year <= 99 ? 1900 + year : year; + } + + public String geMonthStr(){ + return String.format("%02d", month); + } + + public String geDateStr(){ + return String.format("%02d", date); + } + + public String geHoursStr(){ + return String.format("%02d", hours); + } +} From 69bcd8426e35d85f4cdb1b2b5c19e0698563182a Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 17 Oct 2023 18:42:28 +0300 Subject: [PATCH 32/61] tbDate: Tests were checked with: * -timezone Etc/GMT-14 * -timezone Etc/GMT+12 * -timezone America/New_York * -timezone Europe/Kyiv --- .../script/api/tbel/TbDateTest.java | 86 +++++++++---------- 1 file changed, 42 insertions(+), 44 deletions(-) diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index f020d3e092..af9ff4c5e1 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -71,6 +71,11 @@ class TbDateTest { * at java.base/java.util.Calendar.setTimeInMillis(Calendar.java:1834) * at java.base/java.util.Calendar.setTime(Calendar.java:1800) * at java.base/java.text.SimpleDateFormat.format(SimpleDateFormat.java:974) + * Tests were checked with: + * -timezone Etc/GMT-14 + * -timezone Etc/GMT+12 + * -timezone America/New_York + * -timezone Europe/Kyiv */ @Test void testToISOStringConcurrently() throws ExecutionException, InterruptedException, TimeoutException { @@ -455,24 +460,25 @@ class TbDateTest { Assert.assertEquals("2023-09-07 08:04:05", d.toLocaleString()); } - /** - * Tests for: - * min TZ = "Etc/GMT+12" = '-12' - * max TZ = "Etc/GMT-14" = '+14' - */ @Test void Test_Get_LocalDateTime_With_TZ() { int hrs = 8; int date = 7; int tz = 0; String pattern = "2023-09-%s %s:04:05"; - String tzStr = "+00:00"; - TbDate d = new TbDate(23, 9, date, hrs, 4, 5, tzStr); - int localOffsetHrs = ZoneId.systemDefault().getRules().getOffset(d.getInstant()).getTotalSeconds()/60/60; + String tzStr = "UTC"; + TbDate d = new TbDate(23, 9, date, hrs, 4, 5); + int localOffsetHrs = 0; TbDateTestEntity tbDateTest = new TbDateTestEntity(23, 9, date, hrs + localOffsetHrs - tz); String expected = String.format(pattern, tbDateTest.geDateStr(), tbDateTest.geHoursStr()); Assert.assertEquals(expected, d.toLocaleString()); + d = new TbDate(23, 9, date, hrs, 4, 5, tzStr); + localOffsetHrs = ZoneId.systemDefault().getRules().getOffset(d.getInstant()).getTotalSeconds()/60/60; + tbDateTest = new TbDateTestEntity(23, 9, date, hrs + localOffsetHrs - tz); + expected = String.format(pattern, tbDateTest.geDateStr(), tbDateTest.geHoursStr()); + Assert.assertEquals(expected, d.toLocaleString()); + tz = 3; tzStr = "+03:00"; d = new TbDate(23, 9, date, hrs, 4, 5, tzStr); @@ -490,24 +496,36 @@ class TbDateTest { Assert.assertEquals(expected, d.toLocaleString()); } + @Test + public void TestToUTC() { + Assert.assertEquals(-2209075200000L, TbDate.UTC(0)); + Assert.assertEquals("1899-12-31T00:00:00Z", new TbDate(TbDate.UTC(0)).toJSON()); + Assert.assertEquals("1996-02-02T03:04:05Z", new TbDate(TbDate.UTC(96, 2, 2, 3, 4, 5)).toJSON()); + Assert.assertEquals("2022-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(22, 0, 0, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("0903-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(903, 0, 0, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("1958-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(1958, 0, 0, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("2032-04-05T03:04:05.678Z", new TbDate(TbDate.UTC(2032, 4, 5, 3, 4, 5, 678)).toJSON()); + Assert.assertEquals("2024-02-29T03:04:05.678Z", new TbDate(TbDate.UTC(2024, 2, 29, 3, 4, 5, 678)).toJSON()); + Exception actual = assertThrows(DateTimeException.class, () -> { + TbDate.UTC(2023, 2, 29, 3, 4, 5, 678); + }); + String expectedMessage = "Invalid date 'February 29' as '2023' is not a leap year"; + assertTrue(actual.getMessage().contains(expectedMessage)); + } + @Test void TestMethodGetTimeUTC() { - TbDate dd = new TbDate(TbDate.UTC(1996, 1, 2, 3, 4, 5)); - Assert.assertEquals(820551845000L, dd.valueOf()); - dd = new TbDate(1996, 1, 2, 3, 4, 5); - Assert.assertEquals(820544645000L, dd.valueOf()); + TbDate ddUTC = new TbDate(TbDate.UTC(1996, 1, 2, 3, 4, 5)); + Assert.assertEquals(820551845000L, ddUTC.valueOf()); + TbDate dd = new TbDate(1996, 1, 2, 3, 4, 5); + int localOffsetMilli = ZoneId.systemDefault().getRules().getOffset(dd.getInstant()).getTotalSeconds()*1000; + Assert.assertEquals((dd.valueOf() + localOffsetMilli), ddUTC.valueOf()); + + ddUTC = new TbDate(TbDate.UTC(1969, 7, 20, 20, 17, 40)); + Assert.assertEquals(-14182940000L, ddUTC.valueOf()); TbDate beforeStartUTC = new TbDate(1969, 7, 20, 20, 17, 40); - Assert.assertEquals(-14193740000L, beforeStartUTC.getTime()); - - TbDate d = new TbDate(1975, 12, 31, 23,15,30, 560); - TbDate d0 = new TbDate(1975, 12, 31, 23,15,30, 560,"UTC"); - TbDate d1 = new TbDate(1975, 12, 31, 23,15,30, 561,"+03:00"); - TbDate d2 = new TbDate(1975, 12, 31, 23,15,30, 562,"-04:00"); - - Assert.assertEquals(189288930560L, d.valueOf()); - Assert.assertEquals(189299730560L, d0.valueOf()); - Assert.assertEquals(189288930561L, d1.valueOf()); - Assert.assertEquals(189314130562L, d2.getTime()); + localOffsetMilli = ZoneId.systemDefault().getRules().getOffset(beforeStartUTC.getInstant()).getTotalSeconds()*1000; + Assert.assertEquals((beforeStartUTC.valueOf() + localOffsetMilli), ddUTC.valueOf()); } @Test @@ -747,35 +765,15 @@ class TbDateTest { Assert.assertEquals("1975 Dec 31, Wed", d1.toDateString("UTC", "America/New_York")); Assert.assertEquals("Wednesday, December 31, 1975", d1.toDateString("en-US", "America/New_York")); - Assert.assertEquals("06:15:30", d1.toLocaleTimeString("uk-UA", "Europe/Kyiv")); Assert.assertEquals("06:15:30", d1.toLocaleTimeString("UTC", "Europe/Kyiv")); Assert.assertEquals("10:15:30 PM", d1.toLocaleTimeString("en-US", "America/New_York")); Assert.assertEquals("22:15:30", d1.toLocaleTimeString("UTC", "America/New_York")); - Assert.assertEquals("06:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("06:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA", "Europe/Kyiv")); Assert.assertEquals("06:15:30 Eastern European Time", d1.toTimeString("UTC", "Europe/Kyiv")); Assert.assertEquals("10:15:30 PM Eastern Standard Time", d1.toTimeString("en-US", "America/New_York")); Assert.assertEquals("22:15:30 Eastern Standard Time", d1.toTimeString("UTC", "America/New_York")); - - - } - - @Test - public void toUTC() { - Assert.assertEquals(-2209075200000L, TbDate.UTC(0)); - Assert.assertEquals("1899-12-31T00:00:00Z", new TbDate(TbDate.UTC(0)).toJSON()); - Assert.assertEquals("1996-02-02T03:04:05Z", new TbDate(TbDate.UTC(96, 2, 2, 3, 4, 5)).toJSON()); - Assert.assertEquals("2022-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(22, 0, 0, 3, 4, 5, 678)).toJSON()); - Assert.assertEquals("0903-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(903, 0, 0, 3, 4, 5, 678)).toJSON()); - Assert.assertEquals("1958-12-31T03:04:05.678Z", new TbDate(TbDate.UTC(1958, 0, 0, 3, 4, 5, 678)).toJSON()); - Assert.assertEquals("2032-04-05T03:04:05.678Z", new TbDate(TbDate.UTC(2032, 4, 5, 3, 4, 5, 678)).toJSON()); - Assert.assertEquals("2024-02-29T03:04:05.678Z", new TbDate(TbDate.UTC(2024, 2, 29, 3, 4, 5, 678)).toJSON()); - Exception actual = assertThrows(DateTimeException.class, () -> { - TbDate.UTC(2023, 2, 29, 3, 4, 5, 678); - }); - String expectedMessage = "Invalid date 'February 29' as '2023' is not a leap year"; - assertTrue(actual.getMessage().contains(expectedMessage)); } private void testResultChangeDateTime(TbDate d) { From 76ff8f4d93ecf90b2f0017fb0bf2463d1aa47eee Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Tue, 24 Oct 2023 13:56:15 +0200 Subject: [PATCH 33/61] docker FROM thingsboard/openjdk17:bookworm-slim --- msa/monitoring/docker/Dockerfile | 2 +- msa/tb-node/docker/Dockerfile | 2 +- msa/tb/docker-cassandra/Dockerfile | 2 +- msa/tb/docker-postgres/Dockerfile | 2 +- msa/transport/coap/docker/Dockerfile | 2 +- msa/transport/http/docker/Dockerfile | 2 +- msa/transport/lwm2m/docker/Dockerfile | 2 +- msa/transport/mqtt/docker/Dockerfile | 2 +- msa/transport/snmp/docker/Dockerfile | 2 +- msa/vc-executor-docker/docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/msa/monitoring/docker/Dockerfile b/msa/monitoring/docker/Dockerfile index 14c6246280..ce27eb175b 100644 --- a/msa/monitoring/docker/Dockerfile +++ b/msa/monitoring/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-monitoring.sh ${pkg.name}.deb /tmp/ diff --git a/msa/tb-node/docker/Dockerfile b/msa/tb-node/docker/Dockerfile index 2c8af18f9a..8dcba61255 100644 --- a/msa/tb-node/docker/Dockerfile +++ b/msa/tb-node/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-node.sh ${pkg.name}.deb /tmp/ diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile index f871d57ff8..0db1f47331 100644 --- a/msa/tb/docker-cassandra/Dockerfile +++ b/msa/tb/docker-cassandra/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim ENV PG_MAJOR=12 diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile index 2520bee62b..be9cc2799b 100644 --- a/msa/tb/docker-postgres/Dockerfile +++ b/msa/tb/docker-postgres/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim ENV PG_MAJOR 12 diff --git a/msa/transport/coap/docker/Dockerfile b/msa/transport/coap/docker/Dockerfile index 526a8620a8..9ed00eeaf8 100644 --- a/msa/transport/coap/docker/Dockerfile +++ b/msa/transport/coap/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-coap-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/http/docker/Dockerfile b/msa/transport/http/docker/Dockerfile index 399df84000..17e1ed3dbb 100644 --- a/msa/transport/http/docker/Dockerfile +++ b/msa/transport/http/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-http-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/lwm2m/docker/Dockerfile b/msa/transport/lwm2m/docker/Dockerfile index d17f368c8f..2d41c9a0fe 100644 --- a/msa/transport/lwm2m/docker/Dockerfile +++ b/msa/transport/lwm2m/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-lwm2m-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/mqtt/docker/Dockerfile b/msa/transport/mqtt/docker/Dockerfile index 769164b86e..de89c64a58 100644 --- a/msa/transport/mqtt/docker/Dockerfile +++ b/msa/transport/mqtt/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-mqtt-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/snmp/docker/Dockerfile b/msa/transport/snmp/docker/Dockerfile index 2835c56bc7..755a17f495 100644 --- a/msa/transport/snmp/docker/Dockerfile +++ b/msa/transport/snmp/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-snmp-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/vc-executor-docker/docker/Dockerfile b/msa/vc-executor-docker/docker/Dockerfile index 70a3d3e18f..68f9d938f9 100644 --- a/msa/vc-executor-docker/docker/Dockerfile +++ b/msa/vc-executor-docker/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk17:bullseye-slim +FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-vc-executor.sh ${pkg.name}.deb /tmp/ From f4a4782d83593821d3cb67b47a76c5599b3312f3 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Tue, 24 Oct 2023 13:57:22 +0200 Subject: [PATCH 34/61] docker: removed as it exists in base image: echo 'networkaddress.cache.ttl=60' >> /etc/java-17-openjdk/security/java.security --- msa/tb-node/docker/Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/msa/tb-node/docker/Dockerfile b/msa/tb-node/docker/Dockerfile index 8dcba61255..506d41f8ec 100644 --- a/msa/tb-node/docker/Dockerfile +++ b/msa/tb-node/docker/Dockerfile @@ -18,8 +18,7 @@ FROM thingsboard/openjdk17:bookworm-slim COPY start-tb-node.sh ${pkg.name}.deb /tmp/ -RUN echo 'networkaddress.cache.ttl=60' >> /etc/java-17-openjdk/security/java.security \ - && chmod a+x /tmp/*.sh \ +RUN chmod a+x /tmp/*.sh \ && mv /tmp/start-tb-node.sh /usr/bin && \ (yes | dpkg -i /tmp/${pkg.name}.deb) && \ rm /tmp/${pkg.name}.deb && \ From 939d672b07f158e3a3620500753c1dc8233ec497 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Tue, 24 Oct 2023 14:01:22 +0200 Subject: [PATCH 35/61] docker: bump minor version FROM thingsboard/node:16.20.2-bookworm-slim (previous was 16.17.0-bullseye-slim) --- msa/js-executor/docker/Dockerfile | 2 +- msa/web-ui/docker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msa/js-executor/docker/Dockerfile b/msa/js-executor/docker/Dockerfile index f934628a96..ef22343442 100644 --- a/msa/js-executor/docker/Dockerfile +++ b/msa/js-executor/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/node:16.17.0-bullseye-slim +FROM thingsboard/node:16.20.2-bookworm-slim ENV NODE_ENV production ENV DOCKER_MODE true diff --git a/msa/web-ui/docker/Dockerfile b/msa/web-ui/docker/Dockerfile index cf5df5ee2c..18a19e0ead 100644 --- a/msa/web-ui/docker/Dockerfile +++ b/msa/web-ui/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/node:16.17.0-bullseye-slim +FROM thingsboard/node:16.20.2-bookworm-slim ENV NODE_ENV production ENV DOCKER_MODE true From e5eff1f8c7f12fd9113cad8d16f06c18431a1e4d Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Tue, 24 Oct 2023 14:05:58 +0200 Subject: [PATCH 36/61] docker: bump minor version thingsboard/haproxy-certbot:2.2.31-alpine3.18 --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 78ca337e0a..942be3782a 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -300,7 +300,7 @@ services: haproxy: restart: always container_name: "${LOAD_BALANCER_NAME}" - image: thingsboard/haproxy-certbot:1.3.0 + image: thingsboard/haproxy-certbot:2.2.31-alpine3.18 volumes: - ./haproxy/config:/config - ./haproxy/letsencrypt:/etc/letsencrypt From dfb1200e958c9d1e575db737604d510184549a9f Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 24 Oct 2023 16:11:00 +0300 Subject: [PATCH 37/61] tbDate: comments2 --- .../thingsboard/script/api/tbel/TbDate.java | 37 ++++++++++--------- .../script/api/tbel/TbDateTest.java | 33 ++++++++--------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 146de4570f..591084f986 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -46,6 +46,9 @@ public class TbDate implements Serializable, Cloneable { private static final ZoneId zoneIdUTC = ZoneId.of("UTC"); private static final Locale localeUTC = Locale.forLanguageTag("UTC"); + private static final DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( + "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); + public TbDate() { this.instant = Instant.now(); } @@ -108,8 +111,8 @@ public class TbDate implements Serializable, Cloneable { public String toDateString(String locale) { return toDateString(locale, ZoneId.systemDefault().toString()); } - public String toDateString(String locale, String zoneStr) { - return toLocaleDateString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeZone", zoneStr).toString()); + public String toDateString(String localeStr, String zoneStr) { + return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(locale)); } public String toTimeString() { return toTimeString(Locale.getDefault().getLanguage()); @@ -117,8 +120,8 @@ public class TbDate implements Serializable, Cloneable { public String toTimeString(String locale) { return toTimeString(locale, ZoneId.systemDefault().toString()); } - public String toTimeString(String locale, String zoneStr) { - return toLocaleTbTimeString(locale, JacksonUtil.newObjectNode().put("timeStyle", FormatStyle.FULL.name()).put("timeZone", zoneStr).toString()); + public String toTimeString(String localeStr, String zoneStr) { + return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).withLocale(locale)); } public String toISOString() { @@ -131,8 +134,8 @@ public class TbDate implements Serializable, Cloneable { return toUTCString(localeUTC.getLanguage()); } - public String toUTCString(String locale) { - return toLocaleTbString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeStyle", FormatStyle.MEDIUM.name()).put("timeZone", zoneIdUTC.getId()).toString()); + public String toUTCString(String localeStr) { + return toLocaleTbString(localeStr, zoneIdUTC.getId(), (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).withLocale(locale)); } public String toString() { @@ -143,8 +146,8 @@ public class TbDate implements Serializable, Cloneable { return toString(locale, ZoneId.systemDefault().toString()); } - public String toString(String locale, String zoneStr) { - return toLocaleTbString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeStyle", FormatStyle.FULL.name()).put("timeZone", zoneStr).toString()); + public String toString(String localeStr, String zoneStr) { + return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL).withLocale(locale)); } public String toISOZonedDateTimeString() { return getZonedDateTime().toString(); @@ -157,8 +160,8 @@ public class TbDate implements Serializable, Cloneable { return toLocaleDateString(localeUTC.getLanguage()); } - public String toLocaleDateString(String locale) { - return toLocaleDateString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.FULL.name()).put("timeZone", ZoneId.systemDefault().toString()).toString()); + public String toLocaleDateString(String localeStr) { + return toLocaleTbString(localeStr, ZoneId.systemDefault().toString(), (locale, options) -> DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(locale)); } public String toLocaleDateString(String localeStr, String optionsStr) { @@ -170,14 +173,14 @@ public class TbDate implements Serializable, Cloneable { } public String toLocaleTimeString(String localeStr) { - return toLocaleTimeString(localeStr, ZoneId.systemDefault().toString()); + return toLocaleTimeStringWithZoneId(localeStr, ZoneId.systemDefault().toString()); } - public String toLocaleTimeString(String localeStr, String zoneStr) { - return toLocaleTbTimeString(localeStr, JacksonUtil.newObjectNode().put("timeStyle", FormatStyle.MEDIUM.name()).put("timeZone", zoneStr).toString()); + public String toLocaleTimeStringWithZoneId(String localeStr, String zoneStr) { + return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); } - public String toLocaleTbTimeString(String localeStr, String optionsStr) { + public String toLocaleTimeString(String localeStr, String optionsStr) { return toLocaleTbString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); } @@ -189,8 +192,8 @@ public class TbDate implements Serializable, Cloneable { return toLocaleString(locale, ZoneId.systemDefault().toString()); } - public String toLocaleString(String locale, String zoneStr) { - return toLocaleTbString(locale, JacksonUtil.newObjectNode().put("dateStyle", FormatStyle.SHORT.name()).put("timeStyle", FormatStyle.MEDIUM.name()).put("timeZone", zoneStr).toString()); + public String toLocaleString(String localeStr, String zoneStr) { + return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(options.getDateStyle(), options.getTimeStyle()).withLocale(locale)); } public String toLocaleTbString(String localeStr, String optionsStr) { @@ -489,8 +492,6 @@ public class TbDate implements Serializable, Cloneable { } } public static long parse(String value) { - DateTimeFormatter isoDateFormatter = DateTimeFormatter.ofPattern( - "yyyy-MM-dd[[ ]['T']HH:mm[:ss[.SSS]][ ][XXX][Z][z][VV][O]]").withZone(ZoneId.systemDefault()); try { TemporalAccessor accessor = isoDateFormatter.parseBest(value, ZonedDateTime::from, diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index af9ff4c5e1..cf74ff3cb2 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -223,41 +223,41 @@ class TbDateTest { Assert.assertNotNull(d.toLocaleTimeString()); Assert.assertNotNull(d.toLocaleTimeString("en-US")); - Assert.assertEquals("9:04:05 PM", d.toLocaleTbTimeString("en-US", "America/New_York")); - Assert.assertEquals("오후 9:04:05", d.toLocaleTbTimeString("ko-KR", "America/New_York")); - Assert.assertEquals("04:04:05", d.toLocaleTbTimeString( "uk-UA", "Europe/Kiev")); - Assert.assertEquals("9:04:05 م", d.toLocaleTbTimeString( "ar-EG", "America/New_York")); + Assert.assertEquals("9:04:05 PM", d.toLocaleTimeString("en-US", "America/New_York")); + Assert.assertEquals("오후 9:04:05", d.toLocaleTimeString("ko-KR", "America/New_York")); + Assert.assertEquals("04:04:05", d.toLocaleTimeString( "uk-UA", "Europe/Kiev")); + Assert.assertEquals("9:04:05 م", d.toLocaleTimeString( "ar-EG", "America/New_York")); - Assert.assertEquals("9:04:05 PM Eastern Daylight Time", d.toLocaleTbTimeString("en-US", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 PM Eastern Daylight Time", d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") .toString())); - Assert.assertEquals("오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleTbTimeString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleTimeString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") .toString())); - Assert.assertEquals("04:04:05 за східноєвропейським літнім часом", d.toLocaleTbTimeString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("04:04:05 за східноєвропейським літнім часом", d.toLocaleTimeString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("timeStyle", "full") .toString())); - Assert.assertEquals("9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleTbTimeString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleTimeString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("timeStyle", "full") .toString())); - Assert.assertEquals("9:04:05 PM", d.toLocaleTbTimeString("en-US", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 PM", d.toLocaleTimeString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") .toString())); - Assert.assertEquals("9:04:05 오후", d.toLocaleTbTimeString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 오후", d.toLocaleTimeString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") .toString())); - Assert.assertEquals("4:04:05 дп", d.toLocaleTbTimeString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("4:04:05 дп", d.toLocaleTimeString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("pattern", "h:mm:ss a") .toString())); - Assert.assertEquals("9:04:05 م", d.toLocaleTbTimeString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("9:04:05 م", d.toLocaleTimeString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "h:mm:ss a") .toString())); @@ -765,10 +765,10 @@ class TbDateTest { Assert.assertEquals("1975 Dec 31, Wed", d1.toDateString("UTC", "America/New_York")); Assert.assertEquals("Wednesday, December 31, 1975", d1.toDateString("en-US", "America/New_York")); - Assert.assertEquals("06:15:30", d1.toLocaleTimeString("uk-UA", "Europe/Kyiv")); - Assert.assertEquals("06:15:30", d1.toLocaleTimeString("UTC", "Europe/Kyiv")); - Assert.assertEquals("10:15:30 PM", d1.toLocaleTimeString("en-US", "America/New_York")); - Assert.assertEquals("22:15:30", d1.toLocaleTimeString("UTC", "America/New_York")); + Assert.assertEquals("06:15:30", d1.toLocaleTimeStringWithZoneId("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("06:15:30", d1.toLocaleTimeStringWithZoneId("UTC", "Europe/Kyiv")); + Assert.assertEquals("10:15:30 PM", d1.toLocaleTimeStringWithZoneId("en-US", "America/New_York")); + Assert.assertEquals("22:15:30", d1.toLocaleTimeStringWithZoneId("UTC", "America/New_York")); Assert.assertEquals("06:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA", "Europe/Kyiv")); Assert.assertEquals("06:15:30 Eastern European Time", d1.toTimeString("UTC", "Europe/Kyiv")); @@ -788,4 +788,3 @@ class TbDateTest { Assert.assertEquals(d.getMilliseconds(), d.getUTCMilliseconds()); } } - From 2046c4863f5c2ebf9a2927856d3889a034c2f510 Mon Sep 17 00:00:00 2001 From: nick Date: Tue, 24 Oct 2023 16:48:08 +0300 Subject: [PATCH 38/61] tbDate: comments3 --- .../thingsboard/script/api/tbel/TbDate.java | 42 +++++++++---------- .../script/api/tbel/TbDateTest.java | 8 ++-- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 591084f986..0e406cf6dd 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -111,8 +111,8 @@ public class TbDate implements Serializable, Cloneable { public String toDateString(String locale) { return toDateString(locale, ZoneId.systemDefault().toString()); } - public String toDateString(String localeStr, String zoneStr) { - return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(locale)); + public String toDateString(String localeStr, String optionsStr) { + return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(locale)); } public String toTimeString() { return toTimeString(Locale.getDefault().getLanguage()); @@ -120,8 +120,8 @@ public class TbDate implements Serializable, Cloneable { public String toTimeString(String locale) { return toTimeString(locale, ZoneId.systemDefault().toString()); } - public String toTimeString(String localeStr, String zoneStr) { - return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).withLocale(locale)); + public String toTimeString(String localeStr, String optionsStr) { + return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).withLocale(locale)); } public String toISOString() { @@ -135,7 +135,7 @@ public class TbDate implements Serializable, Cloneable { } public String toUTCString(String localeStr) { - return toLocaleTbString(localeStr, zoneIdUTC.getId(), (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).withLocale(locale)); + return toLocaleString(localeStr, zoneIdUTC.getId(), (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM).withLocale(locale)); } public String toString() { @@ -146,8 +146,8 @@ public class TbDate implements Serializable, Cloneable { return toString(locale, ZoneId.systemDefault().toString()); } - public String toString(String localeStr, String zoneStr) { - return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL).withLocale(locale)); + public String toString(String localeStr, String optionsStr) { + return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL).withLocale(locale)); } public String toISOZonedDateTimeString() { return getZonedDateTime().toString(); @@ -161,11 +161,11 @@ public class TbDate implements Serializable, Cloneable { } public String toLocaleDateString(String localeStr) { - return toLocaleTbString(localeStr, ZoneId.systemDefault().toString(), (locale, options) -> DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(locale)); + return toLocaleString(localeStr, ZoneId.systemDefault().toString(), (locale, options) -> DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(locale)); } public String toLocaleDateString(String localeStr, String optionsStr) { - return toLocaleTbString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDate(options.getDateStyle()).withLocale(locale)); + return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDate(options.getDateStyle()).withLocale(locale)); } public String toLocaleTimeString() { @@ -173,15 +173,11 @@ public class TbDate implements Serializable, Cloneable { } public String toLocaleTimeString(String localeStr) { - return toLocaleTimeStringWithZoneId(localeStr, ZoneId.systemDefault().toString()); - } - - public String toLocaleTimeStringWithZoneId(String localeStr, String zoneStr) { - return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); + return toLocaleTimeString(localeStr, ZoneId.systemDefault().toString()); } public String toLocaleTimeString(String localeStr, String optionsStr) { - return toLocaleTbString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); + return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedTime(options.getTimeStyle()).withLocale(locale)); } public String toLocaleString() { @@ -192,12 +188,12 @@ public class TbDate implements Serializable, Cloneable { return toLocaleString(locale, ZoneId.systemDefault().toString()); } - public String toLocaleString(String localeStr, String zoneStr) { - return toLocaleTbString(localeStr, zoneStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(options.getDateStyle(), options.getTimeStyle()).withLocale(locale)); + public String toLocaleString(String localeStr, String optionsStr) { + return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(options.getDateStyle(), options.getTimeStyle()).withLocale(locale)); } public String toLocaleTbString(String localeStr, String optionsStr) { - return toLocaleTbString(localeStr, optionsStr, (locale, options) -> { + return toLocaleString(localeStr, optionsStr, (locale, options) -> { String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern( options.getDateStyle(), @@ -208,7 +204,7 @@ public class TbDate implements Serializable, Cloneable { }); } - public String toLocaleTbString(String localeStr, String optionsStr, BiFunction formatterBuilder) { + public String toLocaleString(String localeStr, String optionsStr, BiFunction formatterBuilder) { Locale locale = StringUtils.isNotEmpty(localeStr) ? Locale.forLanguageTag(localeStr) : Locale.getDefault(); DateTimeFormatOptions options = getDateFormattingOptions(optionsStr); ZonedDateTime zdt = this.getInstant().atZone(options.getTimeZone().toZoneId()); @@ -221,13 +217,13 @@ public class TbDate implements Serializable, Cloneable { return formatter.format(zdt); } - private DateTimeFormatOptions getDateFormattingOptions(String options) { + private DateTimeFormatOptions getDateFormattingOptions(String optionsStr) { DateTimeFormatOptions opt = null; - if (StringUtils.isNotEmpty(options)) { + if (StringUtils.isNotEmpty(optionsStr)) { try { - opt = JacksonUtil.fromString(options, DateTimeFormatOptions.class); + opt = JacksonUtil.fromString(optionsStr, DateTimeFormatOptions.class); } catch (IllegalArgumentException iae) { - opt = new DateTimeFormatOptions(options); + opt = new DateTimeFormatOptions(optionsStr); } } if (opt == null) { diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index cf74ff3cb2..e6c9b3b140 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -765,10 +765,10 @@ class TbDateTest { Assert.assertEquals("1975 Dec 31, Wed", d1.toDateString("UTC", "America/New_York")); Assert.assertEquals("Wednesday, December 31, 1975", d1.toDateString("en-US", "America/New_York")); - Assert.assertEquals("06:15:30", d1.toLocaleTimeStringWithZoneId("uk-UA", "Europe/Kyiv")); - Assert.assertEquals("06:15:30", d1.toLocaleTimeStringWithZoneId("UTC", "Europe/Kyiv")); - Assert.assertEquals("10:15:30 PM", d1.toLocaleTimeStringWithZoneId("en-US", "America/New_York")); - Assert.assertEquals("22:15:30", d1.toLocaleTimeStringWithZoneId("UTC", "America/New_York")); + Assert.assertEquals("06:15:30", d1.toLocaleTimeString("uk-UA", "Europe/Kyiv")); + Assert.assertEquals("06:15:30", d1.toLocaleTimeString("UTC", "Europe/Kyiv")); + Assert.assertEquals("10:15:30 PM", d1.toLocaleTimeString("en-US", "America/New_York")); + Assert.assertEquals("22:15:30", d1.toLocaleTimeString("UTC", "America/New_York")); Assert.assertEquals("06:15:30 за східноєвропейським стандартним часом", d1.toTimeString("uk-UA", "Europe/Kyiv")); Assert.assertEquals("06:15:30 Eastern European Time", d1.toTimeString("UTC", "Europe/Kyiv")); From b1ebb9f27973dd374d2e8e72aaa3342633cfa6ea Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Tue, 24 Oct 2023 16:21:12 +0200 Subject: [PATCH 39/61] msa v16.20.2 --- msa/js-executor/pom.xml | 2 +- msa/web-ui/pom.xml | 2 +- ui-ngx/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index 128479e5eb..1cf55d9795 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -71,7 +71,7 @@ install-node-and-yarn - v16.15.1 + v16.20.2 v1.22.17 diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index cbee67c12e..02772a68e3 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -80,7 +80,7 @@ install-node-and-yarn - v16.15.1 + v16.20.2 v1.22.17 diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index 84b5f8b98c..2c09d29af2 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -56,7 +56,7 @@ install-node-and-yarn - v16.15.1 + v16.20.2 v1.22.17 From 5a0b942b7547888de0d465d53df26b6373d24235 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Wed, 25 Oct 2023 15:57:42 +0300 Subject: [PATCH 40/61] Fix backward compatibility --- .../thingsboard/script/api/tbel/TbDate.java | 15 ++--------- .../script/api/tbel/TbDateTest.java | 25 ++++++++++--------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 0e406cf6dd..34c4669f1e 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -189,19 +189,8 @@ public class TbDate implements Serializable, Cloneable { } public String toLocaleString(String localeStr, String optionsStr) { - return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(options.getDateStyle(), options.getTimeStyle()).withLocale(locale)); - } - - public String toLocaleTbString(String localeStr, String optionsStr) { - return toLocaleString(localeStr, optionsStr, (locale, options) -> { - String formatPattern = - DateTimeFormatterBuilder.getLocalizedDateTimePattern( - options.getDateStyle(), - options.getTimeStyle(), - IsoChronology.INSTANCE, - locale); - return DateTimeFormatter.ofPattern(formatPattern, locale); - }); + return toLocaleString(localeStr, optionsStr, (locale, options) -> + DateTimeFormatter.ofLocalizedDateTime(options.getDateStyle(), options.getTimeStyle()).withLocale(locale)); } public String toLocaleString(String localeStr, String optionsStr, BiFunction formatterBuilder) { diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index e6c9b3b140..7f09219df9 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -271,45 +271,46 @@ class TbDateTest { Assert.assertNotNull(d.toLocaleString()); Assert.assertNotNull(d.toLocaleString("en-US")); - Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleTbString("en-US", "America/New_York")); - Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleTbString("ko-KR", "America/New_York")); - Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleTbString( "uk-UA", "Europe/Kiev")); - Assert.assertEquals("5\u200F/9\u200F/2023, 9:04:05 م", d.toLocaleTbString( "ar-EG", "America/New_York")); + Assert.assertEquals("9/5/23, 9:04:05 PM", d.toLocaleString("en-US", "America/New_York")); + Assert.assertEquals("23. 9. 5. 오후 9:04:05", d.toLocaleString("ko-KR", "America/New_York")); + Assert.assertEquals("06.09.23, 04:04:05", d.toLocaleString( "uk-UA", "Europe/Kiev")); + Assert.assertEquals("5\u200F/9\u200F/2023, 9:04:05 م", d.toLocaleString( "ar-EG", "America/New_York")); - Assert.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleTbString("en-US", JacksonUtil.newObjectNode() + + Assert.assertEquals("Tuesday, September 5, 2023 at 9:04:05 PM Eastern Daylight Time", d.toLocaleString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("2023년 9월 5일 화요일 오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleTbString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("2023년 9월 5일 화요일 오후 9시 4분 5초 미 동부 하계 표준시", d.toLocaleString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("середа, 6 вересня 2023 р. о 04:04:05 за східноєвропейським літнім часом", d.toLocaleTbString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("середа, 6 вересня 2023 р. о 04:04:05 за східноєвропейським літнім часом", d.toLocaleString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleTbString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("الثلاثاء، 5 سبتمبر 2023 في 9:04:05 م التوقيت الصيفي الشرقي لأمريكا الشمالية", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("dateStyle", "full") .put("timeStyle", "full") .toString())); - Assert.assertEquals("9/5/2023, 9:04:05 PM", d.toLocaleTbString("en-US", JacksonUtil.newObjectNode() + Assert.assertEquals("9/5/2023, 9:04:05 PM", d.toLocaleString("en-US", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); - Assert.assertEquals("9/5/2023, 9:04:05 오후", d.toLocaleTbString("ko-KR", JacksonUtil.newObjectNode() + Assert.assertEquals("9/5/2023, 9:04:05 오후", d.toLocaleString("ko-KR", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); - Assert.assertEquals("9/6/2023, 4:04:05 дп", d.toLocaleTbString("uk-UA", JacksonUtil.newObjectNode() + Assert.assertEquals("9/6/2023, 4:04:05 дп", d.toLocaleString("uk-UA", JacksonUtil.newObjectNode() .put("timeZone", "Europe/Kiev") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); - Assert.assertEquals("9/5/2023, 9:04:05 م", d.toLocaleTbString("ar-EG", JacksonUtil.newObjectNode() + Assert.assertEquals("9/5/2023, 9:04:05 م", d.toLocaleString("ar-EG", JacksonUtil.newObjectNode() .put("timeZone", "America/New_York") .put("pattern", "M/d/yyyy, h:mm:ss a") .toString())); From f1a751db5a835209fbfe35ca66c2028e86a9dde7 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 27 Oct 2023 16:33:42 +0300 Subject: [PATCH 41/61] tbDate: add DateTimeFormatter --- .../thingsboard/script/api/tbel/TbDate.java | 18 +++++++-- .../script/api/tbel/TbDateTest.java | 40 +++++++++++++------ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java index 34c4669f1e..a662aa1ad9 100644 --- a/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java +++ b/common/script/script-api/src/main/java/org/thingsboard/script/api/tbel/TbDate.java @@ -28,7 +28,6 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; -import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; @@ -94,7 +93,10 @@ public class TbDate implements Serializable, Cloneable { } public ZonedDateTime getZonedDateTime() { - return instant.atZone(zoneIdUTC); + return getZonedDateTime(zoneIdUTC); + } + public ZonedDateTime getZonedDateTime(ZoneId zoneId) { + return instant.atZone(zoneId); } public LocalDateTime getLocalDateTime() { @@ -149,13 +151,21 @@ public class TbDate implements Serializable, Cloneable { public String toString(String localeStr, String optionsStr) { return toLocaleString(localeStr, optionsStr, (locale, options) -> DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL).withLocale(locale)); } - public String toISOZonedDateTimeString() { + public String toZonedDateTimeString() { return getZonedDateTime().toString(); } - public String toISOZonedDateTimeString(DateTimeFormatter formatter) { + public String toZonedDateTimeString(DateTimeFormatter formatter) { return getZonedDateTime().format(formatter); } + public String toZonedDateTimeString(String zoneIdStr) { + return getZonedDateTime(ZoneId.of(zoneIdStr)).toString(); + } + public String toZonedDateTimeString(DateTimeFormatter formatter, String zoneIdStr) { + return getZonedDateTime(ZoneId.of(zoneIdStr)).format(formatter); + } + + public String toLocaleDateString() { return toLocaleDateString(localeUTC.getLanguage()); } diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index 7f09219df9..3f6730de51 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -365,19 +365,33 @@ class TbDateTest { TbDate d1 = new TbDate(23, 9, 7, 8, 4, 5, "+04:00"); TbDate d2 = new TbDate(23, 9, 7, 8, 4, 5, "-03:00"); - Assert.assertEquals("2023-09-07T04:04:05Z[UTC]", d1.toISOZonedDateTimeString()); - Assert.assertEquals("2023-09-07T04:04:05Z", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); - Assert.assertEquals("2023-09-07T04:04:05Z[UTC]", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_ZONED_DATE_TIME)); - Assert.assertEquals("2023-09-07T04:04:05", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); - Assert.assertEquals("Thu, 7 Sep 2023 04:04:05 GMT", d1.toISOZonedDateTimeString(DateTimeFormatter.RFC_1123_DATE_TIME)); - Assert.assertEquals("2023-09-07T04:04:05Z", d1.toISOZonedDateTimeString(DateTimeFormatter.ISO_INSTANT)); - - Assert.assertEquals("2023-09-07T11:04:05Z[UTC]", d2.toISOZonedDateTimeString()); - Assert.assertEquals("2023-09-07T11:04:05Z", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); - Assert.assertEquals("2023-09-07T11:04:05Z[UTC]", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_ZONED_DATE_TIME)); - Assert.assertEquals("2023-09-07T11:04:05", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); - Assert.assertEquals("Thu, 7 Sep 2023 11:04:05 GMT", d2.toISOZonedDateTimeString(DateTimeFormatter.RFC_1123_DATE_TIME)); - Assert.assertEquals("2023-09-07T11:04:05Z", d2.toISOZonedDateTimeString(DateTimeFormatter.ISO_INSTANT)); + Assert.assertEquals("2023-09-07T04:04:05Z[UTC]", d1.toZonedDateTimeString()); + Assert.assertEquals("2023-09-07T04:04:05Z", d1.toZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); + Assert.assertEquals("2023-09-07T04:04:05Z[UTC]", d1.toZonedDateTimeString(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + Assert.assertEquals("2023-09-07T04:04:05", d1.toZonedDateTimeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + Assert.assertEquals("Thu, 7 Sep 2023 04:04:05 GMT", d1.toZonedDateTimeString(DateTimeFormatter.RFC_1123_DATE_TIME)); + Assert.assertEquals("2023-09-07T04:04:05Z", d1.toZonedDateTimeString(DateTimeFormatter.ISO_INSTANT)); + + Assert.assertEquals("2023-09-07T11:04:05Z[UTC]", d2.toZonedDateTimeString()); + Assert.assertEquals("2023-09-07T11:04:05Z", d2.toZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME)); + Assert.assertEquals("2023-09-07T11:04:05Z[UTC]", d2.toZonedDateTimeString(DateTimeFormatter.ISO_ZONED_DATE_TIME)); + Assert.assertEquals("2023-09-07T11:04:05", d2.toZonedDateTimeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + Assert.assertEquals("Thu, 7 Sep 2023 11:04:05 GMT", d2.toZonedDateTimeString(DateTimeFormatter.RFC_1123_DATE_TIME)); + Assert.assertEquals("2023-09-07T11:04:05Z", d2.toZonedDateTimeString(DateTimeFormatter.ISO_INSTANT)); + } + @Test + void TestZoneDateTimeFormatterToString () { + TbDate d1 = new TbDate(23, 9, 7, 8, 4, 5, "-04:00"); + Assert.assertEquals("2023-09-07T12:04:05Z[UTC]", d1.toZonedDateTimeString()); + Assert.assertEquals("2023-09-07T12:04:05Z", d1.toZonedDateTimeString(DateTimeFormatter.ISO_INSTANT,"America/New_York")); + Assert.assertEquals("2023-09-07T08:04:05-04:00", d1.toZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME,"America/New_York")); + Assert.assertEquals("2023-09-07T08:04:05-04:00[America/New_York]", d1.toZonedDateTimeString("America/New_York")); + Assert.assertEquals("Thu, 7 Sep 2023 08:04:05 -0400", d1.toZonedDateTimeString(DateTimeFormatter.RFC_1123_DATE_TIME,"America/New_York")); + + Assert.assertEquals("2023-09-07T14:04:05+02:00[Europe/Berlin]", d1.toZonedDateTimeString("Europe/Berlin")); + Assert.assertEquals("2023-09-07T14:04:05+02:00", d1.toZonedDateTimeString(DateTimeFormatter.ISO_OFFSET_DATE_TIME,"Europe/Berlin")); + Assert.assertEquals("2023-09-08T02:04:05+14:00[Etc/GMT-14]", d1.toZonedDateTimeString("Etc/GMT-14")); + Assert.assertEquals("2023-09-07T00:04:05-12:00[Etc/GMT+12]", d1.toZonedDateTimeString("Etc/GMT+12")); } @Test From edfc72ad2a1246f0cdbad36b865dece8b6a0041c Mon Sep 17 00:00:00 2001 From: nick Date: Mon, 30 Oct 2023 14:14:40 +0200 Subject: [PATCH 42/61] tbel Release 1.1.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a393dd74cf..a81c4d38f9 100755 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 3.8.1 3.21.9 1.42.1 - 1.1.1 + 1.1.3 1.18.26 1.2.4 1.2.5 From 3bfde753f037abd3a4b76fca1785225fcbec0981 Mon Sep 17 00:00:00 2001 From: nick Date: Sat, 2 Dec 2023 10:59:45 +0200 Subject: [PATCH 43/61] tbel Release 1.1.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a81c4d38f9..64ed92bbc6 100755 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ 3.8.1 3.21.9 1.42.1 - 1.1.3 + 1.1.5 1.18.26 1.2.4 1.2.5 From b30bbf9d80183c3839ffcca8bf6df2c0dc609098 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 14 Dec 2023 19:05:54 +0200 Subject: [PATCH 44/61] attribute_kv optimization: deleted entity_type column, updated attribute_type and attribute_key columns --- .../3.6.2/schema_update_attribute_kv.sql | 181 ++++++++++++++++++ .../data/upgrade/3.6.2/schema_update_ttl.sql | 87 +++++++++ .../install/ThingsboardInstallService.java | 6 + .../CassandraTsDatabaseUpgradeService.java | 1 + .../install/SqlDatabaseUpgradeService.java | 97 ++++++++++ .../install/SqlTsDatabaseUpgradeService.java | 2 + .../TimescaleTsDatabaseUpgradeService.java | 5 + .../query/DefaultEntityQueryService.java | 11 +- .../dao/attributes/AttributesService.java | 3 +- .../server/common/data/AttributeScope.java | 32 ++++ .../server/dao/attributes/AttributeUtils.java | 3 +- .../server/dao/attributes/AttributesDao.java | 14 +- .../dao/attributes/BaseAttributesService.java | 18 +- .../attributes/CachedAttributesService.java | 18 +- .../model/sql/AttributeKvCompositeKey.java | 11 +- .../dao/model/sql/AttributeKvDictionary.java | 41 ++++ .../dao/model/sql/AttributeKvEntity.java | 14 +- .../server/dao/service/Validator.java | 14 ++ .../AttributeKvDictionaryRepository.java | 29 +++ .../AttributeKvInsertRepository.java | 58 +++--- .../sql/attributes/AttributeKvRepository.java | 29 ++- .../dao/sql/attributes/JpaAttributeDao.java | 113 ++++++++--- .../dao/sql/query/EntityKeyMapping.java | 20 +- .../main/resources/sql/schema-entities.sql | 13 +- .../main/resources/sql/schema-timescale.sql | 4 +- dao/src/main/resources/sql/schema-ts-psql.sql | 4 +- .../sql/schema-views-and-functions.sql | 2 +- .../profile/TbDeviceProfileNodeTest.java | 58 ++++-- 28 files changed, 729 insertions(+), 159 deletions(-) create mode 100644 application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql create mode 100644 application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/AttributeScope.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionary.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java diff --git a/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql b/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql new file mode 100644 index 0000000000..142b3c1844 --- /dev/null +++ b/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql @@ -0,0 +1,181 @@ +-- +-- Copyright © 2016-2023 The Thingsboard Authors +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + + +-- create new attribute_kv table schema +DO +$$ + BEGIN + -- in case of running the upgrade script a second time: + IF EXISTS(SELECT 1 FROM information_schema.columns WHERE table_name = 'attribute_kv' and column_name='entity_type') THEN + IF EXISTS(SELECT 1 FROM pg_indexes WHERE indexname = 'idx_attribute_kv_by_key_and_last_update_ts') THEN + ALTER INDEX idx_attribute_kv_by_key_and_last_update_ts RENAME TO idx_attribute_kv_by_key_and_last_update_ts_old; + END IF; + IF EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'attribute_kv_pkey') THEN + ALTER TABLE attribute_kv RENAME CONSTRAINT attribute_kv_pkey TO attribute_kv_pkey_old; + END IF; + ALTER TABLE attribute_kv + RENAME TO attribute_kv_old; + CREATE TABLE IF NOT EXISTS attribute_kv + ( + entity_id uuid, + attribute_type int, + attribute_key int, + bool_v boolean, + str_v varchar(10000000), + long_v bigint, + dbl_v double precision, + json_v json, + last_update_ts bigint, + CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_id, attribute_type, attribute_key) + ); + END IF; + END; +$$; + +-- create attribute_kv_dictionary table +CREATE TABLE IF NOT EXISTS attribute_kv_dictionary +( + key varchar(255) NOT NULL, + key_id serial UNIQUE, + CONSTRAINT attribute_key_id_pkey PRIMARY KEY (key) +); + +-- create to_attribute_type_id +CREATE OR REPLACE FUNCTION to_attribute_type_id(IN attribute_type varchar, OUT attribute_type_id int) AS +$$ +BEGIN + CASE + WHEN attribute_type = 'CLIENT_SCOPE' THEN + attribute_type_id := 1; + WHEN attribute_type = 'SERVER_SCOPE' THEN + attribute_type_id := 2; + WHEN attribute_type = 'SHARED_SCOPE' THEN + attribute_type_id := 3; + END CASE; +END; +$$ LANGUAGE plpgsql; + + +-- insert keys into attribute_kv_dictionary +DO +$$ +DECLARE + insert_record RECORD; + key_cursor refcursor; +BEGIN + IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'attribute_kv_old') THEN + OPEN key_cursor FOR SELECT DISTINCT attribute_key + FROM attribute_kv_old + ORDER BY attribute_key; + LOOP + FETCH key_cursor INTO insert_record; + EXIT WHEN NOT FOUND; + IF NOT EXISTS(SELECT key FROM attribute_kv_dictionary WHERE key = insert_record.attribute_key) THEN + INSERT INTO attribute_kv_dictionary(key) VALUES (insert_record.attribute_key); + END IF; + END LOOP; + CLOSE key_cursor; + END IF; +END; +$$; + +-- create procedure to migrate all rows from attribute_kv_old to attribute_kv +CREATE OR REPLACE PROCEDURE insert_into_attribute_kv(IN path_to_file varchar) + LANGUAGE plpgsql AS +$$ +DECLARE + row_num_old integer; + row_num integer; + attribute_scope_array text[]; +BEGIN + attribute_scope_array := ARRAY['SERVER_SCOPE', 'CLIENT_SCOPE', 'SHARED_SCOPE']; + IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'attribute_kv_old') THEN + EXECUTE format('COPY (SELECT records.entity_id AS entity_id, + to_attribute_type_id(records.attribute_type) AS attribute_type, + records.attribute_key AS attribute_key, + records.bool_v AS bool_v, + records.str_v AS str_v, + records.long_v AS long_v, + records.dbl_v AS dbl_v, + records.json_v AS json_v, + records.last_update_ts AS last_update_ts + FROM (SELECT entity_id, + attribute_type, + key_id AS attribute_key, + bool_v, + str_v, + long_v, + dbl_v, + json_v, + last_update_ts + FROM attribute_kv_old INNER JOIN attribute_kv_dictionary ON (attribute_kv_old.attribute_key = attribute_kv_dictionary.key) + WHERE attribute_type= ANY(%L)) AS records) TO %L;', attribute_scope_array, path_to_file); + EXECUTE format('COPY attribute_kv FROM %L', path_to_file); + SELECT COUNT(*) INTO row_num_old FROM attribute_kv_old; + SELECT COUNT(*) INTO row_num FROM attribute_kv; + RAISE NOTICE 'Migrated % of % rows', row_num, row_num_old; + END IF; +EXCEPTION + WHEN others THEN + ROLLBACK; + RAISE EXCEPTION 'Error during COPY: %', SQLERRM; +END +$$; + +CREATE OR REPLACE PROCEDURE recreate_device_info_active_attribute_view() + LANGUAGE plpgsql AS +$$ +BEGIN + DROP VIEW IF EXISTS device_info_active_attribute_view CASCADE; + CREATE OR REPLACE VIEW device_info_active_attribute_view AS + SELECT d.* + , c.title as customer_title + , COALESCE((c.additional_info::json->>'isPublic')::bool, FALSE) as customer_is_public + , d.type as device_profile_name + , COALESCE(da.bool_v, FALSE) as active + FROM device d + LEFT JOIN customer c ON c.id = d.customer_id + LEFT JOIN attribute_kv da ON da.entity_id = d.id AND da.attribute_type = 2 AND da.attribute_key = (select key_id from attribute_kv_dictionary where key = 'active'); +END; +$$; + +CREATE OR REPLACE PROCEDURE recreate_device_info_view() + LANGUAGE plpgsql AS +$$ +BEGIN + DROP VIEW IF EXISTS device_info_view CASCADE; + CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_attribute_view; +END; +$$; + +CREATE OR REPLACE PROCEDURE drop_attribute_kv_old_table() + LANGUAGE plpgsql AS +$$ +DECLARE + row_num integer; +BEGIN + SELECT COUNT(*) INTO row_num FROM attribute_kv; + IF row_num != 0 then + DROP TABLE IF EXISTS attribute_kv_old; + DROP PROCEDURE IF EXISTS insert_into_attribute_kv(IN path_to_file varchar); + ELSE + RAISE EXCEPTION 'Table attribute_kv is empty'; + END IF; + RETURN; +END; +$$; + diff --git a/application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql b/application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql new file mode 100644 index 0000000000..67ec25656e --- /dev/null +++ b/application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql @@ -0,0 +1,87 @@ +-- +-- Copyright © 2016-2023 The Thingsboard Authors +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +CREATE OR REPLACE PROCEDURE cleanup_timeseries_by_ttl(IN null_uuid uuid, + IN system_ttl bigint, INOUT deleted bigint) + LANGUAGE plpgsql AS +$$ +DECLARE +tenant_cursor CURSOR FOR select tenant.id as tenant_id + from tenant; +tenant_id_record uuid; + customer_id_record uuid; + tenant_ttl bigint; + customer_ttl bigint; + deleted_for_entities bigint; + tenant_ttl_ts bigint; + customer_ttl_ts bigint; +BEGIN +OPEN tenant_cursor; +FETCH tenant_cursor INTO tenant_id_record; +WHILE FOUND + LOOP + EXECUTE format( + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + tenant_id_record, 'TTL') INTO tenant_ttl; + if tenant_ttl IS NULL THEN + tenant_ttl := system_ttl; +END IF; + IF tenant_ttl > 0 THEN + tenant_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - tenant_ttl::bigint * 1000)::bigint; + deleted_for_entities := delete_device_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for devices where tenant_id = %', deleted_for_entities, tenant_id_record; + deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for assets where tenant_id = %', deleted_for_entities, tenant_id_record; +END IF; +FOR customer_id_record IN +SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record + LOOP + EXECUTE format( + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + customer_id_record, 'TTL') INTO customer_ttl; +IF customer_ttl IS NULL THEN + customer_ttl_ts := tenant_ttl_ts; +ELSE + IF customer_ttl > 0 THEN + customer_ttl_ts := + (EXTRACT(EPOCH FROM current_timestamp) * 1000 - + customer_ttl::bigint * 1000)::bigint; +END IF; +END IF; + IF customer_ttl_ts IS NOT NULL AND customer_ttl_ts > 0 THEN + deleted_for_entities := + delete_customer_records_from_ts_kv(tenant_id_record, customer_id_record, + customer_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for customer with id = % where tenant_id = %', deleted_for_entities, customer_id_record, tenant_id_record; + deleted_for_entities := + delete_device_records_from_ts_kv(tenant_id_record, customer_id_record, + customer_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for devices where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; + deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, + customer_id_record, + customer_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for assets where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; +END IF; +END LOOP; +FETCH tenant_cursor INTO tenant_id_record; +END LOOP; +END +$$; \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 3829b3cf45..ac348c1249 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -265,6 +265,12 @@ public class ThingsboardInstallService { case "3.6.0": log.info("Upgrading ThingsBoard from version 3.6.0 to 3.6.1 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.6.0"); + case "3.6.2": + log.info("Upgrading ThingsBoard from version 3.6.2 to 3.7.0 ..."); + if (databaseTsUpgradeService != null) { + databaseTsUpgradeService.upgradeDatabase("3.6.2"); + } + databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java index 5c7c51eb2c..3e2f29440c 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java @@ -52,6 +52,7 @@ public class CassandraTsDatabaseUpgradeService extends AbstractCassandraDatabase case "3.1.1": case "3.2.1": case "3.2.2": + case "3.6.2": break; default: throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion); diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index c02b7e9cc1..2983dea649 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -19,12 +19,14 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.SystemUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.EntitySubtype; +import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; @@ -48,6 +50,8 @@ import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; import org.thingsboard.server.service.install.sql.SqlDbHelper; import org.thingsboard.server.service.install.update.DefaultDataUpdateService; +import java.io.File; +import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; @@ -64,6 +68,8 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.TimeUnit; +import static org.thingsboard.server.service.install.AbstractSqlTsDatabaseUpgradeService.PATH_TO_USERS_PUBLIC_FOLDER; +import static org.thingsboard.server.service.install.AbstractSqlTsDatabaseUpgradeService.THINGSBOARD_WINDOWS_UPGRADE_DIR; import static org.thingsboard.server.service.install.DatabaseHelper.ADDITIONAL_INFO; import static org.thingsboard.server.service.install.DatabaseHelper.ASSIGNED_CUSTOMERS; import static org.thingsboard.server.service.install.DatabaseHelper.CONFIGURATION; @@ -89,6 +95,7 @@ import static org.thingsboard.server.service.install.DatabaseHelper.TYPE; public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService { private static final String SCHEMA_UPDATE_SQL = "schema_update.sql"; + private static final String LOAD_ATTRIBUTE_KV_FUNCTIONS_SQL = "schema_update_attribute_kv.sql"; @Value("${spring.datasource.url}") private String dbUrl; @@ -792,11 +799,88 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService log.error("Failed updating schema!!!", e); } break; + case "3.6.2": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + if (isOldSchema(conn, 3006002)) { + log.info("Updating schema ..."); + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.6.2", LOAD_ATTRIBUTE_KV_FUNCTIONS_SQL); + loadSql(schemaUpdateFile, conn); + + Path pathToTempAttributeKvFile; + if (SystemUtils.IS_OS_WINDOWS) { + pathToTempAttributeKvFile = createTempFileWindows("attribute_kv_temp",".sql"); + executeQuery(conn, "call insert_into_attribute_kv('" + pathToTempAttributeKvFile + "')"); + } else { + pathToTempAttributeKvFile = createTempFile("attribute_kv", "attribute_kv_temp.sql"); + executeQuery(conn, "call insert_into_attribute_kv('" + pathToTempAttributeKvFile + "')"); + } + + //recreate device_info_active_attribute_view + executeQuery(conn, "call recreate_device_info_active_attribute_view()"); + executeQuery(conn, "call recreate_device_info_view()"); + + // remove attribute_kv_old + executeQuery(conn, "call drop_attribute_kv_old_table()"); + + //create index for new table attribute_kv + executeQuery(conn, "CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc);"); + + // remove temp files + if (pathToTempAttributeKvFile.toFile().exists()) { + boolean deleteTsKvFile = pathToTempAttributeKvFile.toFile().delete(); + if (deleteTsKvFile) { + log.info("Successfully deleted the temp file for attribute_kv table upgrade!"); + } + } + + executeQuery(conn, "UPDATE tb_schema_settings SET schema_version = 3007000;"); + log.info("Schema updated to version 3.7.0."); + } else { + log.info("Skip schema re-update to version 3.7.0. Use env flag 'SKIP_SCHEMA_VERSION_CHECK' to force the re-update."); + } + } catch (Exception e) { + log.error("Failed updating schema!!!", e); + } + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } } + private static Path createTempFile(String tempDirectoryName, String tempFileName) throws IOException { + Path pathToTempAttributeKvFile; + Path tempDirPath = Files.createTempDirectory(tempDirectoryName); + File tempDirAsFile = tempDirPath.toFile(); + boolean writable = tempDirAsFile.setWritable(true, false); + boolean readable = tempDirAsFile.setReadable(true, false); + boolean executable = tempDirAsFile.setExecutable(true, false); + pathToTempAttributeKvFile = tempDirPath.resolve(tempFileName).toAbsolutePath(); + + if (!(writable && readable && executable)) { + throw new RuntimeException("Failed to grant write permissions for the: " + tempDirPath + "folder!"); + } + return pathToTempAttributeKvFile; + } + + private static Path createTempFileWindows(String prefix, String suffix) throws IOException { + Path pathToTempAttributeKvFile; + log.info("Lookup for environment variable: {} ...", THINGSBOARD_WINDOWS_UPGRADE_DIR); + Path pathToDir; + String thingsboardWindowsUpgradeDir = System.getenv("THINGSBOARD_WINDOWS_UPGRADE_DIR"); + if (StringUtils.isNotEmpty(thingsboardWindowsUpgradeDir)) { + log.info("Environment variable: {} was found!", THINGSBOARD_WINDOWS_UPGRADE_DIR); + pathToDir = Paths.get(thingsboardWindowsUpgradeDir); + } else { + log.info("Failed to lookup environment variable: {}", THINGSBOARD_WINDOWS_UPGRADE_DIR); + pathToDir = Paths.get(PATH_TO_USERS_PUBLIC_FOLDER); + } + log.info("Directory: {} will be used for creation temporary upgrade files!", pathToDir); + + Path attributeKvFile = Files.createTempFile(pathToDir, prefix, suffix); + pathToTempAttributeKvFile = attributeKvFile.toAbsolutePath(); + return pathToTempAttributeKvFile; + } + private void runSchemaUpdateScript(Connection connection, String version) throws Exception { Path schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", version, SCHEMA_UPDATE_SQL); loadSql(schemaUpdateFile, connection); @@ -811,6 +895,19 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService Thread.sleep(5000); } + private void executeQuery(Connection conn, String query) { + try { + Statement statement = conn.createStatement(); + statement.execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script + printWarnings(statement); + Thread.sleep(2000); + log.info("Successfully executed query: {}", query); + } catch (InterruptedException | SQLException e) { + log.error("Failed to execute query: {} due to: {}", query, e.getMessage()); + throw new RuntimeException("Failed to execute query:" + query + " due to: ", e); + } + } + protected void printWarnings(Statement statement) throws SQLException { SQLWarning warnings = statement.getWarnings(); if (warnings != null) { diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java index 6400463e11..b61da45631 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java @@ -213,6 +213,8 @@ public class SqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSer loadSql(conn, LOAD_DROP_PARTITIONS_FUNCTIONS_SQL, "2.4.3"); } break; + case "3.6.2": + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java index 205ec14591..4477bef1c4 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java @@ -184,6 +184,11 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr break; case "3.2.2": break; + case "3.6.2": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + loadSql(conn, LOAD_TTL_FUNCTIONS_SQL, "3.6.2"); + } + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java b/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java index 89b4002223..296c992ccf 100644 --- a/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java +++ b/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java @@ -251,14 +251,13 @@ public class DefaultEntityQueryService implements EntityQueryService { } if (isAttributes) { - Map> typesMap = ids.stream().collect(Collectors.groupingBy(EntityId::getEntityType)); - List>> futures = new ArrayList<>(typesMap.size()); - typesMap.forEach((type, entityIds) -> futures.add(dbCallbackExecutor.submit(() -> attributesService.findAllKeysByEntityIds(tenantId, type, entityIds)))); - attributesKeysFuture = Futures.transform(Futures.allAsList(futures), lists -> { - if (CollectionUtils.isEmpty(lists)) { + ListenableFuture> future; + future = dbCallbackExecutor.submit(() -> attributesService.findAllKeysByEntityIds(tenantId, ids)); + attributesKeysFuture = Futures.transform(future, list -> { + if (CollectionUtils.isEmpty(list)) { return Collections.emptyList(); } - return lists.stream().flatMap(List::stream).distinct().sorted().collect(Collectors.toList()); + return list.stream().distinct().sorted().collect(Collectors.toList()); }, dbCallbackExecutor); } else { attributesKeysFuture = null; diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java index 8fab864cc5..de1386d0c6 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java @@ -16,7 +16,6 @@ package org.thingsboard.server.dao.attributes; import com.google.common.util.concurrent.ListenableFuture; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -45,6 +44,6 @@ public interface AttributesService { List findAllKeysByDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId); - List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds); + List findAllKeysByEntityIds(TenantId tenantId, List entityIds); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/AttributeScope.java b/common/data/src/main/java/org/thingsboard/server/common/data/AttributeScope.java new file mode 100644 index 0000000000..83f5210427 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/AttributeScope.java @@ -0,0 +1,32 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data; + +import lombok.Getter; + +public enum AttributeScope { + + CLIENT_SCOPE(1), + SERVER_SCOPE(2), + SHARED_SCOPE(3); + @Getter + private final int id; + + AttributeScope(int id) { + this.id = id; + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java index 192d56334d..29c44edd68 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.attributes; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.dao.exception.IncorrectParameterException; @@ -27,7 +28,7 @@ public class AttributeUtils { public static void validate(EntityId id, String scope) { Validator.validateId(id.getId(), "Incorrect id " + id); - Validator.validateString(scope, "Incorrect scope " + scope); + Validator.validateEnum(AttributeScope.class, scope, "Incorrect scope " + scope); } public static void validate(List kvEntries, boolean valueNoXssValidation) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java index ffb3b9c229..2f53b0afa7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributesDao.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.attributes; import com.google.common.util.concurrent.ListenableFuture; -import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -31,17 +31,17 @@ import java.util.Optional; */ public interface AttributesDao { - Optional find(TenantId tenantId, EntityId entityId, String attributeType, String attributeKey); + Optional find(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, String attributeKey); - List find(TenantId tenantId, EntityId entityId, String attributeType, Collection attributeKey); + List find(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, Collection attributeKey); - List findAll(TenantId tenantId, EntityId entityId, String attributeType); + List findAll(TenantId tenantId, EntityId entityId, AttributeScope attributeScope); - ListenableFuture save(TenantId tenantId, EntityId entityId, String attributeType, AttributeKvEntry attribute); + ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, AttributeKvEntry attribute); - List> removeAll(TenantId tenantId, EntityId entityId, String attributeType, List keys); + List> removeAll(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, List keys); List findAllKeysByDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId); - List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds); + List findAllKeysByEntityIds(TenantId tenantId, List entityIds); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java index f855c116e2..2defbd9398 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -57,20 +57,20 @@ public class BaseAttributesService implements AttributesService { public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey) { validate(entityId, scope); Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey); - return Futures.immediateFuture(attributesDao.find(tenantId, entityId, scope, attributeKey)); + return Futures.immediateFuture(attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKey)); } @Override public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys) { validate(entityId, scope); attributeKeys.forEach(attributeKey -> Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey)); - return Futures.immediateFuture(attributesDao.find(tenantId, entityId, scope, attributeKeys)); + return Futures.immediateFuture(attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys)); } @Override public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope) { validate(entityId, scope); - return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, scope)); + return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, AttributeScope.valueOf(scope))); } @Override @@ -79,28 +79,28 @@ public class BaseAttributesService implements AttributesService { } @Override - public List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds) { - return attributesDao.findAllKeysByEntityIds(tenantId, entityType, entityIds); + public List findAllKeysByEntityIds(TenantId tenantId, List entityIds) { + return attributesDao.findAllKeysByEntityIds(tenantId, entityIds); } @Override public ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute) { validate(entityId, scope); AttributeUtils.validate(attribute, valueNoXssValidation); - return attributesDao.save(tenantId, entityId, scope, attribute); + return attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); } @Override public ListenableFuture> save(TenantId tenantId, EntityId entityId, String scope, List attributes) { validate(entityId, scope); AttributeUtils.validate(attributes, valueNoXssValidation); - List> saveFutures = attributes.stream().map(attribute -> attributesDao.save(tenantId, entityId, scope, attribute)).collect(Collectors.toList()); + List> saveFutures = attributes.stream().map(attribute -> attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute)).collect(Collectors.toList()); return Futures.allAsList(saveFutures); } @Override public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys) { validate(entityId, scope); - return Futures.allAsList(attributesDao.removeAll(tenantId, entityId, scope, attributeKeys)); + return Futures.allAsList(attributesDao.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys)); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java index 322d725ff3..327f6b5706 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java @@ -26,7 +26,7 @@ import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; import org.thingsboard.server.cache.TbCacheValueWrapper; import org.thingsboard.server.cache.TbTransactionalCache; -import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; @@ -120,7 +120,7 @@ public class CachedAttributesService implements AttributesService { return cacheExecutor.submit(() -> { var cacheTransaction = cache.newTransactionForKey(attributeCacheKey); try { - Optional result = attributesDao.find(tenantId, entityId, scope, attributeKey); + Optional result = attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKey); cacheTransaction.putIfAbsent(attributeCacheKey, result.orElse(null)); cacheTransaction.commit(); return result; @@ -159,7 +159,7 @@ public class CachedAttributesService implements AttributesService { var cacheTransaction = cache.newTransactionForKeys(notFoundKeys); try { log.trace("[{}][{}] Lookup attributes from db: {}", entityId, scope, notFoundAttributeKeys); - List result = attributesDao.find(tenantId, entityId, scope, notFoundAttributeKeys); + List result = attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), notFoundAttributeKeys); for (AttributeKvEntry foundInDbAttribute : result) { AttributeCacheKey attributeCacheKey = new AttributeCacheKey(scope, entityId, foundInDbAttribute.getKey()); cacheTransaction.putIfAbsent(attributeCacheKey, foundInDbAttribute); @@ -198,7 +198,7 @@ public class CachedAttributesService implements AttributesService { @Override public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope) { validate(entityId, scope); - return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, scope)); + return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, AttributeScope.valueOf(scope))); } @Override @@ -207,15 +207,15 @@ public class CachedAttributesService implements AttributesService { } @Override - public List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds) { - return attributesDao.findAllKeysByEntityIds(tenantId, entityType, entityIds); + public List findAllKeysByEntityIds(TenantId tenantId, List entityIds) { + return attributesDao.findAllKeysByEntityIds(tenantId, entityIds); } @Override public ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute) { validate(entityId, scope); AttributeUtils.validate(attribute, valueNoXssValidation); - ListenableFuture future = attributesDao.save(tenantId, entityId, scope, attribute); + ListenableFuture future = attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); return Futures.transform(future, key -> evict(entityId, scope, attribute, key), cacheExecutor); } @@ -226,7 +226,7 @@ public class CachedAttributesService implements AttributesService { List> futures = new ArrayList<>(attributes.size()); for (var attribute : attributes) { - ListenableFuture future = attributesDao.save(tenantId, entityId, scope, attribute); + ListenableFuture future = attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); futures.add(Futures.transform(future, key -> evict(entityId, scope, attribute, key), cacheExecutor)); } @@ -243,7 +243,7 @@ public class CachedAttributesService implements AttributesService { @Override public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys) { validate(entityId, scope); - List> futures = attributesDao.removeAll(tenantId, entityId, scope, attributeKeys); + List> futures = attributesDao.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys); return Futures.allAsList(futures.stream().map(future -> Futures.transform(future, key -> { cache.evict(new AttributeCacheKey(scope, entityId, key)); return key; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java index 936a18eeeb..80be913468 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvCompositeKey.java @@ -17,12 +17,9 @@ package org.thingsboard.server.dao.model.sql; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.thingsboard.server.common.data.EntityType; import java.io.Serializable; import java.util.UUID; @@ -30,20 +27,16 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.ATTRIBUTE_KEY_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.ATTRIBUTE_TYPE_COLUMN; import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_ID_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_COLUMN; @Data @AllArgsConstructor @NoArgsConstructor @Embeddable public class AttributeKvCompositeKey implements Serializable { - @Enumerated(EnumType.STRING) - @Column(name = ENTITY_TYPE_COLUMN) - private EntityType entityType; @Column(name = ENTITY_ID_COLUMN, columnDefinition = "uuid") private UUID entityId; @Column(name = ATTRIBUTE_TYPE_COLUMN) - private String attributeType; + private int attributeType; @Column(name = ATTRIBUTE_KEY_COLUMN) - private String attributeKey; + private int attributeKey; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionary.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionary.java new file mode 100644 index 0000000000..1cde08912e --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionary.java @@ -0,0 +1,41 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.model.sql; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; +import org.hibernate.annotations.Generated; + +import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN; +import static org.thingsboard.server.dao.model.ModelConstants.KEY_ID_COLUMN; + +@Data +@Entity +@Table(name = "attribute_kv_dictionary") +public final class AttributeKvDictionary { + + @Id + @Column(name = KEY_COLUMN) + private String key; + + @Column(name = KEY_ID_COLUMN, unique = true, columnDefinition="int") + @Generated + private int keyId; + +} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java index bc97c0394f..1bb23aaa89 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvEntity.java @@ -30,6 +30,7 @@ import jakarta.persistence.Column; import jakarta.persistence.EmbeddedId; import jakarta.persistence.Entity; import jakarta.persistence.Table; +import jakarta.persistence.Transient; import java.io.Serializable; import static org.thingsboard.server.dao.model.ModelConstants.BOOLEAN_VALUE_COLUMN; @@ -65,19 +66,22 @@ public class AttributeKvEntity implements ToData, Serializable @Column(name = LAST_UPDATE_TS_COLUMN) private Long lastUpdateTs; + @Transient + protected String strKey; + @Override public AttributeKvEntry toData() { KvEntry kvEntry = null; if (strValue != null) { - kvEntry = new StringDataEntry(id.getAttributeKey(), strValue); + kvEntry = new StringDataEntry(strKey, strValue); } else if (booleanValue != null) { - kvEntry = new BooleanDataEntry(id.getAttributeKey(), booleanValue); + kvEntry = new BooleanDataEntry(strKey, booleanValue); } else if (doubleValue != null) { - kvEntry = new DoubleDataEntry(id.getAttributeKey(), doubleValue); + kvEntry = new DoubleDataEntry(strKey, doubleValue); } else if (longValue != null) { - kvEntry = new LongDataEntry(id.getAttributeKey(), longValue); + kvEntry = new LongDataEntry(strKey, longValue); } else if (jsonValue != null) { - kvEntry = new JsonDataEntry(id.getAttributeKey(), jsonValue); + kvEntry = new JsonDataEntry(strKey, jsonValue); } return new BaseAttributeKvEntry(kvEntry, lastUpdateTs); diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index d8c4ffddc9..5bf14d06ae 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.service; +import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.StringUtils; import org.thingsboard.common.util.RegexUtils; import org.thingsboard.server.common.data.id.EntityId; @@ -59,6 +60,19 @@ public class Validator { } } + /** + * This method validate String string. If string is null or can not be cast to enum than throw + * IncorrectParameterException exception + * + * @param val the val + * @param errorMessage the error message for exception + */ + public static > void validateEnum(Class enumClass, String val, String errorMessage) { + if (val == null || !EnumUtils.isValidEnum(enumClass, val)) { + throw new IncorrectParameterException(errorMessage); + } + } + /** * This method validate long value. If value isn't possitive than throw diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java new file mode 100644 index 0000000000..7af7df70ea --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java @@ -0,0 +1,29 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sql.attributes; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.thingsboard.server.dao.model.sql.AttributeKvDictionary; +import org.thingsboard.server.dao.util.SqlTsOrTsLatestAnyDao; + +import java.util.Optional; + +@SqlTsOrTsLatestAnyDao +public interface AttributeKvDictionaryRepository extends JpaRepository { + + Optional findByKeyId(int keyId); + +} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvInsertRepository.java index 75b7412985..6b33e45546 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvInsertRepository.java @@ -43,12 +43,12 @@ public abstract class AttributeKvInsertRepository { private static final String EMPTY_STR = ""; private static final String BATCH_UPDATE = "UPDATE attribute_kv SET str_v = ?, long_v = ?, dbl_v = ?, bool_v = ?, json_v = cast(? AS json), last_update_ts = ? " + - "WHERE entity_type = ? and entity_id = ? and attribute_type =? and attribute_key = ?;"; + "WHERE entity_id = ? and attribute_type =? and attribute_key = ?;"; private static final String INSERT_OR_UPDATE = - "INSERT INTO attribute_kv (entity_type, entity_id, attribute_type, attribute_key, str_v, long_v, dbl_v, bool_v, json_v, last_update_ts) " + - "VALUES(?, ?, ?, ?, ?, ?, ?, ?, cast(? AS json), ?) " + - "ON CONFLICT (entity_type, entity_id, attribute_type, attribute_key) " + + "INSERT INTO attribute_kv (entity_id, attribute_type, attribute_key, str_v, long_v, dbl_v, bool_v, json_v, last_update_ts) " + + "VALUES(?, ?, ?, ?, ?, ?, ?, cast(? AS json), ?) " + + "ON CONFLICT (entity_id, attribute_type, attribute_key) " + "DO UPDATE SET str_v = ?, long_v = ?, dbl_v = ?, bool_v = ?, json_v = cast(? AS json), last_update_ts = ?;"; @Autowired @@ -91,10 +91,9 @@ public abstract class AttributeKvInsertRepository { ps.setString(5, replaceNullChars(kvEntity.getJsonValue())); ps.setLong(6, kvEntity.getLastUpdateTs()); - ps.setString(7, kvEntity.getId().getEntityType().name()); - ps.setObject(8, kvEntity.getId().getEntityId()); - ps.setString(9, kvEntity.getId().getAttributeType()); - ps.setString(10, kvEntity.getId().getAttributeKey()); + ps.setObject(7, kvEntity.getId().getEntityId()); + ps.setInt(8, kvEntity.getId().getAttributeType()); + ps.setInt(9, kvEntity.getId().getAttributeKey()); } @Override @@ -121,43 +120,42 @@ public abstract class AttributeKvInsertRepository { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { AttributeKvEntity kvEntity = insertEntities.get(i); - ps.setString(1, kvEntity.getId().getEntityType().name()); - ps.setObject(2, kvEntity.getId().getEntityId()); - ps.setString(3, kvEntity.getId().getAttributeType()); - ps.setString(4, kvEntity.getId().getAttributeKey()); + ps.setObject(1, kvEntity.getId().getEntityId()); + ps.setInt(2, kvEntity.getId().getAttributeType()); + ps.setInt(3, kvEntity.getId().getAttributeKey()); - ps.setString(5, replaceNullChars(kvEntity.getStrValue())); - ps.setString(11, replaceNullChars(kvEntity.getStrValue())); + ps.setString(4, replaceNullChars(kvEntity.getStrValue())); + ps.setString(10, replaceNullChars(kvEntity.getStrValue())); if (kvEntity.getLongValue() != null) { - ps.setLong(6, kvEntity.getLongValue()); - ps.setLong(12, kvEntity.getLongValue()); + ps.setLong(5, kvEntity.getLongValue()); + ps.setLong(11, kvEntity.getLongValue()); } else { - ps.setNull(6, Types.BIGINT); - ps.setNull(12, Types.BIGINT); + ps.setNull(5, Types.BIGINT); + ps.setNull(11, Types.BIGINT); } if (kvEntity.getDoubleValue() != null) { - ps.setDouble(7, kvEntity.getDoubleValue()); - ps.setDouble(13, kvEntity.getDoubleValue()); + ps.setDouble(6, kvEntity.getDoubleValue()); + ps.setDouble(12, kvEntity.getDoubleValue()); } else { - ps.setNull(7, Types.DOUBLE); - ps.setNull(13, Types.DOUBLE); + ps.setNull(6, Types.DOUBLE); + ps.setNull(12, Types.DOUBLE); } if (kvEntity.getBooleanValue() != null) { - ps.setBoolean(8, kvEntity.getBooleanValue()); - ps.setBoolean(14, kvEntity.getBooleanValue()); + ps.setBoolean(7, kvEntity.getBooleanValue()); + ps.setBoolean(13, kvEntity.getBooleanValue()); } else { - ps.setNull(8, Types.BOOLEAN); - ps.setNull(14, Types.BOOLEAN); + ps.setNull(7, Types.BOOLEAN); + ps.setNull(13, Types.BOOLEAN); } - ps.setString(9, replaceNullChars(kvEntity.getJsonValue())); - ps.setString(15, replaceNullChars(kvEntity.getJsonValue())); + ps.setString(8, replaceNullChars(kvEntity.getJsonValue())); + ps.setString(14, replaceNullChars(kvEntity.getJsonValue())); - ps.setLong(10, kvEntity.getLastUpdateTs()); - ps.setLong(16, kvEntity.getLastUpdateTs()); + ps.setLong(9, kvEntity.getLastUpdateTs()); + ps.setLong(15, kvEntity.getLastUpdateTs()); } @Override diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java index 6a0cdfabd0..a43be3e49d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java @@ -20,7 +20,6 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; import org.thingsboard.server.dao.model.sql.AttributeKvEntity; @@ -29,35 +28,31 @@ import java.util.UUID; public interface AttributeKvRepository extends JpaRepository { - @Query("SELECT a FROM AttributeKvEntity a WHERE a.id.entityType = :entityType " + - "AND a.id.entityId = :entityId " + + @Query("SELECT a FROM AttributeKvEntity a WHERE a.id.entityId = :entityId " + "AND a.id.attributeType = :attributeType") - List findAllByEntityTypeAndEntityIdAndAttributeType(@Param("entityType") EntityType entityType, - @Param("entityId") UUID entityId, - @Param("attributeType") String attributeType); + List findAllEntityIdAndAttributeType(@Param("entityId") UUID entityId, + @Param("attributeType") int attributeType); @Transactional @Modifying - @Query("DELETE FROM AttributeKvEntity a WHERE a.id.entityType = :entityType " + - "AND a.id.entityId = :entityId " + + @Query("DELETE FROM AttributeKvEntity a WHERE a.id.entityId = :entityId " + "AND a.id.attributeType = :attributeType " + "AND a.id.attributeKey = :attributeKey") - void delete(@Param("entityType") EntityType entityType, - @Param("entityId") UUID entityId, - @Param("attributeType") String attributeType, - @Param("attributeKey") String attributeKey); + void delete(@Param("entityId") UUID entityId, + @Param("attributeType") int attributeType, + @Param("attributeKey") int attributeKey); @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE entity_type = 'DEVICE' " + "AND entity_id in (SELECT id FROM device WHERE tenant_id = :tenantId and device_profile_id = :deviceProfileId limit 100) ORDER BY attribute_key", nativeQuery = true) - List findAllKeysByDeviceProfileId(@Param("tenantId") UUID tenantId, + List findAllKeysByDeviceProfileId(@Param("tenantId") UUID tenantId, @Param("deviceProfileId") UUID deviceProfileId); @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE entity_type = 'DEVICE' " + "AND entity_id in (SELECT id FROM device WHERE tenant_id = :tenantId limit 100) ORDER BY attribute_key", nativeQuery = true) - List findAllKeysByTenantId(@Param("tenantId") UUID tenantId); + List findAllKeysByTenantId(@Param("tenantId") UUID tenantId); - @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE entity_type = :entityType " + - "AND entity_id in :entityIds ORDER BY attribute_key", nativeQuery = true) - List findAllKeysByEntityIds(@Param("entityType") String entityType, @Param("entityIds") List entityIds); + @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE " + + "entity_id in :entityIds ORDER BY attribute_key", nativeQuery = true) + List findAllKeysByEntityIds(@Param("entityIds") List entityIds); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java index 6d195d1cc4..c47cd9dbdf 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java @@ -22,10 +22,12 @@ import com.google.common.util.concurrent.MoreExecutors; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; +import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -34,6 +36,7 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.attributes.AttributesDao; import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; +import org.thingsboard.server.dao.model.sql.AttributeKvDictionary; import org.thingsboard.server.dao.model.sql.AttributeKvEntity; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; @@ -46,6 +49,9 @@ import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import java.util.stream.Collectors; @@ -57,6 +63,9 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl @Autowired ScheduledLogExecutorComponent logExecutor; + @Autowired + private AttributeKvDictionaryRepository dictionaryRepository; + @Autowired private AttributeKvRepository attributeKvRepository; @@ -81,6 +90,9 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl @Value("${sql.batch_sort:true}") private boolean batchSortEnabled; + private final ConcurrentMap attributeDictionaryMap = new ConcurrentHashMap<>(); + private static final ReentrantLock attributeCreationLock = new ReentrantLock(); + private TbSqlBlockingQueueWrapper queue; @PostConstruct @@ -98,7 +110,6 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl queue = new TbSqlBlockingQueueWrapper<>(params, hashcodeFunction, batchThreads, statsFactory); queue.init(logExecutor, v -> attributeKvInsertRepository.saveOrUpdate(v), Comparator.comparing((AttributeKvEntity attributeKvEntity) -> attributeKvEntity.getId().getEntityId()) - .thenComparing(attributeKvEntity -> attributeKvEntity.getId().getEntityType().name()) .thenComparing(attributeKvEntity -> attributeKvEntity.getId().getAttributeType()) .thenComparing(attributeKvEntity -> attributeKvEntity.getId().getAttributeKey()) ); @@ -112,81 +123,131 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl } @Override - public Optional find(TenantId tenantId, EntityId entityId, String attributeType, String attributeKey) { + public Optional find(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, String attributeKey) { AttributeKvCompositeKey compositeKey = - getAttributeKvCompositeKey(entityId, attributeType, attributeKey); - return Optional.ofNullable(DaoUtil.getData(attributeKvRepository.findById(compositeKey))); + getAttributeKvCompositeKey(entityId, attributeScope.getId(), getOrSaveKeyId(attributeKey)); + Optional attributeKvEntityOptional = attributeKvRepository.findById(compositeKey); + if (attributeKvEntityOptional.isPresent()) { + AttributeKvEntity attributeKvEntity = attributeKvEntityOptional.get(); + attributeKvEntity.setStrKey(attributeKey); + return Optional.ofNullable(DaoUtil.getData(attributeKvEntity)); + } + return Optional.ofNullable(DaoUtil.getData(attributeKvEntityOptional)); } @Override - public List find(TenantId tenantId, EntityId entityId, String attributeType, Collection attributeKeys) { + public List find(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, Collection attributeKeys) { List compositeKeys = attributeKeys .stream() .map(attributeKey -> - getAttributeKvCompositeKey(entityId, attributeType, attributeKey)) + getAttributeKvCompositeKey(entityId, attributeScope.getId(), getOrSaveKeyId(attributeKey))) .collect(Collectors.toList()); - return DaoUtil.convertDataList(Lists.newArrayList(attributeKvRepository.findAllById(compositeKeys))); + List attributes = attributeKvRepository.findAllById(compositeKeys); + attributes.forEach(attributeKvEntity -> attributeKvEntity.setStrKey(getKey(attributeKvEntity.getId().getAttributeKey()))); + return DaoUtil.convertDataList(Lists.newArrayList(attributes)); } @Override - public List findAll(TenantId tenantId, EntityId entityId, String attributeType) { + public List findAll(TenantId tenantId, EntityId entityId, AttributeScope attributeScope) { + List attributes = attributeKvRepository.findAllEntityIdAndAttributeType( + entityId.getId(), + attributeScope.getId()); + attributes.forEach(attributeKvEntity -> attributeKvEntity.setStrKey(getKey(attributeKvEntity.getId().getAttributeKey()))); return DaoUtil.convertDataList(Lists.newArrayList( - attributeKvRepository.findAllByEntityTypeAndEntityIdAndAttributeType( - entityId.getEntityType(), - entityId.getId(), - attributeType))); + attributes)); } @Override public List findAllKeysByDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId) { if (deviceProfileId != null) { - return attributeKvRepository.findAllKeysByDeviceProfileId(tenantId.getId(), deviceProfileId.getId()); + return attributeKvRepository.findAllKeysByDeviceProfileId(tenantId.getId(), deviceProfileId.getId()) + .stream().map(this::getKey).collect(Collectors.toList()); } else { - return attributeKvRepository.findAllKeysByTenantId(tenantId.getId()); + return attributeKvRepository.findAllKeysByTenantId(tenantId.getId()) + .stream().map(this::getKey).collect(Collectors.toList()); } } @Override - public List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds) { + public List findAllKeysByEntityIds(TenantId tenantId, List entityIds) { return attributeKvRepository - .findAllKeysByEntityIds(entityType.name(), entityIds.stream().map(EntityId::getId).collect(Collectors.toList())); + .findAllKeysByEntityIds(entityIds.stream().map(EntityId::getId).collect(Collectors.toList())) + .stream().map(this::getKey).collect(Collectors.toList()); } @Override - public ListenableFuture save(TenantId tenantId, EntityId entityId, String attributeType, AttributeKvEntry attribute) { + public ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, AttributeKvEntry attribute) { AttributeKvEntity entity = new AttributeKvEntity(); - entity.setId(new AttributeKvCompositeKey(entityId.getEntityType(), entityId.getId(), attributeType, attribute.getKey())); + entity.setId(new AttributeKvCompositeKey(entityId.getId(), attributeScope.getId(), getOrSaveKeyId(attribute.getKey()))); entity.setLastUpdateTs(attribute.getLastUpdateTs()); entity.setStrValue(attribute.getStrValue().orElse(null)); entity.setDoubleValue(attribute.getDoubleValue().orElse(null)); entity.setLongValue(attribute.getLongValue().orElse(null)); entity.setBooleanValue(attribute.getBooleanValue().orElse(null)); entity.setJsonValue(attribute.getJsonValue().orElse(null)); - return addToQueue(entity); + return addToQueue(entity, attribute.getKey()); } - private ListenableFuture addToQueue(AttributeKvEntity entity) { - return Futures.transform(queue.add(entity), v -> entity.getId().getAttributeKey(), MoreExecutors.directExecutor()); + private ListenableFuture addToQueue(AttributeKvEntity entity, String key) { + return Futures.transform(queue.add(entity), v -> key, MoreExecutors.directExecutor()); } @Override - public List> removeAll(TenantId tenantId, EntityId entityId, String attributeType, List keys) { + public List> removeAll(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, List keys) { List> futuresList = new ArrayList<>(keys.size()); for (String key : keys) { futuresList.add(service.submit(() -> { - attributeKvRepository.delete(entityId.getEntityType(), entityId.getId(), attributeType, key); + attributeKvRepository.delete(entityId.getId(), attributeScope.getId(), getOrSaveKeyId(key)); return key; })); } return futuresList; } - private AttributeKvCompositeKey getAttributeKvCompositeKey(EntityId entityId, String attributeType, String attributeKey) { + private AttributeKvCompositeKey getAttributeKvCompositeKey(EntityId entityId, Integer attributeType, Integer attributeKey) { return new AttributeKvCompositeKey( - entityId.getEntityType(), entityId.getId(), attributeType, attributeKey); } + + private Integer getOrSaveKeyId(String attributeKey) { + Integer keyId = attributeDictionaryMap.get(attributeKey); + if (keyId == null) { + Optional byIdOptional = dictionaryRepository.findById(attributeKey); + if (byIdOptional.isEmpty()) { + attributeCreationLock.lock(); + try { + byIdOptional = dictionaryRepository.findById(attributeKey); + if (byIdOptional.isEmpty()) { + AttributeKvDictionary attributeKvDictionary = new AttributeKvDictionary(); + attributeKvDictionary.setKey(attributeKey); + try { + AttributeKvDictionary saved = dictionaryRepository.save(attributeKvDictionary); + attributeDictionaryMap.put(saved.getKey(), saved.getKeyId()); + keyId = saved.getKeyId(); + } catch (DataIntegrityViolationException | ConstraintViolationException e) { + byIdOptional = dictionaryRepository.findById(attributeKey); + AttributeKvDictionary dictionary = byIdOptional.orElseThrow(() -> new RuntimeException("Failed to get AttributeKvDictionary entity from DB!")); + attributeDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); + keyId = dictionary.getKeyId(); + } + } else { + keyId = byIdOptional.get().getKeyId(); + } + } finally { + attributeCreationLock.unlock(); + } + } else { + keyId = byIdOptional.get().getKeyId(); + attributeDictionaryMap.put(attributeKey, keyId); + } + } + return keyId; + } + private String getKey(Integer attributeKey) { + Optional byKeyId = dictionaryRepository.findByKeyId(attributeKey); + return byKeyId.map(AttributeKvDictionary::getKey).orElse(null); + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java index e9adae29ff..200e93765d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java @@ -16,7 +16,7 @@ package org.thingsboard.server.dao.sql.query; import lombok.Data; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.query.BooleanFilterPredicate; @@ -262,22 +262,22 @@ public class EntityKeyMapping { String query; if (!entityKey.getType().equals(EntityKeyType.ATTRIBUTE)) { String join = (hasFilter() && hasFilterValues(ctx)) ? "inner join" : "left join"; - query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key=:%s_key_id ", - join, alias, alias, alias, entityTypeStr, alias, alias); - String scope; + query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.attribute_key=(select key_id from attribute_kv_dictionary where key = :%s_key_id) ", + join, alias, alias, alias, alias); + int scope; if (entityKey.getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) { - scope = DataConstants.CLIENT_SCOPE; + scope = AttributeScope.CLIENT_SCOPE.getId(); } else if (entityKey.getType().equals(EntityKeyType.SHARED_ATTRIBUTE)) { - scope = DataConstants.SHARED_SCOPE; + scope = AttributeScope.SHARED_SCOPE.getId();; } else { - scope = DataConstants.SERVER_SCOPE; + scope = AttributeScope.SERVER_SCOPE.getId();; } - query = String.format("%s AND %s.attribute_type='%s' %s", query, alias, scope, filterQuery); + query = String.format("%s AND %s.attribute_type=%s %s", query, alias, scope, filterQuery); } else { String join = (hasFilter() && hasFilterValues(ctx)) ? "join LATERAL" : "left join LATERAL"; - query = String.format("%s (select * from attribute_kv %s WHERE %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key=:%s_key_id %s " + + query = String.format("%s (select * from attribute_kv %s WHERE %s.entity_id=entities.id AND %s.attribute_key=(select key_id from attribute_kv_dictionary where key = :%s_key_id) %s " + "ORDER BY %s.last_update_ts DESC limit 1) as %s ON true", - join, alias, alias, alias, entityTypeStr, alias, alias, filterQuery, alias, alias); + join, alias, alias, alias, alias, filterQuery, alias, alias); } return query; } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index 85b09e2053..f376a777d3 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -103,17 +103,22 @@ CREATE TABLE IF NOT EXISTS audit_log ( ) PARTITION BY RANGE (created_time); CREATE TABLE IF NOT EXISTS attribute_kv ( - entity_type varchar(255), entity_id uuid, - attribute_type varchar(255), - attribute_key varchar(255), + attribute_type int, + attribute_key int, bool_v boolean, str_v varchar(10000000), long_v bigint, dbl_v double precision, json_v json, last_update_ts bigint, - CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_type, entity_id, attribute_type, attribute_key) + CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_id, attribute_type, attribute_key) +); + +CREATE TABLE IF NOT EXISTS attribute_kv_dictionary ( + key varchar(255) NOT NULL, + key_id serial UNIQUE, + CONSTRAINT attribute_key_id_pkey PRIMARY KEY (key) ); CREATE TABLE IF NOT EXISTS component_descriptor ( diff --git a/dao/src/main/resources/sql/schema-timescale.sql b/dao/src/main/resources/sql/schema-timescale.sql index ed15566268..0a60b64a50 100644 --- a/dao/src/main/resources/sql/schema-timescale.sql +++ b/dao/src/main/resources/sql/schema-timescale.sql @@ -104,7 +104,7 @@ BEGIN WHILE FOUND LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', tenant_id_record, 'TTL') INTO tenant_ttl; if tenant_ttl IS NULL THEN tenant_ttl := system_ttl; @@ -122,7 +122,7 @@ BEGIN SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', customer_id_record, 'TTL') INTO customer_ttl; IF customer_ttl IS NULL THEN customer_ttl_ts := tenant_ttl_ts; diff --git a/dao/src/main/resources/sql/schema-ts-psql.sql b/dao/src/main/resources/sql/schema-ts-psql.sql index 8b2b80203e..3f8f380b03 100644 --- a/dao/src/main/resources/sql/schema-ts-psql.sql +++ b/dao/src/main/resources/sql/schema-ts-psql.sql @@ -272,7 +272,7 @@ BEGIN WHILE FOUND LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', tenant_id_record, 'TTL') INTO tenant_ttl; if tenant_ttl IS NULL THEN tenant_ttl := system_ttl; @@ -290,7 +290,7 @@ BEGIN SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = %L', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', customer_id_record, 'TTL') INTO customer_ttl; IF customer_ttl IS NULL THEN customer_ttl_ts := tenant_ttl_ts; diff --git a/dao/src/main/resources/sql/schema-views-and-functions.sql b/dao/src/main/resources/sql/schema-views-and-functions.sql index 1aa5647bde..4583b71e92 100644 --- a/dao/src/main/resources/sql/schema-views-and-functions.sql +++ b/dao/src/main/resources/sql/schema-views-and-functions.sql @@ -23,7 +23,7 @@ SELECT d.* , COALESCE(da.bool_v, FALSE) as active FROM device d LEFT JOIN customer c ON c.id = d.customer_id - LEFT JOIN attribute_kv da ON da.entity_type = 'DEVICE' AND da.entity_id = d.id AND da.attribute_type = 'SERVER_SCOPE' AND da.attribute_key = 'active'; + LEFT JOIN attribute_kv da ON da.entity_id = d.id AND da.attribute_type = 2 AND da.attribute_key = (select key_id from attribute_kv_dictionary where key = 'active'); DROP VIEW IF EXISTS device_info_active_ts_view CASCADE; CREATE OR REPLACE VIEW device_info_active_ts_view AS diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index ad23b7492b..1c798ea7de 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -29,6 +29,7 @@ import org.thingsboard.rule.engine.api.RuleEngineDeviceProfileCache; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; @@ -321,12 +322,13 @@ public class TbDeviceProfileNodeTest { device.setCustomerId(customerId); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "alarmEnabled" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); attributeKvEntity.setBooleanValue(Boolean.TRUE); + attributeKvEntity.setStrKey("alarmEnabled"); attributeKvEntity.setLastUpdateTs(System.currentTimeMillis()); AttributeKvEntry entry = attributeKvEntity.toData(); @@ -403,11 +405,12 @@ public class TbDeviceProfileNodeTest { device.setCustomerId(customerId); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, tenantId.getId(), "SERVER_SCOPE", "alarmEnabled" + tenantId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("alarmEnabled"); attributeKvEntity.setBooleanValue(Boolean.TRUE); attributeKvEntity.setLastUpdateTs(System.currentTimeMillis()); @@ -486,11 +489,12 @@ public class TbDeviceProfileNodeTest { DeviceProfileData deviceProfileData = new DeviceProfileData(); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "greaterAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("greaterAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); @@ -555,20 +559,22 @@ public class TbDeviceProfileNodeTest { DeviceProfileData deviceProfileData = new DeviceProfileData(); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "greaterAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("greaterAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); AttributeKvCompositeKey alarmDelayCompositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "alarm_delay" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 11 ); AttributeKvEntity alarmDelayAttributeKvEntity = new AttributeKvEntity(); alarmDelayAttributeKvEntity.setId(alarmDelayCompositeKey); + alarmDelayAttributeKvEntity.setStrKey("alarm_delay"); long alarmDelayInSeconds = 5L; alarmDelayAttributeKvEntity.setLongValue(alarmDelayInSeconds); alarmDelayAttributeKvEntity.setLastUpdateTs(0L); @@ -669,20 +675,22 @@ public class TbDeviceProfileNodeTest { AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "greaterAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("greaterAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); AttributeKvCompositeKey alarmDelayCompositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "alarm_delay" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 11 ); AttributeKvEntity alarmDelayAttributeKvEntity = new AttributeKvEntity(); alarmDelayAttributeKvEntity.setId(alarmDelayCompositeKey); + alarmDelayAttributeKvEntity.setStrKey("alarm_delay"); long alarmDelayInSeconds = 5L; alarmDelayAttributeKvEntity.setLongValue(alarmDelayInSeconds); alarmDelayAttributeKvEntity.setLastUpdateTs(0L); @@ -788,20 +796,22 @@ public class TbDeviceProfileNodeTest { DeviceProfileData deviceProfileData = new DeviceProfileData(); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "greaterAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("greaterAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); AttributeKvCompositeKey alarmDelayCompositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "alarm_delay" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 11 ); AttributeKvEntity alarmDelayAttributeKvEntity = new AttributeKvEntity(); alarmDelayAttributeKvEntity.setId(alarmDelayCompositeKey); + alarmDelayAttributeKvEntity.setStrKey("alarm_delay"); long alarmRepeating = 2; alarmDelayAttributeKvEntity.setLongValue(alarmRepeating); alarmDelayAttributeKvEntity.setLastUpdateTs(0L); @@ -891,7 +901,7 @@ public class TbDeviceProfileNodeTest { DeviceProfileData deviceProfileData = new DeviceProfileData(); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "greaterAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); Device device = new Device(); @@ -900,15 +910,17 @@ public class TbDeviceProfileNodeTest { AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("greaterAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); AttributeKvCompositeKey alarmDelayCompositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "alarm_delay" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 11 ); AttributeKvEntity alarmDelayAttributeKvEntity = new AttributeKvEntity(); alarmDelayAttributeKvEntity.setId(alarmDelayCompositeKey); + alarmDelayAttributeKvEntity.setStrKey("alarm_delay"); long repeatingCondition = 2; alarmDelayAttributeKvEntity.setLongValue(repeatingCondition); alarmDelayAttributeKvEntity.setLastUpdateTs(0L); @@ -1012,11 +1024,12 @@ public class TbDeviceProfileNodeTest { device.setCustomerId(customerId); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "greaterAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("greaterAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); @@ -1113,11 +1126,12 @@ public class TbDeviceProfileNodeTest { device.setCustomerId(customerId); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "greaterAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("greaterAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); @@ -1196,11 +1210,12 @@ public class TbDeviceProfileNodeTest { device.setCustomerId(customerId); AttributeKvCompositeKey compositeKeyActiveSchedule = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "dynamicValueActiveSchedule" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntityActiveSchedule = new AttributeKvEntity(); attributeKvEntityActiveSchedule.setId(compositeKeyActiveSchedule); + attributeKvEntityActiveSchedule.setStrKey("dynamicValueActiveSchedule"); attributeKvEntityActiveSchedule.setJsonValue( "{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":true,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":6,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":8.64e+7}],\"dynamicValue\":null}" ); @@ -1280,11 +1295,12 @@ public class TbDeviceProfileNodeTest { device.setCustomerId(customerId); AttributeKvCompositeKey compositeKeyInactiveSchedule = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "dynamicValueInactiveSchedule" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntityInactiveSchedule = new AttributeKvEntity(); attributeKvEntityInactiveSchedule.setId(compositeKeyInactiveSchedule); + attributeKvEntityInactiveSchedule.setStrKey("dynamicValueInactiveSchedule"); attributeKvEntityInactiveSchedule.setJsonValue( "{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":false,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":6,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":0}],\"dynamicValue\":null}" ); @@ -1372,11 +1388,12 @@ public class TbDeviceProfileNodeTest { device.setCustomerId(customerId); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.CUSTOMER, deviceId.getId(), "SERVER_SCOPE", "lessAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("lessAttribute"); attributeKvEntity.setLongValue(30L); attributeKvEntity.setLastUpdateTs(0L); @@ -1447,11 +1464,12 @@ public class TbDeviceProfileNodeTest { DeviceProfileData deviceProfileData = new DeviceProfileData(); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "lessAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("lessAttribute"); attributeKvEntity.setLongValue(50L); attributeKvEntity.setLastUpdateTs(0L); @@ -1520,7 +1538,7 @@ public class TbDeviceProfileNodeTest { DeviceProfileData deviceProfileData = new DeviceProfileData(); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "tenantAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); Device device = new Device(); @@ -1529,6 +1547,7 @@ public class TbDeviceProfileNodeTest { AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("tenantAttribute"); attributeKvEntity.setLongValue(100L); attributeKvEntity.setLastUpdateTs(0L); @@ -1605,7 +1624,7 @@ public class TbDeviceProfileNodeTest { DeviceProfileData deviceProfileData = new DeviceProfileData(); AttributeKvCompositeKey compositeKey = new AttributeKvCompositeKey( - EntityType.DEVICE, deviceId.getId(), EntityKeyType.SERVER_ATTRIBUTE.name(), "tenantAttribute" + deviceId.getId(), AttributeScope.SERVER_SCOPE.getId(), 10 ); Device device = new Device(); @@ -1614,6 +1633,7 @@ public class TbDeviceProfileNodeTest { AttributeKvEntity attributeKvEntity = new AttributeKvEntity(); attributeKvEntity.setId(compositeKey); + attributeKvEntity.setStrKey("tenantAttribute"); attributeKvEntity.setLongValue(100L); attributeKvEntity.setLastUpdateTs(0L); From e779c06ec1d39b27d6d3502aed468f5cf576aa9e Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Mon, 18 Dec 2023 14:20:29 +0200 Subject: [PATCH 45/61] changed AttributeService interface to accept AttributeScope instead of String --- .../3.6.2/schema_update_attribute_kv.sql | 26 ------ .../data/upgrade/3.6.2/schema_update_ttl.sql | 87 ------------------- .../device/DeviceActorMessageProcessor.java | 19 ++-- .../controller/TelemetryController.java | 86 +++++++++--------- .../install/ThingsboardInstallService.java | 3 - .../device/ClaimDevicesServiceImpl.java | 5 +- .../device/DeviceProvisionServiceImpl.java | 5 +- .../service/edge/rpc/EdgeGrpcSession.java | 5 +- .../telemetry/BaseTelemetryProcessor.java | 3 +- .../rpc/sync/DefaultEdgeRequestsService.java | 3 +- .../DefaultTbEntityViewService.java | 25 +++--- .../CassandraTsDatabaseUpgradeService.java | 1 - .../DefaultSystemDataLoaderService.java | 7 +- .../install/SqlDatabaseUpgradeService.java | 11 +-- .../query/DefaultEntityQueryService.java | 14 +-- .../state/DefaultDeviceStateService.java | 5 +- .../DefaultSubscriptionManagerService.java | 3 +- .../subscription/TbAbstractSubCtx.java | 3 +- .../impl/DefaultEntityExportService.java | 10 +-- .../DefaultTelemetrySubscriptionService.java | 5 +- .../service/ws/DefaultWebSocketService.java | 10 +-- ...AbstractRuleEngineFlowIntegrationTest.java | 9 +- ...actRuleEngineLifecycleIntegrationTest.java | 3 +- .../dao/attributes/AttributesService.java | 13 +-- .../importing/csv/BulkImportColumnType.java | 6 +- .../dao/attributes/AttributeCacheKey.java | 3 +- .../server/dao/attributes/AttributeUtils.java | 4 +- .../dao/attributes/BaseAttributesService.java | 24 ++--- .../attributes/CachedAttributesService.java | 28 +++--- ...y.java => AttributeKvDictionaryEntry.java} | 2 +- .../server/dao/service/Validator.java | 14 --- .../AttributeKvDictionaryRepository.java | 8 +- .../dao/sql/attributes/JpaAttributeDao.java | 16 ++-- .../sql/schema-views-and-functions.sql | 72 +++++++++++++++ .../server/dao/service/EntityServiceTest.java | 17 ++-- .../attributes/BaseAttributesServiceTest.java | 40 ++++----- .../edge/BaseTbMsgPushNodeConfiguration.java | 4 +- .../engine/geo/TbGpsGeofencingActionNode.java | 5 +- .../rule/engine/math/TbMathNode.java | 13 +-- .../metadata/TbAbstractGetAttributesNode.java | 13 +-- .../metadata/TbAbstractGetMappedDataNode.java | 4 +- .../rule/engine/profile/DeviceState.java | 7 +- .../profile/DynamicPredicateValueCtxImpl.java | 3 +- .../engine/telemetry/TbMsgAttributesNode.java | 3 +- .../rule/engine/math/TbMathNodeTest.java | 3 +- .../metadata/TbGetAttributesNodeTest.java | 7 +- .../TbGetCustomerAttributeNodeTest.java | 5 +- .../TbGetRelatedAttributeNodeTest.java | 5 +- .../TbGetTenantAttributeNodeTest.java | 5 +- .../profile/TbDeviceProfileNodeTest.java | 54 ++++++------ 50 files changed, 343 insertions(+), 383 deletions(-) delete mode 100644 application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql rename dao/src/main/java/org/thingsboard/server/dao/model/sql/{AttributeKvDictionary.java => AttributeKvDictionaryEntry.java} (96%) diff --git a/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql b/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql index 142b3c1844..8a13029310 100644 --- a/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql +++ b/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql @@ -136,32 +136,6 @@ EXCEPTION END $$; -CREATE OR REPLACE PROCEDURE recreate_device_info_active_attribute_view() - LANGUAGE plpgsql AS -$$ -BEGIN - DROP VIEW IF EXISTS device_info_active_attribute_view CASCADE; - CREATE OR REPLACE VIEW device_info_active_attribute_view AS - SELECT d.* - , c.title as customer_title - , COALESCE((c.additional_info::json->>'isPublic')::bool, FALSE) as customer_is_public - , d.type as device_profile_name - , COALESCE(da.bool_v, FALSE) as active - FROM device d - LEFT JOIN customer c ON c.id = d.customer_id - LEFT JOIN attribute_kv da ON da.entity_id = d.id AND da.attribute_type = 2 AND da.attribute_key = (select key_id from attribute_kv_dictionary where key = 'active'); -END; -$$; - -CREATE OR REPLACE PROCEDURE recreate_device_info_view() - LANGUAGE plpgsql AS -$$ -BEGIN - DROP VIEW IF EXISTS device_info_view CASCADE; - CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_attribute_view; -END; -$$; - CREATE OR REPLACE PROCEDURE drop_attribute_kv_old_table() LANGUAGE plpgsql AS $$ diff --git a/application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql b/application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql deleted file mode 100644 index 67ec25656e..0000000000 --- a/application/src/main/data/upgrade/3.6.2/schema_update_ttl.sql +++ /dev/null @@ -1,87 +0,0 @@ --- --- Copyright © 2016-2023 The Thingsboard Authors --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- - -CREATE OR REPLACE PROCEDURE cleanup_timeseries_by_ttl(IN null_uuid uuid, - IN system_ttl bigint, INOUT deleted bigint) - LANGUAGE plpgsql AS -$$ -DECLARE -tenant_cursor CURSOR FOR select tenant.id as tenant_id - from tenant; -tenant_id_record uuid; - customer_id_record uuid; - tenant_ttl bigint; - customer_ttl bigint; - deleted_for_entities bigint; - tenant_ttl_ts bigint; - customer_ttl_ts bigint; -BEGIN -OPEN tenant_cursor; -FETCH tenant_cursor INTO tenant_id_record; -WHILE FOUND - LOOP - EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', - tenant_id_record, 'TTL') INTO tenant_ttl; - if tenant_ttl IS NULL THEN - tenant_ttl := system_ttl; -END IF; - IF tenant_ttl > 0 THEN - tenant_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - tenant_ttl::bigint * 1000)::bigint; - deleted_for_entities := delete_device_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); - deleted := deleted + deleted_for_entities; - RAISE NOTICE '% telemetry removed for devices where tenant_id = %', deleted_for_entities, tenant_id_record; - deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); - deleted := deleted + deleted_for_entities; - RAISE NOTICE '% telemetry removed for assets where tenant_id = %', deleted_for_entities, tenant_id_record; -END IF; -FOR customer_id_record IN -SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record - LOOP - EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', - customer_id_record, 'TTL') INTO customer_ttl; -IF customer_ttl IS NULL THEN - customer_ttl_ts := tenant_ttl_ts; -ELSE - IF customer_ttl > 0 THEN - customer_ttl_ts := - (EXTRACT(EPOCH FROM current_timestamp) * 1000 - - customer_ttl::bigint * 1000)::bigint; -END IF; -END IF; - IF customer_ttl_ts IS NOT NULL AND customer_ttl_ts > 0 THEN - deleted_for_entities := - delete_customer_records_from_ts_kv(tenant_id_record, customer_id_record, - customer_ttl_ts); - deleted := deleted + deleted_for_entities; - RAISE NOTICE '% telemetry removed for customer with id = % where tenant_id = %', deleted_for_entities, customer_id_record, tenant_id_record; - deleted_for_entities := - delete_device_records_from_ts_kv(tenant_id_record, customer_id_record, - customer_ttl_ts); - deleted := deleted + deleted_for_entities; - RAISE NOTICE '% telemetry removed for devices where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; - deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, - customer_id_record, - customer_ttl_ts); - deleted := deleted + deleted_for_entities; - RAISE NOTICE '% telemetry removed for assets where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; -END IF; -END LOOP; -FETCH tenant_cursor INTO tenant_id_record; -END LOOP; -END -$$; \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 99e61ee8dc..be7dad7abc 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -32,6 +32,7 @@ import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActorCtx; import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EdgeUtils; @@ -501,7 +502,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso private void handleGetAttributesRequest(SessionInfoProto sessionInfo, GetAttributeRequestMsg request) { int requestId = request.getRequestId(); if (request.getOnlyShared()) { - Futures.addCallback(findAllAttributesByScope(DataConstants.SHARED_SCOPE), new FutureCallback<>() { + Futures.addCallback(findAllAttributesByScope(AttributeScope.SHARED_SCOPE), new FutureCallback<>() { @Override public void onSuccess(@Nullable List result) { GetAttributeResponseMsg responseMsg = GetAttributeResponseMsg.newBuilder() @@ -551,26 +552,26 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso ListenableFuture> clientAttributesFuture; ListenableFuture> sharedAttributesFuture; if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) { - clientAttributesFuture = findAllAttributesByScope(DataConstants.CLIENT_SCOPE); - sharedAttributesFuture = findAllAttributesByScope(DataConstants.SHARED_SCOPE); + clientAttributesFuture = findAllAttributesByScope(AttributeScope.CLIENT_SCOPE); + sharedAttributesFuture = findAllAttributesByScope(AttributeScope.SHARED_SCOPE); } else if (!CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) { - clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), DataConstants.CLIENT_SCOPE); - sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), DataConstants.SHARED_SCOPE); + clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), AttributeScope.CLIENT_SCOPE); + sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), AttributeScope.SHARED_SCOPE); } else if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) { clientAttributesFuture = Futures.immediateFuture(Collections.emptyList()); - sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), DataConstants.SHARED_SCOPE); + sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), AttributeScope.SHARED_SCOPE); } else { sharedAttributesFuture = Futures.immediateFuture(Collections.emptyList()); - clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), DataConstants.CLIENT_SCOPE); + clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), AttributeScope.CLIENT_SCOPE); } return Futures.allAsList(Arrays.asList(clientAttributesFuture, sharedAttributesFuture)); } - private ListenableFuture> findAllAttributesByScope(String scope) { + private ListenableFuture> findAllAttributesByScope(AttributeScope scope) { return systemContext.getAttributesService().findAll(tenantId, deviceId, scope); } - private ListenableFuture> findAttributesByScope(Set attributesSet, String scope) { + private ListenableFuture> findAttributesByScope(Set attributesSet, AttributeScope scope) { return systemContext.getAttributesService().find(tenantId, deviceId, scope, attributesSet); } diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 7056cab3f1..7033a9babc 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -51,7 +51,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; import org.thingsboard.server.common.adaptor.JsonConverter; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TenantProfile; @@ -198,7 +198,7 @@ public class TelemetryController extends BaseController { public DeferredResult getAttributeKeysByScope( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope") String scope) throws ThingsboardException { + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope") AttributeScope scope) throws ThingsboardException { return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope)); } @@ -240,7 +240,7 @@ public class TelemetryController extends BaseController { public DeferredResult getAttributesByScope( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope") String scope, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope") AttributeScope scope, @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION) @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.READ_ATTRIBUTES, entityType, entityIdStr, @@ -352,7 +352,7 @@ public class TelemetryController extends BaseController { @ResponseBody public DeferredResult saveDeviceAttributes( @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable("deviceId") String deviceIdStr, - @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope") String scope, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope") AttributeScope scope, @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true) @RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); return saveAttributes(getTenantId(), entityId, scope, request); @@ -376,7 +376,7 @@ public class TelemetryController extends BaseController { public DeferredResult saveEntityAttributesV1( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"})) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"})) @PathVariable("scope")AttributeScope scope, @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveAttributes(getTenantId(), entityId, scope, request); @@ -400,7 +400,7 @@ public class TelemetryController extends BaseController { public DeferredResult saveEntityAttributesV2( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE"}, required = true)) @PathVariable("scope")AttributeScope scope, @Parameter(description = ATTRIBUTES_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody JsonNode request) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveAttributes(getTenantId(), entityId, scope, request); @@ -425,7 +425,7 @@ public class TelemetryController extends BaseController { public DeferredResult saveEntityTelemetry( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")String scope, + @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")AttributeScope scope, @Parameter(description = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody String requestBody) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveTelemetry(getTenantId(), entityId, requestBody, 0L); @@ -450,7 +450,7 @@ public class TelemetryController extends BaseController { public DeferredResult saveEntityTelemetryWithTTL( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")String scope, + @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")AttributeScope scope, @Parameter(description = "A long value representing TTL (Time to Live) parameter.", required = true)@PathVariable("ttl")Long ttl, @Parameter(description = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody String requestBody) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); @@ -555,7 +555,7 @@ public class TelemetryController extends BaseController { @ResponseBody public DeferredResult deleteDeviceAttributes( @Parameter(description = DEVICE_ID_PARAM_DESCRIPTION, required = true) @PathVariable(DEVICE_ID) String deviceIdStr, - @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"}, required = true)) @PathVariable("scope")AttributeScope scope, @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION, required = true)@RequestParam(name = "keys")String keysStr) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); return deleteAttributes(entityId, scope, keysStr); @@ -579,49 +579,43 @@ public class TelemetryController extends BaseController { public DeferredResult deleteEntityAttributes( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope")String scope, + @Parameter(description = ATTRIBUTES_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = {"SERVER_SCOPE", "SHARED_SCOPE", "CLIENT_SCOPE"})) @PathVariable("scope")AttributeScope scope, @Parameter(description = ATTRIBUTES_KEYS_DESCRIPTION, required = true)@RequestParam(name = "keys")String keysStr) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return deleteAttributes(entityId, scope, keysStr); } - private DeferredResult deleteAttributes(EntityId entityIdSrc, String scope, String keysStr) throws ThingsboardException { + private DeferredResult deleteAttributes(EntityId entityIdSrc, AttributeScope scope, String keysStr) throws ThingsboardException { List keys = toKeysList(keysStr); if (keys.isEmpty()) { return getImmediateDeferredResult("Empty keys: " + keysStr, HttpStatus.BAD_REQUEST); } SecurityUser user = getCurrentUser(); - if (DataConstants.SERVER_SCOPE.equals(scope) || - DataConstants.SHARED_SCOPE.equals(scope) || - DataConstants.CLIENT_SCOPE.equals(scope)) { - return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_ATTRIBUTES, entityIdSrc, (result, tenantId, entityId) -> { - tsSubService.deleteAndNotify(tenantId, entityId, scope, keys, new FutureCallback() { - @Override - public void onSuccess(@Nullable Void tmp) { - logAttributesDeleted(user, entityId, scope, keys, null); - if (entityIdSrc.getEntityType().equals(EntityType.DEVICE)) { - DeviceId deviceId = new DeviceId(entityId.getId()); - tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete( - user.getTenantId(), deviceId, scope, keys), null); - } - result.setResult(new ResponseEntity<>(HttpStatus.OK)); + return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_ATTRIBUTES, entityIdSrc, (result, tenantId, entityId) -> { + tsSubService.deleteAndNotify(tenantId, entityId, scope.name(), keys, new FutureCallback() { + @Override + public void onSuccess(@Nullable Void tmp) { + logAttributesDeleted(user, entityId, scope, keys, null); + if (entityIdSrc.getEntityType().equals(EntityType.DEVICE)) { + DeviceId deviceId = new DeviceId(entityId.getId()); + tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete( + user.getTenantId(), deviceId, scope.name(), keys), null); } + result.setResult(new ResponseEntity<>(HttpStatus.OK)); + } - @Override - public void onFailure(Throwable t) { - logAttributesDeleted(user, entityId, scope, keys, t); - result.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); - } - }); + @Override + public void onFailure(Throwable t) { + logAttributesDeleted(user, entityId, scope, keys, t); + result.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); + } }); - } else { - return getImmediateDeferredResult("Invalid attribute scope: " + scope, HttpStatus.BAD_REQUEST); - } + }); } - private DeferredResult saveAttributes(TenantId srcTenantId, EntityId entityIdSrc, String scope, JsonNode json) throws ThingsboardException { - if (!DataConstants.SERVER_SCOPE.equals(scope) && !DataConstants.SHARED_SCOPE.equals(scope)) { + private DeferredResult saveAttributes(TenantId srcTenantId, EntityId entityIdSrc, AttributeScope scope, JsonNode json) throws ThingsboardException { + if (AttributeScope.SERVER_SCOPE != scope && AttributeScope.SHARED_SCOPE != scope) { return getImmediateDeferredResult("Invalid scope: " + scope, HttpStatus.BAD_REQUEST); } if (json.isObject()) { @@ -636,7 +630,7 @@ public class TelemetryController extends BaseController { } SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_ATTRIBUTES, entityIdSrc, (result, tenantId, entityId) -> { - tsSubService.saveAndNotify(tenantId, entityId, scope, attributes, new FutureCallback() { + tsSubService.saveAndNotify(tenantId, entityId, scope.name(), attributes, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { logAttributesUpdated(user, entityId, scope, attributes, null); @@ -710,10 +704,10 @@ public class TelemetryController extends BaseController { Futures.addCallback(future, getTsKvListCallback(result, useStrictDataTypes), MoreExecutors.directExecutor()); } - private void getAttributeValuesCallback(@Nullable DeferredResult result, SecurityUser user, EntityId entityId, String scope, String keys) { + private void getAttributeValuesCallback(@Nullable DeferredResult result, SecurityUser user, EntityId entityId, AttributeScope scope, String keys) { List keyList = toKeysList(keys); FutureCallback> callback = getAttributeValuesToResponseCallback(result, user, scope, entityId, keyList); - if (!StringUtils.isEmpty(scope)) { + if (scope != null) { if (keyList != null && !keyList.isEmpty()) { Futures.addCallback(attributesService.find(user.getTenantId(), entityId, scope, keyList), callback, MoreExecutors.directExecutor()); } else { @@ -721,7 +715,7 @@ public class TelemetryController extends BaseController { } } else { List>> futures = new ArrayList<>(); - for (String tmpScope : DataConstants.allScopes()) { + for (AttributeScope tmpScope : AttributeScope.values()) { if (keyList != null && !keyList.isEmpty()) { futures.add(attributesService.find(user.getTenantId(), entityId, tmpScope, keyList)); } else { @@ -735,13 +729,13 @@ public class TelemetryController extends BaseController { } } - private void getAttributeKeysCallback(@Nullable DeferredResult result, TenantId tenantId, EntityId entityId, String scope) { + private void getAttributeKeysCallback(@Nullable DeferredResult result, TenantId tenantId, EntityId entityId, AttributeScope scope) { Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), getAttributeKeysToResponseCallback(result), MoreExecutors.directExecutor()); } private void getAttributeKeysCallback(@Nullable DeferredResult result, TenantId tenantId, EntityId entityId) { List>> futures = new ArrayList<>(); - for (String scope : DataConstants.allScopes()) { + for (AttributeScope scope : AttributeScope.values()) { futures.add(attributesService.findAll(tenantId, entityId, scope)); } @@ -784,7 +778,7 @@ public class TelemetryController extends BaseController { } private FutureCallback> getAttributeValuesToResponseCallback(final DeferredResult response, - final SecurityUser user, final String scope, + final SecurityUser user, final AttributeScope scope, final EntityId entityId, final List keyList) { return new FutureCallback<>() { @Override @@ -835,18 +829,18 @@ public class TelemetryController extends BaseController { toException(e), telemetry); } - private void logAttributesDeleted(SecurityUser user, EntityId entityId, String scope, List keys, Throwable e) { + private void logAttributesDeleted(SecurityUser user, EntityId entityId, AttributeScope scope, List keys, Throwable e) { notificationEntityService.logEntityAction(user.getTenantId(), (UUIDBased & EntityId) entityId, ActionType.ATTRIBUTES_DELETED, user, toException(e), scope, keys); } - private void logAttributesUpdated(SecurityUser user, EntityId entityId, String scope, List attributes, Throwable e) { + private void logAttributesUpdated(SecurityUser user, EntityId entityId, AttributeScope scope, List attributes, Throwable e) { notificationEntityService.logEntityAction(user.getTenantId(), entityId, ActionType.ATTRIBUTES_UPDATED, user, toException(e), scope, attributes); } - private void logAttributesRead(SecurityUser user, EntityId entityId, String scope, List keys, Throwable e) { + private void logAttributesRead(SecurityUser user, EntityId entityId, AttributeScope scope, List keys, Throwable e) { notificationEntityService.logEntityAction(user.getTenantId(), entityId, ActionType.ATTRIBUTES_READ, user, toException(e), scope, keys); } diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index ac348c1249..f9fcf77001 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -267,9 +267,6 @@ public class ThingsboardInstallService { databaseEntitiesUpgradeService.upgradeDatabase("3.6.0"); case "3.6.2": log.info("Upgrading ThingsBoard from version 3.6.2 to 3.7.0 ..."); - if (databaseTsUpgradeService != null) { - databaseTsUpgradeService.upgradeDatabase("3.6.2"); - } databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; diff --git a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java index a4ba2c8311..08852be7fa 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java @@ -29,6 +29,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -100,7 +101,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { return Futures.immediateFailedFuture(new IllegalArgumentException()); } else { ListenableFuture> claimingAllowedFuture = attributesService.find(tenantId, device.getId(), - DataConstants.SERVER_SCOPE, Collections.singletonList(CLAIM_ATTRIBUTE_NAME)); + AttributeScope.SERVER_SCOPE, Collections.singletonList(CLAIM_ATTRIBUTE_NAME)); return Futures.transform(claimingAllowedFuture, list -> { if (list != null && !list.isEmpty()) { Optional claimingAllowedOptional = list.get(0).getBooleanValue(); @@ -123,7 +124,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { return Futures.immediateFuture(new ClaimDataInfo(true, key, claimDataFromCache)); } else { ListenableFuture> claimDataAttrFuture = attributesService.find(device.getTenantId(), device.getId(), - DataConstants.SERVER_SCOPE, CLAIM_DATA_ATTRIBUTE_NAME); + AttributeScope.SERVER_SCOPE, CLAIM_DATA_ATTRIBUTE_NAME); return Futures.transform(claimDataAttrFuture, claimDataAttr -> { if (claimDataAttr.isPresent()) { diff --git a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java index 763ce01116..c01c2330d2 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java @@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; @@ -189,7 +190,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { private ProvisionResponse processProvision(Device device, ProvisionRequest provisionRequest) { try { Optional provisionState = attributesService.find(device.getTenantId(), device.getId(), - DataConstants.SERVER_SCOPE, DEVICE_PROVISION_STATE).get(); + AttributeScope.SERVER_SCOPE, DEVICE_PROVISION_STATE).get(); if (provisionState != null && provisionState.isPresent() && !provisionState.get().getValueAsString().equals(PROVISIONED_STATE)) { notify(device, provisionRequest, TbMsgType.PROVISION_FAILURE, false); throw new ProvisionFailedException(ProvisionResponseStatus.FAILURE.name()); @@ -245,7 +246,7 @@ public class DeviceProvisionServiceImpl implements DeviceProvisionService { } private ListenableFuture> saveProvisionStateAttribute(Device device) { - return attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE, + return attributesService.save(device.getTenantId(), device.getId(), AttributeScope.SERVER_SCOPE, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry(DEVICE_PROVISION_STATE, PROVISIONED_STATE), System.currentTimeMillis()))); } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java index 59d744c3f1..003162816b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java @@ -25,6 +25,7 @@ import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.data.util.Pair; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.edge.Edge; @@ -543,7 +544,7 @@ public final class EdgeGrpcSession implements Closeable { private ListenableFuture> getQueueStartTsAndSeqId() { ListenableFuture> future = - ctx.getAttributesService().find(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, Arrays.asList(QUEUE_START_TS_ATTR_KEY, QUEUE_START_SEQ_ID_ATTR_KEY)); + ctx.getAttributesService().find(edge.getTenantId(), edge.getId(), AttributeScope.SERVER_SCOPE, Arrays.asList(QUEUE_START_TS_ATTR_KEY, QUEUE_START_SEQ_ID_ATTR_KEY)); return Futures.transform(future, attributeKvEntries -> { long startTs = 0L; long startSeqId = 0L; @@ -605,7 +606,7 @@ public final class EdgeGrpcSession implements Closeable { List attributes = Arrays.asList( new BaseAttributeKvEntry(new LongDataEntry(QUEUE_START_TS_ATTR_KEY, this.newStartTs), System.currentTimeMillis()), new BaseAttributeKvEntry(new LongDataEntry(QUEUE_START_SEQ_ID_ATTR_KEY, this.newStartSeqId), System.currentTimeMillis())); - return ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), DataConstants.SERVER_SCOPE, attributes); + return ctx.getAttributesService().save(edge.getTenantId(), edge.getId(), AttributeScope.SERVER_SCOPE, attributes); } private DownlinkMsg convertEntityEventToDownlink(EdgeEvent edgeEvent) { diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java index 2f4c3ff2d0..6641753ae5 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java @@ -30,6 +30,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; @@ -287,7 +288,7 @@ public abstract class BaseTelemetryProcessor extends BaseEdgeProcessor { String scope = attributeDeleteMsg.getScope(); List attributeKeys = attributeDeleteMsg.getAttributeNamesList(); - ListenableFuture> removeAllFuture = attributesService.removeAll(tenantId, entityId, scope, attributeKeys); + ListenableFuture> removeAllFuture = attributesService.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys); return Futures.transformAsync(removeAllFuture, removeAttributes -> { if (EntityType.DEVICE.name().equals(entityType)) { SettableFuture futureToSet = SettableFuture.create(); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java index 46bb940da9..71856ed61f 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/sync/DefaultEdgeRequestsService.java @@ -28,6 +28,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EdgeUtils; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; @@ -136,7 +137,7 @@ public class DefaultEdgeRequestsService implements EdgeRequestsService { return Futures.immediateFuture(null); } String scope = attributesRequestMsg.getScope(); - ListenableFuture> findAttrFuture = attributesService.findAll(tenantId, entityId, scope); + ListenableFuture> findAttrFuture = attributesService.findAll(tenantId, entityId, AttributeScope.valueOf(scope)); return Futures.transformAsync(findAttrFuture, ssAttributes -> processEntityAttributesAndAddToEdgeQueue(tenantId, entityId, edge, entityType, scope, ssAttributes, attributesRequestMsg), dbCallbackExecutorService); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java index d511d6d4e4..665735cc22 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java @@ -24,6 +24,7 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.ConcurrentReferenceHashMap; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; @@ -99,9 +100,9 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen if (oldEntityView != null) { if (oldEntityView.getKeys() != null && oldEntityView.getKeys().getAttributes() != null) { - futures.add(deleteAttributesFromEntityView(oldEntityView, DataConstants.CLIENT_SCOPE, oldEntityView.getKeys().getAttributes().getCs(), user)); - futures.add(deleteAttributesFromEntityView(oldEntityView, DataConstants.SERVER_SCOPE, oldEntityView.getKeys().getAttributes().getSs(), user)); - futures.add(deleteAttributesFromEntityView(oldEntityView, DataConstants.SHARED_SCOPE, oldEntityView.getKeys().getAttributes().getSh(), user)); + futures.add(deleteAttributesFromEntityView(oldEntityView, AttributeScope.CLIENT_SCOPE, oldEntityView.getKeys().getAttributes().getCs(), user)); + futures.add(deleteAttributesFromEntityView(oldEntityView, AttributeScope.SERVER_SCOPE, oldEntityView.getKeys().getAttributes().getSs(), user)); + futures.add(deleteAttributesFromEntityView(oldEntityView, AttributeScope.SHARED_SCOPE, oldEntityView.getKeys().getAttributes().getSh(), user)); } List tsKeys = oldEntityView.getKeys() != null && oldEntityView.getKeys().getTimeseries() != null ? oldEntityView.getKeys().getTimeseries() : Collections.emptyList(); @@ -109,9 +110,9 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen } if (savedEntityView.getKeys() != null) { if (savedEntityView.getKeys().getAttributes() != null) { - futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.CLIENT_SCOPE, savedEntityView.getKeys().getAttributes().getCs(), user)); - futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SERVER_SCOPE, savedEntityView.getKeys().getAttributes().getSs(), user)); - futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SHARED_SCOPE, savedEntityView.getKeys().getAttributes().getSh(), user)); + futures.add(copyAttributesFromEntityToEntityView(savedEntityView, AttributeScope.CLIENT_SCOPE, savedEntityView.getKeys().getAttributes().getCs(), user)); + futures.add(copyAttributesFromEntityToEntityView(savedEntityView, AttributeScope.SERVER_SCOPE, savedEntityView.getKeys().getAttributes().getSs(), user)); + futures.add(copyAttributesFromEntityToEntityView(savedEntityView, AttributeScope.SHARED_SCOPE, savedEntityView.getKeys().getAttributes().getSh(), user)); } futures.add(copyLatestFromEntityToEntityView(tenantId, savedEntityView)); } @@ -269,7 +270,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen } } - private ListenableFuture> copyAttributesFromEntityToEntityView(EntityView entityView, String scope, Collection keys, User user) throws ThingsboardException { + private ListenableFuture> copyAttributesFromEntityToEntityView(EntityView entityView, AttributeScope scope, Collection keys, User user) throws ThingsboardException { EntityViewId entityId = entityView.getId(); if (keys != null && !keys.isEmpty()) { ListenableFuture> getAttrFuture = attributesService.find(entityView.getTenantId(), entityView.getEntityId(), scope, keys); @@ -287,7 +288,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen (startTime == 0 && endTime > lastUpdateTs) || (startTime < lastUpdateTs && endTime > lastUpdateTs); }).collect(Collectors.toList()); - tsSubService.saveAndNotify(entityView.getTenantId(), entityId, scope, attributes, new FutureCallback() { + tsSubService.saveAndNotify(entityView.getTenantId(), entityId, scope.name(), attributes, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { try { @@ -351,11 +352,11 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen }, MoreExecutors.directExecutor()); } - private ListenableFuture deleteAttributesFromEntityView(EntityView entityView, String scope, List keys, User user) { + private ListenableFuture deleteAttributesFromEntityView(EntityView entityView, AttributeScope scope, List keys, User user) { EntityViewId entityId = entityView.getId(); SettableFuture resultFuture = SettableFuture.create(); if (keys != null && !keys.isEmpty()) { - tsSubService.deleteAndNotify(entityView.getTenantId(), entityId, scope, keys, new FutureCallback() { + tsSubService.deleteAndNotify(entityView.getTenantId(), entityId, scope.name(), keys, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { try { @@ -433,11 +434,11 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen return resultFuture; } - private void logAttributesUpdated(TenantId tenantId, User user, EntityId entityId, String scope, List attributes, Throwable e) throws ThingsboardException { + private void logAttributesUpdated(TenantId tenantId, User user, EntityId entityId, AttributeScope scope, List attributes, Throwable e) throws ThingsboardException { notificationEntityService.logEntityAction(tenantId, entityId, ActionType.ATTRIBUTES_UPDATED, user, toException(e), scope, attributes); } - private void logAttributesDeleted(TenantId tenantId, User user, EntityId entityId, String scope, List keys, Throwable e) throws ThingsboardException { + private void logAttributesDeleted(TenantId tenantId, User user, EntityId entityId, AttributeScope scope, List keys, Throwable e) throws ThingsboardException { notificationEntityService.logEntityAction(tenantId, entityId, ActionType.ATTRIBUTES_DELETED, user, toException(e), scope, keys); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java index 3e2f29440c..5c7c51eb2c 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/CassandraTsDatabaseUpgradeService.java @@ -52,7 +52,6 @@ public class CassandraTsDatabaseUpgradeService extends AbstractCassandraDatabase case "3.1.1": case "3.2.1": case "3.2.2": - case "3.6.2": break; default: throw new RuntimeException("Unable to upgrade Cassandra database, unsupported fromVersion: " + fromVersion); diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 54c6dab5e5..402236c8c6 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -32,6 +32,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.AdminSettings; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -469,7 +470,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { DeviceId t1Id = createDevice(demoTenant.getId(), null, savedThermostatDeviceProfile.getId(), "Thermostat T1", "T1_TEST_TOKEN", "Demo device for Thermostats dashboard").getId(); DeviceId t2Id = createDevice(demoTenant.getId(), null, savedThermostatDeviceProfile.getId(), "Thermostat T2", "T2_TEST_TOKEN", "Demo device for Thermostats dashboard").getId(); - attributesService.save(demoTenant.getId(), t1Id, DataConstants.SERVER_SCOPE, + attributesService.save(demoTenant.getId(), t1Id, AttributeScope.SERVER_SCOPE, Arrays.asList(new BaseAttributeKvEntry(System.currentTimeMillis(), new DoubleDataEntry("latitude", 37.3948)), new BaseAttributeKvEntry(System.currentTimeMillis(), new DoubleDataEntry("longitude", -122.1503)), new BaseAttributeKvEntry(System.currentTimeMillis(), new BooleanDataEntry("temperatureAlarmFlag", true)), @@ -477,7 +478,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { new BaseAttributeKvEntry(System.currentTimeMillis(), new LongDataEntry("temperatureAlarmThreshold", (long) 20)), new BaseAttributeKvEntry(System.currentTimeMillis(), new LongDataEntry("humidityAlarmThreshold", (long) 50)))); - attributesService.save(demoTenant.getId(), t2Id, DataConstants.SERVER_SCOPE, + attributesService.save(demoTenant.getId(), t2Id, AttributeScope.SERVER_SCOPE, Arrays.asList(new BaseAttributeKvEntry(System.currentTimeMillis(), new DoubleDataEntry("latitude", 37.493801)), new BaseAttributeKvEntry(System.currentTimeMillis(), new DoubleDataEntry("longitude", -121.948769)), new BaseAttributeKvEntry(System.currentTimeMillis(), new BooleanDataEntry("temperatureAlarmFlag", true)), @@ -586,7 +587,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value))), 0L); addTsCallback(saveFuture, new TelemetrySaveCallback<>(deviceId, key, value)); } else { - ListenableFuture> saveFuture = attributesService.save(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, + ListenableFuture> saveFuture = attributesService.save(TenantId.SYS_TENANT_ID, deviceId, AttributeScope.SERVER_SCOPE, Collections.singletonList(new BaseAttributeKvEntry(new BooleanDataEntry(key, value) , System.currentTimeMillis()))); addTsCallback(saveFuture, new TelemetrySaveCallback<>(deviceId, key, value)); diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 2983dea649..1a22b6e0e2 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -826,11 +826,9 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService executeQuery(conn, "CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc);"); // remove temp files - if (pathToTempAttributeKvFile.toFile().exists()) { - boolean deleteTsKvFile = pathToTempAttributeKvFile.toFile().delete(); - if (deleteTsKvFile) { - log.info("Successfully deleted the temp file for attribute_kv table upgrade!"); - } + boolean deleteTsKvFile = Files.deleteIfExists(pathToTempAttributeKvFile); + if (deleteTsKvFile) { + log.info("Successfully deleted the temp file for attribute_kv table upgrade!"); } executeQuery(conn, "UPDATE tb_schema_settings SET schema_version = 3007000;"); @@ -900,9 +898,8 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService Statement statement = conn.createStatement(); statement.execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script printWarnings(statement); - Thread.sleep(2000); log.info("Successfully executed query: {}", query); - } catch (InterruptedException | SQLException e) { + } catch (SQLException e) { log.error("Failed to execute query: {} due to: {}", query, e.getMessage()); throw new RuntimeException("Failed to execute query:" + query + " due to: ", e); } diff --git a/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java b/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java index 296c992ccf..22912ebe9e 100644 --- a/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java +++ b/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java @@ -31,6 +31,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.web.context.request.async.DeferredResult; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.KvUtil; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -154,7 +155,7 @@ public class DefaultEntityQueryService implements EntityQueryService { try { Optional valueOpt = attributesService.find(user.getTenantId(), entityId, - TbAttributeSubscriptionScope.SERVER_SCOPE.name(), dynamicValue.getSourceAttribute()).get(); + AttributeScope.SERVER_SCOPE, dynamicValue.getSourceAttribute()).get(); if (valueOpt.isPresent()) { AttributeKvEntry entry = valueOpt.get(); @@ -251,13 +252,14 @@ public class DefaultEntityQueryService implements EntityQueryService { } if (isAttributes) { - ListenableFuture> future; - future = dbCallbackExecutor.submit(() -> attributesService.findAllKeysByEntityIds(tenantId, ids)); - attributesKeysFuture = Futures.transform(future, list -> { - if (CollectionUtils.isEmpty(list)) { + Map> typesMap = ids.stream().collect(Collectors.groupingBy(EntityId::getEntityType)); + List>> futures = new ArrayList<>(typesMap.size()); + typesMap.forEach((type, entityIds) -> futures.add(dbCallbackExecutor.submit(() -> attributesService.findAllKeysByEntityIds(tenantId, entityIds)))); + attributesKeysFuture = Futures.transform(Futures.allAsList(futures), lists -> { + if (CollectionUtils.isEmpty(lists)) { return Collections.emptyList(); } - return list.stream().distinct().sorted().collect(Collectors.toList()); + return lists.stream().flatMap(List::stream).distinct().sorted().collect(Collectors.toList()); }, dbCallbackExecutor); } else { attributesKeysFuture = null; diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index 64df0b0a43..0affb51fc4 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -36,6 +36,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.ApiUsageRecordKey; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceIdInfo; import org.thingsboard.server.common.data.EntityType; @@ -585,7 +586,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService> tsData = tsService.findLatest(TenantId.SYS_TENANT_ID, device.getId(), PERSISTENT_ATTRIBUTES); future = Futures.transform(tsData, extractDeviceStateData(device), deviceStateExecutor); } else { - ListenableFuture> attrData = attributesService.find(TenantId.SYS_TENANT_ID, device.getId(), SERVER_SCOPE, PERSISTENT_ATTRIBUTES); + ListenableFuture> attrData = attributesService.find(TenantId.SYS_TENANT_ID, device.getId(), AttributeScope.SERVER_SCOPE, PERSISTENT_ATTRIBUTES); future = Futures.transform(attrData, extractDeviceStateData(device), deviceStateExecutor); } return transformInactivityTimeout(future); @@ -596,7 +597,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService { attributes.flatMap(KvEntry::getLongValue).ifPresent((inactivityTimeout) -> { if (inactivityTimeout > 0) { diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java index c3c050f73b..ed02fa4d06 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultSubscriptionManagerService.java @@ -23,6 +23,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.AlarmInfo; @@ -496,7 +497,7 @@ public class DefaultSubscriptionManagerService extends TbApplicationEventListene serviceId, subscription.getSessionId(), subscription.getSubscriptionId(), subscription.getEntityId()); final Map keyStates = subscription.getKeyStates(); - DonAsynchron.withCallback(attrService.find(subscription.getTenantId(), subscription.getEntityId(), DataConstants.CLIENT_SCOPE, keyStates.keySet()), values -> { + DonAsynchron.withCallback(attrService.find(subscription.getTenantId(), subscription.getEntityId(), AttributeScope.CLIENT_SCOPE, keyStates.keySet()), values -> { List missedUpdates = new ArrayList<>(); values.forEach(latestEntry -> { if (latestEntry.getLastUpdateTs() > keyStates.get(latestEntry.getKey())) { diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java index 7eba28bccd..b6046aef1d 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractSubCtx.java @@ -22,6 +22,7 @@ import lombok.Data; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -215,7 +216,7 @@ public abstract class TbAbstractSubCtx { private ListenableFuture resolveEntityValue(TenantId tenantId, EntityId entityId, DynamicValueKey key) { ListenableFuture> entry = attributesService.find(tenantId, entityId, - TbAttributeSubscriptionScope.SERVER_SCOPE.name(), key.getSourceAttribute()); + AttributeScope.SERVER_SCOPE, key.getSourceAttribute()); return Futures.transform(entry, attributeOpt -> { DynamicValueKeySub sub = new DynamicValueKeySub(key, entityId); if (attributeOpt.isPresent()) { diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/DefaultEntityExportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/DefaultEntityExportService.java index a9e0cf1166..1e079e0c0f 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/DefaultEntityExportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/exporting/impl/DefaultEntityExportService.java @@ -19,7 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.ExportableEntity; import org.thingsboard.server.common.data.exception.ThingsboardException; @@ -108,16 +108,16 @@ public class DefaultEntityExportService> exportAttributes(EntitiesExportCtx ctx, E entity) throws ThingsboardException { - List scopes; + List scopes; if (entity.getId().getEntityType() == EntityType.DEVICE) { - scopes = List.of(DataConstants.SERVER_SCOPE, DataConstants.SHARED_SCOPE); + scopes = List.of(AttributeScope.SERVER_SCOPE, AttributeScope.SHARED_SCOPE); } else { - scopes = Collections.singletonList(DataConstants.SERVER_SCOPE); + scopes = Collections.singletonList(AttributeScope.SERVER_SCOPE); } Map> attributes = new LinkedHashMap<>(); scopes.forEach(scope -> { try { - attributes.put(scope, attributesService.findAll(ctx.getTenantId(), entity.getId(), scope).get().stream() + attributes.put(scope.name(), attributesService.findAll(ctx.getTenantId(), entity.getId(), scope).get().stream() .map(attribute -> { AttributeExportData attributeExportData = new AttributeExportData(); attributeExportData.setKey(attribute.getKey()); diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java index d65896a9d8..5139a6ee65 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java @@ -26,6 +26,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.ApiUsageRecordKey; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.id.CustomerId; @@ -248,7 +249,7 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer @Override public void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List attributes, boolean notifyDevice, FutureCallback callback) { - ListenableFuture> saveFuture = attrService.save(tenantId, entityId, scope, attributes); + ListenableFuture> saveFuture = attrService.save(tenantId, entityId, AttributeScope.valueOf(scope), attributes); addVoidCallback(saveFuture, callback); addWsCallback(saveFuture, success -> onAttributesUpdate(tenantId, entityId, scope, attributes, notifyDevice)); } @@ -280,7 +281,7 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer @Override public void deleteAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List keys, boolean notifyDevice, FutureCallback callback) { - ListenableFuture> deleteFuture = attrService.removeAll(tenantId, entityId, scope, keys); + ListenableFuture> deleteFuture = attrService.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), keys); addVoidCallback(deleteFuture, callback); addWsCallback(deleteFuture, success -> onAttributesDelete(tenantId, entityId, scope, keys, notifyDevice)); } diff --git a/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java b/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java index 711a218f0e..6a8d41208d 100644 --- a/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java +++ b/application/src/main/java/org/thingsboard/server/service/ws/DefaultWebSocketService.java @@ -29,7 +29,7 @@ import org.springframework.web.socket.CloseStatus; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.common.util.ThingsBoardThreadFactory; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.id.CustomerId; @@ -949,7 +949,7 @@ public class DefaultWebSocketService implements WebSocketService { @Override public void onSuccess(@Nullable ValidationResult result) { List>> futures = new ArrayList<>(); - for (String scope : DataConstants.allScopes()) { + for (AttributeScope scope : AttributeScope.values()) { futures.add(attributesService.find(tenantId, entityId, scope, keys)); } @@ -968,7 +968,7 @@ public class DefaultWebSocketService implements WebSocketService { return new FutureCallback() { @Override public void onSuccess(@Nullable ValidationResult result) { - Futures.addCallback(attributesService.find(tenantId, entityId, scope, keys), callback, MoreExecutors.directExecutor()); + Futures.addCallback(attributesService.find(tenantId, entityId, AttributeScope.valueOf(scope), keys), callback, MoreExecutors.directExecutor()); } @Override @@ -983,7 +983,7 @@ public class DefaultWebSocketService implements WebSocketService { @Override public void onSuccess(@Nullable ValidationResult result) { List>> futures = new ArrayList<>(); - for (String scope : DataConstants.allScopes()) { + for (AttributeScope scope : AttributeScope.values()) { futures.add(attributesService.findAll(tenantId, entityId, scope)); } @@ -1002,7 +1002,7 @@ public class DefaultWebSocketService implements WebSocketService { return new FutureCallback() { @Override public void onSuccess(@Nullable ValidationResult result) { - Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), callback, MoreExecutors.directExecutor()); + Futures.addCallback(attributesService.findAll(tenantId, entityId, AttributeScope.valueOf(scope)), callback, MoreExecutors.directExecutor()); } @Override diff --git a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java index b86287c5d7..4cb36bb0a8 100644 --- a/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java @@ -31,6 +31,7 @@ import org.thingsboard.rule.engine.util.TbMsgSource; import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EventInfo; @@ -174,9 +175,9 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule device.setType("default"); device = doPost("/api/device", device, Device.class); - attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE, + attributesService.save(device.getTenantId(), device.getId(), AttributeScope.SERVER_SCOPE, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey1", "serverAttributeValue1"), System.currentTimeMillis()))).get(); - attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE, + attributesService.save(device.getTenantId(), device.getId(), AttributeScope.SERVER_SCOPE, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey2", "serverAttributeValue2"), System.currentTimeMillis()))).get(); TbMsgCallback tbMsgCallback = Mockito.mock(TbMsgCallback.class); @@ -299,9 +300,9 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule device.setType("default"); device = doPost("/api/device", device, Device.class); - attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE, + attributesService.save(device.getTenantId(), device.getId(), AttributeScope.SERVER_SCOPE, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey1", "serverAttributeValue1"), System.currentTimeMillis()))).get(); - attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE, + attributesService.save(device.getTenantId(), device.getId(), AttributeScope.SERVER_SCOPE, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey2", "serverAttributeValue2"), System.currentTimeMillis()))).get(); TbMsgCallback tbMsgCallback = Mockito.mock(TbMsgCallback.class); diff --git a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java index 9b05be4a05..fa909b20e4 100644 --- a/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java @@ -28,6 +28,7 @@ import org.thingsboard.rule.engine.util.TbMsgSource; import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; import org.thingsboard.server.actors.ActorSystemContext; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EventInfo; @@ -134,7 +135,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac device = doPost("/api/device", device, Device.class); log.warn("before update attr"); - attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE, + attributesService.save(device.getTenantId(), device.getId(), AttributeScope.SERVER_SCOPE, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey", "serverAttributeValue"), System.currentTimeMillis()))) .get(TIMEOUT, TimeUnit.SECONDS); log.warn("attr updated"); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java index de1386d0c6..ccbc90825a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao.attributes; import com.google.common.util.concurrent.ListenableFuture; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -30,17 +31,17 @@ import java.util.Optional; */ public interface AttributesService { - ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey); + ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, String attributeKey); - ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys); + ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, Collection attributeKeys); - ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope); + ListenableFuture> findAll(TenantId tenantId, EntityId entityId, AttributeScope scope); - ListenableFuture> save(TenantId tenantId, EntityId entityId, String scope, List attributes); + ListenableFuture> save(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes); - ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute); + ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope scope, AttributeKvEntry attribute); - ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys); + ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributeKeys); List findAllKeysByDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sync/ie/importing/csv/BulkImportColumnType.java b/common/data/src/main/java/org/thingsboard/server/common/data/sync/ie/importing/csv/BulkImportColumnType.java index 87582b4d6d..4890d902b6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sync/ie/importing/csv/BulkImportColumnType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sync/ie/importing/csv/BulkImportColumnType.java @@ -16,7 +16,7 @@ package org.thingsboard.server.common.data.sync.ie.importing.csv; import lombok.Getter; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; @Getter @@ -24,8 +24,8 @@ public enum BulkImportColumnType { NAME, TYPE, LABEL, - SHARED_ATTRIBUTE(DataConstants.SHARED_SCOPE, true), - SERVER_ATTRIBUTE(DataConstants.SERVER_SCOPE, true), + SHARED_ATTRIBUTE(AttributeScope.SHARED_SCOPE.name(), true), + SERVER_ATTRIBUTE(AttributeScope.SERVER_SCOPE.name(), true), TIMESERIES(true), ACCESS_TOKEN, X509, diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java index f3fd154b0e..6fa1a7840f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeCacheKey.java @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.attributes; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.EntityId; import java.io.Serializable; @@ -28,7 +29,7 @@ import java.io.Serializable; public class AttributeCacheKey implements Serializable { private static final long serialVersionUID = 2013369077925351881L; - private final String scope; + private final AttributeScope scope; private final EntityId entityId; private final String key; diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java index 29c44edd68..983661ff6e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java @@ -26,9 +26,9 @@ import java.util.List; public class AttributeUtils { - public static void validate(EntityId id, String scope) { + public static void validate(EntityId id, AttributeScope scope) { Validator.validateId(id.getId(), "Incorrect id " + id); - Validator.validateEnum(AttributeScope.class, scope, "Incorrect scope " + scope); + Validator.checkNotNull(scope, "Incorrect scope " + scope); } public static void validate(List kvEntries, boolean valueNoXssValidation) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java index 2defbd9398..3f8c88d609 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java @@ -54,23 +54,23 @@ public class BaseAttributesService implements AttributesService { } @Override - public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey) { + public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, String attributeKey) { validate(entityId, scope); Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey); - return Futures.immediateFuture(attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKey)); + return Futures.immediateFuture(attributesDao.find(tenantId, entityId, scope, attributeKey)); } @Override - public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys) { + public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, Collection attributeKeys) { validate(entityId, scope); attributeKeys.forEach(attributeKey -> Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey)); - return Futures.immediateFuture(attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys)); + return Futures.immediateFuture(attributesDao.find(tenantId, entityId, scope, attributeKeys)); } @Override - public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope) { + public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, AttributeScope scope) { validate(entityId, scope); - return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, AttributeScope.valueOf(scope))); + return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, scope)); } @Override @@ -84,23 +84,23 @@ public class BaseAttributesService implements AttributesService { } @Override - public ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute) { + public ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope scope, AttributeKvEntry attribute) { validate(entityId, scope); AttributeUtils.validate(attribute, valueNoXssValidation); - return attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); + return attributesDao.save(tenantId, entityId, scope, attribute); } @Override - public ListenableFuture> save(TenantId tenantId, EntityId entityId, String scope, List attributes) { + public ListenableFuture> save(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes) { validate(entityId, scope); AttributeUtils.validate(attributes, valueNoXssValidation); - List> saveFutures = attributes.stream().map(attribute -> attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute)).collect(Collectors.toList()); + List> saveFutures = attributes.stream().map(attribute -> attributesDao.save(tenantId, entityId, scope, attribute)).collect(Collectors.toList()); return Futures.allAsList(saveFutures); } @Override - public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys) { + public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributeKeys) { validate(entityId, scope); - return Futures.allAsList(attributesDao.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys)); + return Futures.allAsList(attributesDao.removeAll(tenantId, entityId, scope, attributeKeys)); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java index 327f6b5706..cd633462a3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java @@ -105,7 +105,7 @@ public class CachedAttributesService implements AttributesService { @Override - public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey) { + public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, String attributeKey) { validate(entityId, scope); Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey); @@ -120,7 +120,7 @@ public class CachedAttributesService implements AttributesService { return cacheExecutor.submit(() -> { var cacheTransaction = cache.newTransactionForKey(attributeCacheKey); try { - Optional result = attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKey); + Optional result = attributesDao.find(tenantId, entityId, scope, attributeKey); cacheTransaction.putIfAbsent(attributeCacheKey, result.orElse(null)); cacheTransaction.commit(); return result; @@ -134,7 +134,7 @@ public class CachedAttributesService implements AttributesService { } @Override - public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys) { + public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, Collection attributeKeys) { validate(entityId, scope); attributeKeys = new LinkedHashSet<>(attributeKeys); // deduplicate the attributes attributeKeys.forEach(attributeKey -> Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey)); @@ -159,7 +159,7 @@ public class CachedAttributesService implements AttributesService { var cacheTransaction = cache.newTransactionForKeys(notFoundKeys); try { log.trace("[{}][{}] Lookup attributes from db: {}", entityId, scope, notFoundAttributeKeys); - List result = attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), notFoundAttributeKeys); + List result = attributesDao.find(tenantId, entityId, scope, notFoundAttributeKeys); for (AttributeKvEntry foundInDbAttribute : result) { AttributeCacheKey attributeCacheKey = new AttributeCacheKey(scope, entityId, foundInDbAttribute.getKey()); cacheTransaction.putIfAbsent(attributeCacheKey, foundInDbAttribute); @@ -181,7 +181,7 @@ public class CachedAttributesService implements AttributesService { }); } - private Map> findCachedAttributes(EntityId entityId, String scope, Collection attributeKeys) { + private Map> findCachedAttributes(EntityId entityId, AttributeScope scope, Collection attributeKeys) { Map> cachedAttributes = new HashMap<>(); for (String attributeKey : attributeKeys) { var cachedAttributeValue = cache.get(new AttributeCacheKey(scope, entityId, attributeKey)); @@ -196,9 +196,9 @@ public class CachedAttributesService implements AttributesService { } @Override - public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope) { + public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, AttributeScope scope) { validate(entityId, scope); - return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, AttributeScope.valueOf(scope))); + return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, scope)); } @Override @@ -212,28 +212,28 @@ public class CachedAttributesService implements AttributesService { } @Override - public ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute) { + public ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope scope, AttributeKvEntry attribute) { validate(entityId, scope); AttributeUtils.validate(attribute, valueNoXssValidation); - ListenableFuture future = attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); + ListenableFuture future = attributesDao.save(tenantId, entityId, scope, attribute); return Futures.transform(future, key -> evict(entityId, scope, attribute, key), cacheExecutor); } @Override - public ListenableFuture> save(TenantId tenantId, EntityId entityId, String scope, List attributes) { + public ListenableFuture> save(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes) { validate(entityId, scope); AttributeUtils.validate(attributes, valueNoXssValidation); List> futures = new ArrayList<>(attributes.size()); for (var attribute : attributes) { - ListenableFuture future = attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); + ListenableFuture future = attributesDao.save(tenantId, entityId, scope, attribute); futures.add(Futures.transform(future, key -> evict(entityId, scope, attribute, key), cacheExecutor)); } return Futures.allAsList(futures); } - private String evict(EntityId entityId, String scope, AttributeKvEntry attribute, String key) { + private String evict(EntityId entityId, AttributeScope scope, AttributeKvEntry attribute, String key) { log.trace("[{}][{}][{}] Before cache evict: {}", entityId, scope, key, attribute); cache.evictOrPut(new AttributeCacheKey(scope, entityId, key), attribute); log.trace("[{}][{}][{}] after cache evict.", entityId, scope, key); @@ -241,9 +241,9 @@ public class CachedAttributesService implements AttributesService { } @Override - public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys) { + public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributeKeys) { validate(entityId, scope); - List> futures = attributesDao.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys); + List> futures = attributesDao.removeAll(tenantId, entityId, scope, attributeKeys); return Futures.allAsList(futures.stream().map(future -> Futures.transform(future, key -> { cache.evict(new AttributeCacheKey(scope, entityId, key)); return key; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionary.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionaryEntry.java similarity index 96% rename from dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionary.java rename to dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionaryEntry.java index 1cde08912e..98e3a0f5ab 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionary.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionaryEntry.java @@ -28,7 +28,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_ID_COLUMN; @Data @Entity @Table(name = "attribute_kv_dictionary") -public final class AttributeKvDictionary { +public final class AttributeKvDictionaryEntry { @Id @Column(name = KEY_COLUMN) diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index 5bf14d06ae..d8c4ffddc9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.service; -import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.StringUtils; import org.thingsboard.common.util.RegexUtils; import org.thingsboard.server.common.data.id.EntityId; @@ -60,19 +59,6 @@ public class Validator { } } - /** - * This method validate String string. If string is null or can not be cast to enum than throw - * IncorrectParameterException exception - * - * @param val the val - * @param errorMessage the error message for exception - */ - public static > void validateEnum(Class enumClass, String val, String errorMessage) { - if (val == null || !EnumUtils.isValidEnum(enumClass, val)) { - throw new IncorrectParameterException(errorMessage); - } - } - /** * This method validate long value. If value isn't possitive than throw diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java index 7af7df70ea..aa0ca5b8a5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java @@ -16,14 +16,12 @@ package org.thingsboard.server.dao.sql.attributes; import org.springframework.data.jpa.repository.JpaRepository; -import org.thingsboard.server.dao.model.sql.AttributeKvDictionary; -import org.thingsboard.server.dao.util.SqlTsOrTsLatestAnyDao; +import org.thingsboard.server.dao.model.sql.AttributeKvDictionaryEntry; import java.util.Optional; -@SqlTsOrTsLatestAnyDao -public interface AttributeKvDictionaryRepository extends JpaRepository { +public interface AttributeKvDictionaryRepository extends JpaRepository { - Optional findByKeyId(int keyId); + Optional findByKeyId(int keyId); } \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java index c47cd9dbdf..50ee8c462c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java @@ -36,7 +36,7 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.attributes.AttributesDao; import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; -import org.thingsboard.server.dao.model.sql.AttributeKvDictionary; +import org.thingsboard.server.dao.model.sql.AttributeKvDictionaryEntry; import org.thingsboard.server.dao.model.sql.AttributeKvEntity; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; @@ -215,21 +215,21 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl private Integer getOrSaveKeyId(String attributeKey) { Integer keyId = attributeDictionaryMap.get(attributeKey); if (keyId == null) { - Optional byIdOptional = dictionaryRepository.findById(attributeKey); + Optional byIdOptional = dictionaryRepository.findById(attributeKey); if (byIdOptional.isEmpty()) { attributeCreationLock.lock(); try { byIdOptional = dictionaryRepository.findById(attributeKey); if (byIdOptional.isEmpty()) { - AttributeKvDictionary attributeKvDictionary = new AttributeKvDictionary(); - attributeKvDictionary.setKey(attributeKey); + AttributeKvDictionaryEntry attributeKvDictionaryEntry = new AttributeKvDictionaryEntry(); + attributeKvDictionaryEntry.setKey(attributeKey); try { - AttributeKvDictionary saved = dictionaryRepository.save(attributeKvDictionary); + AttributeKvDictionaryEntry saved = dictionaryRepository.save(attributeKvDictionaryEntry); attributeDictionaryMap.put(saved.getKey(), saved.getKeyId()); keyId = saved.getKeyId(); } catch (DataIntegrityViolationException | ConstraintViolationException e) { byIdOptional = dictionaryRepository.findById(attributeKey); - AttributeKvDictionary dictionary = byIdOptional.orElseThrow(() -> new RuntimeException("Failed to get AttributeKvDictionary entity from DB!")); + AttributeKvDictionaryEntry dictionary = byIdOptional.orElseThrow(() -> new RuntimeException("Failed to get AttributeKvDictionary entity from DB!")); attributeDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); keyId = dictionary.getKeyId(); } @@ -247,7 +247,7 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl return keyId; } private String getKey(Integer attributeKey) { - Optional byKeyId = dictionaryRepository.findByKeyId(attributeKey); - return byKeyId.map(AttributeKvDictionary::getKey).orElse(null); + Optional byKeyId = dictionaryRepository.findByKeyId(attributeKey); + return byKeyId.map(AttributeKvDictionaryEntry::getKey).orElse(null); } } diff --git a/dao/src/main/resources/sql/schema-views-and-functions.sql b/dao/src/main/resources/sql/schema-views-and-functions.sql index 4583b71e92..4d684c6406 100644 --- a/dao/src/main/resources/sql/schema-views-and-functions.sql +++ b/dao/src/main/resources/sql/schema-views-and-functions.sql @@ -291,3 +291,75 @@ CREATE OR REPLACE VIEW widget_type_info_view AS SELECT t.* , COALESCE((t.descriptor::json->>'type')::text, '') as widget_type FROM widget_type t; + +CREATE OR REPLACE PROCEDURE cleanup_timeseries_by_ttl(IN null_uuid uuid, + IN system_ttl bigint, INOUT deleted bigint) + LANGUAGE plpgsql AS +$$ +DECLARE + tenant_cursor CURSOR FOR select tenant.id as tenant_id + from tenant; + tenant_id_record uuid; + customer_id_record uuid; + tenant_ttl bigint; + customer_ttl bigint; + deleted_for_entities bigint; + tenant_ttl_ts bigint; + customer_ttl_ts bigint; +BEGIN + OPEN tenant_cursor; + FETCH tenant_cursor INTO tenant_id_record; + WHILE FOUND + LOOP + EXECUTE format( + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + tenant_id_record, 'TTL') INTO tenant_ttl; + if tenant_ttl IS NULL THEN + tenant_ttl := system_ttl; + END IF; + IF tenant_ttl > 0 THEN + tenant_ttl_ts := (EXTRACT(EPOCH FROM current_timestamp) * 1000 - tenant_ttl::bigint * 1000)::bigint; + deleted_for_entities := delete_device_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for devices where tenant_id = %', deleted_for_entities, tenant_id_record; + deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, null_uuid, tenant_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for assets where tenant_id = %', deleted_for_entities, tenant_id_record; + END IF; + FOR customer_id_record IN + SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record + LOOP + EXECUTE format( + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + customer_id_record, 'TTL') INTO customer_ttl; + IF customer_ttl IS NULL THEN + customer_ttl_ts := tenant_ttl_ts; + ELSE + IF customer_ttl > 0 THEN + customer_ttl_ts := + (EXTRACT(EPOCH FROM current_timestamp) * 1000 - + customer_ttl::bigint * 1000)::bigint; + END IF; + END IF; + IF customer_ttl_ts IS NOT NULL AND customer_ttl_ts > 0 THEN + deleted_for_entities := + delete_customer_records_from_ts_kv(tenant_id_record, customer_id_record, + customer_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for customer with id = % where tenant_id = %', deleted_for_entities, customer_id_record, tenant_id_record; + deleted_for_entities := + delete_device_records_from_ts_kv(tenant_id_record, customer_id_record, + customer_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for devices where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; + deleted_for_entities := delete_asset_records_from_ts_kv(tenant_id_record, + customer_id_record, + customer_ttl_ts); + deleted := deleted + deleted_for_entities; + RAISE NOTICE '% telemetry removed for assets where tenant_id = % and customer_id = %', deleted_for_entities, tenant_id_record, customer_id_record; + END IF; + END LOOP; + FETCH tenant_cursor INTO tenant_id_record; + END LOOP; +END +$$; \ No newline at end of file diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java index f41e92a305..b3b56ffcba 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/EntityServiceTest.java @@ -25,6 +25,7 @@ import org.junit.Assert; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.ResultSetExtractor; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.EntityType; @@ -373,7 +374,7 @@ public class EntityServiceTest extends AbstractServiceTest { List>> attributeFutures = new ArrayList<>(); for (int i = 0; i < devices.size(); i++) { Device device = devices.get(i); - attributeFutures.add(saveLongAttribute(device.getId(), "temperature", temperatures.get(i), DataConstants.CLIENT_SCOPE)); + attributeFutures.add(saveLongAttribute(device.getId(), "temperature", temperatures.get(i), AttributeScope.CLIENT_SCOPE)); } Futures.allAsList(attributeFutures).get(); @@ -552,7 +553,7 @@ public class EntityServiceTest extends AbstractServiceTest { List>> attributeFutures = new ArrayList<>(); for (int i = 0; i < devices.size(); i++) { Device device = devices.get(i); - attributeFutures.add(saveLongAttribute(device.getId(), "temperature", temperatures.get(i), DataConstants.CLIENT_SCOPE)); + attributeFutures.add(saveLongAttribute(device.getId(), "temperature", temperatures.get(i), AttributeScope.CLIENT_SCOPE)); } Futures.allAsList(attributeFutures).get(); @@ -627,7 +628,7 @@ public class EntityServiceTest extends AbstractServiceTest { List>> attributeFutures = new ArrayList<>(); for (int i = 0; i < assets.size(); i++) { Asset asset = assets.get(i); - attributeFutures.add(saveLongAttribute(asset.getId(), "consumption", consumptions.get(i), DataConstants.SERVER_SCOPE)); + attributeFutures.add(saveLongAttribute(asset.getId(), "consumption", consumptions.get(i), AttributeScope.SERVER_SCOPE)); } Futures.allAsList(attributeFutures).get(); @@ -1436,7 +1437,7 @@ public class EntityServiceTest extends AbstractServiceTest { List>> attributeFutures = new ArrayList<>(); for (int i = 0; i < devices.size(); i++) { Device device = devices.get(i); - for (String currentScope : DataConstants.allScopes()) { + for (AttributeScope currentScope : AttributeScope.values()) { attributeFutures.add(saveLongAttribute(device.getId(), "temperature", temperatures.get(i), currentScope)); } } @@ -1538,7 +1539,7 @@ public class EntityServiceTest extends AbstractServiceTest { List>> attributeFutures = new ArrayList<>(); for (int i = 0; i < devices.size(); i++) { Device device = devices.get(i); - attributeFutures.add(saveLongAttribute(device.getId(), "temperature", temperatures.get(i), DataConstants.CLIENT_SCOPE)); + attributeFutures.add(saveLongAttribute(device.getId(), "temperature", temperatures.get(i), AttributeScope.CLIENT_SCOPE)); } Futures.allAsList(attributeFutures).get(); @@ -1816,7 +1817,7 @@ public class EntityServiceTest extends AbstractServiceTest { List>> attributeFutures = new ArrayList<>(); for (int i = 0; i < devices.size(); i++) { Device device = devices.get(i); - attributeFutures.add(saveStringAttribute(device.getId(), "attributeString", attributeStrings.get(i), DataConstants.CLIENT_SCOPE)); + attributeFutures.add(saveStringAttribute(device.getId(), "attributeString", attributeStrings.get(i), AttributeScope.CLIENT_SCOPE)); } Futures.allAsList(attributeFutures).get(); @@ -2149,13 +2150,13 @@ public class EntityServiceTest extends AbstractServiceTest { return filter; } - private ListenableFuture> saveLongAttribute(EntityId entityId, String key, long value, String scope) { + private ListenableFuture> saveLongAttribute(EntityId entityId, String key, long value, AttributeScope scope) { KvEntry attrValue = new LongDataEntry(key, value); AttributeKvEntry attr = new BaseAttributeKvEntry(attrValue, 42L); return attributesService.save(SYSTEM_TENANT_ID, entityId, scope, Collections.singletonList(attr)); } - private ListenableFuture> saveStringAttribute(EntityId entityId, String key, String value, String scope) { + private ListenableFuture> saveStringAttribute(EntityId entityId, String key, String value, AttributeScope scope) { KvEntry attrValue = new StringDataEntry(key, value); AttributeKvEntry attr = new BaseAttributeKvEntry(attrValue, 42L); return attributesService.save(SYSTEM_TENANT_ID, entityId, scope, Collections.singletonList(attr)); diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java index a863310b06..5bf8d24117 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/attributes/BaseAttributesServiceTest.java @@ -26,7 +26,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.thingsboard.server.cache.TbTransactionalCache; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -71,8 +71,8 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { DeviceId deviceId = new DeviceId(Uuids.timeBased()); KvEntry attrValue = new StringDataEntry("attribute1", "value1"); AttributeKvEntry attr = new BaseAttributeKvEntry(attrValue, 42L); - attributesService.save(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, Collections.singletonList(attr)).get(); - Optional saved = attributesService.find(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, attr.getKey()).get(); + attributesService.save(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, Collections.singletonList(attr)).get(); + Optional saved = attributesService.find(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, attr.getKey()).get(); Assert.assertTrue(saved.isPresent()); Assert.assertEquals(attr, saved.get()); } @@ -83,17 +83,17 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { KvEntry attrOldValue = new StringDataEntry("attribute1", "value1"); AttributeKvEntry attrOld = new BaseAttributeKvEntry(attrOldValue, 42L); - attributesService.save(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, Collections.singletonList(attrOld)).get(); - Optional saved = attributesService.find(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, attrOld.getKey()).get(); + attributesService.save(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, Collections.singletonList(attrOld)).get(); + Optional saved = attributesService.find(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, attrOld.getKey()).get(); Assert.assertTrue(saved.isPresent()); Assert.assertEquals(attrOld, saved.get()); KvEntry attrNewValue = new StringDataEntry("attribute1", "value2"); AttributeKvEntry attrNew = new BaseAttributeKvEntry(attrNewValue, 73L); - attributesService.save(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, Collections.singletonList(attrNew)).get(); + attributesService.save(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, Collections.singletonList(attrNew)).get(); - saved = attributesService.find(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, attrOld.getKey()).get(); + saved = attributesService.find(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, attrOld.getKey()).get(); Assert.assertEquals(attrNew, saved.get()); } @@ -108,11 +108,11 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { KvEntry attrBNewValue = new StringDataEntry("B", "value3"); AttributeKvEntry attrBNew = new BaseAttributeKvEntry(attrBNewValue, 73L); - attributesService.save(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, Collections.singletonList(attrAOld)).get(); - attributesService.save(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, Collections.singletonList(attrANew)).get(); - attributesService.save(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE, Collections.singletonList(attrBNew)).get(); + attributesService.save(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, Collections.singletonList(attrAOld)).get(); + attributesService.save(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, Collections.singletonList(attrANew)).get(); + attributesService.save(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE, Collections.singletonList(attrBNew)).get(); - List saved = attributesService.findAll(SYSTEM_TENANT_ID, deviceId, DataConstants.CLIENT_SCOPE).get(); + List saved = attributesService.findAll(SYSTEM_TENANT_ID, deviceId, AttributeScope.CLIENT_SCOPE).get(); Assert.assertNotNull(saved); Assert.assertEquals(2, saved.size()); @@ -123,7 +123,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { @Test public void testDummyRequestWithEmptyResult() throws Exception { - var future = attributesService.find(new TenantId(UUID.randomUUID()), new DeviceId(UUID.randomUUID()), DataConstants.SERVER_SCOPE, "TEST"); + var future = attributesService.find(new TenantId(UUID.randomUUID()), new DeviceId(UUID.randomUUID()), AttributeScope.SERVER_SCOPE, "TEST"); Assert.assertNotNull(future); var result = future.get(10, TimeUnit.SECONDS); Assert.assertTrue(result.isEmpty()); @@ -133,7 +133,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { public void testConcurrentTransaction() throws Exception { var tenantId = new TenantId(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); - var scope = DataConstants.SERVER_SCOPE; + var scope = AttributeScope.SERVER_SCOPE; var key = "TEST"; var attrKey = new AttributeCacheKey(scope, deviceId, "TEST"); @@ -179,7 +179,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { public void testFetchAndUpdateEmpty() throws Exception { var tenantId = new TenantId(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); - var scope = DataConstants.SERVER_SCOPE; + var scope = AttributeScope.SERVER_SCOPE; var key = "TEST"; Optional emptyValue = attributesService.find(tenantId, deviceId, scope, key).get(10, TimeUnit.SECONDS); @@ -193,7 +193,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { public void testFetchAndUpdateMulti() throws Exception { var tenantId = new TenantId(UUID.randomUUID()); var deviceId = new DeviceId(UUID.randomUUID()); - var scope = DataConstants.SERVER_SCOPE; + var scope = AttributeScope.SERVER_SCOPE; var key1 = "TEST1"; var key2 = "TEST2"; @@ -222,7 +222,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { } private void testConcurrentFetchAndUpdate(TenantId tenantId, DeviceId deviceId, ListeningExecutorService pool) throws Exception { - var scope = DataConstants.SERVER_SCOPE; + var scope = AttributeScope.SERVER_SCOPE; var key = "TEST"; saveAttribute(tenantId, deviceId, scope, key, OLD_VALUE); List> futures = new ArrayList<>(); @@ -236,7 +236,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { } private void testConcurrentFetchAndUpdateMulti(TenantId tenantId, DeviceId deviceId, ListeningExecutorService pool) throws Exception { - var scope = DataConstants.SERVER_SCOPE; + var scope = AttributeScope.SERVER_SCOPE; var key1 = "TEST1"; var key2 = "TEST2"; saveAttribute(tenantId, deviceId, scope, key1, OLD_VALUE); @@ -258,7 +258,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { Assert.assertEquals(NEW_VALUE, newResult.get(1)); } - private String getAttributeValue(TenantId tenantId, DeviceId deviceId, String scope, String key) { + private String getAttributeValue(TenantId tenantId, DeviceId deviceId, AttributeScope scope, String key) { try { Optional entry = attributesService.find(tenantId, deviceId, scope, key).get(10, TimeUnit.SECONDS); return entry.orElseThrow(RuntimeException::new).getStrValue().orElse("Unknown"); @@ -268,7 +268,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { } } - private List getAttributeValues(TenantId tenantId, DeviceId deviceId, String scope, List keys) { + private List getAttributeValues(TenantId tenantId, DeviceId deviceId, AttributeScope scope, List keys) { try { List entry = attributesService.find(tenantId, deviceId, scope, keys).get(10, TimeUnit.SECONDS); return entry.stream().map(e -> e.getStrValue().orElse(null)).collect(Collectors.toList()); @@ -278,7 +278,7 @@ public abstract class BaseAttributesServiceTest extends AbstractServiceTest { } } - private void saveAttribute(TenantId tenantId, DeviceId deviceId, String scope, String key, String s) { + private void saveAttribute(TenantId tenantId, DeviceId deviceId, AttributeScope scope, String key, String s) { try { AttributeKvEntry newEntry = new BaseAttributeKvEntry(System.currentTimeMillis(), new StringDataEntry(key, s)); attributesService.save(tenantId, deviceId, scope, Collections.singletonList(newEntry)).get(10, TimeUnit.SECONDS); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/BaseTbMsgPushNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/BaseTbMsgPushNodeConfiguration.java index 64f80a7b9a..ffa1d0ff06 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/BaseTbMsgPushNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/edge/BaseTbMsgPushNodeConfiguration.java @@ -17,7 +17,7 @@ package org.thingsboard.rule.engine.edge; import lombok.Data; import org.thingsboard.rule.engine.api.NodeConfiguration; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; @Data public class BaseTbMsgPushNodeConfiguration implements NodeConfiguration { @@ -27,7 +27,7 @@ public class BaseTbMsgPushNodeConfiguration implements NodeConfiguration { try { Optional entry = ctx.getAttributesService() - .find(ctx.getTenantId(), msg.getOriginator(), DataConstants.SERVER_SCOPE, ctx.getServiceId()) + .find(ctx.getTenantId(), msg.getOriginator(), AttributeScope.SERVER_SCOPE, ctx.getServiceId()) .get(1, TimeUnit.MINUTES); if (entry.isPresent()) { JsonObject element = parser.parse(entry.get().getValueAsString()).getAsJsonObject(); @@ -120,7 +121,7 @@ public class TbGpsGeofencingActionNode extends AbstractGeofencingNode attributeKvEntryList = Collections.singletonList(entry); - ctx.getAttributesService().save(ctx.getTenantId(), entityId, DataConstants.SERVER_SCOPE, attributeKvEntryList); + ctx.getAttributesService().save(ctx.getTenantId(), entityId, AttributeScope.SERVER_SCOPE, attributeKvEntryList); } @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java index 095612b4e1..455e5c8da7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java @@ -33,6 +33,7 @@ import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.EntityId; @@ -208,15 +209,15 @@ public class TbMathNode implements TbNode { } private ListenableFuture saveAttribute(TbContext ctx, TbMsg msg, double result, TbMathResult mathResultDef) { - String attributeScope = getAttributeScope(mathResultDef.getAttributeScope()); + AttributeScope attributeScope = getAttributeScope(mathResultDef.getAttributeScope()); if (isIntegerResult(mathResultDef, config.getOperation())) { var value = toIntValue(result); return ctx.getTelemetryService().saveAttrAndNotify( - ctx.getTenantId(), msg.getOriginator(), attributeScope, mathResultDef.getKey(), value); + ctx.getTenantId(), msg.getOriginator(), attributeScope.name(), mathResultDef.getKey(), value); } else { var value = toDoubleValue(mathResultDef, result); return ctx.getTelemetryService().saveAttrAndNotify( - ctx.getTenantId(), msg.getOriginator(), attributeScope, mathResultDef.getKey(), value); + ctx.getTenantId(), msg.getOriginator(), attributeScope.name(), mathResultDef.getKey(), value); } } @@ -384,7 +385,7 @@ public class TbMathNode implements TbNode { case MESSAGE_METADATA: return Futures.immediateFuture(TbMathArgumentValue.fromMessageMetadata(arg, argKey, msg.getMetaData())); case ATTRIBUTE: - String scope = getAttributeScope(arg.getAttributeScope()); + AttributeScope scope = getAttributeScope(arg.getAttributeScope()); return Futures.transform(ctx.getAttributesService().find(ctx.getTenantId(), msg.getOriginator(), scope, argKey), opt -> getTbMathArgumentValue(arg, opt, "Attribute: " + argKey + " with scope: " + scope + " not found for entity: " + msg.getOriginator()) , MoreExecutors.directExecutor()); @@ -402,8 +403,8 @@ public class TbMathNode implements TbNode { return CONSTANT.equals(type) ? keyPattern : TbNodeUtils.processPattern(keyPattern, msg); } - private String getAttributeScope(String attrScope) { - return StringUtils.isEmpty(attrScope) ? DataConstants.SERVER_SCOPE : attrScope; + private AttributeScope getAttributeScope(String attrScope) { + return StringUtils.isEmpty(attrScope) ? AttributeScope.SERVER_SCOPE : AttributeScope.valueOf(attrScope); } private TbMathArgumentValue getTbMathArgumentValue(TbMathArgument arg, Optional kvOpt, String error) { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java index 50d71f88a0..bb17f61f75 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java @@ -29,6 +29,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.TbMsgSource; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; @@ -100,9 +101,9 @@ public abstract class TbAbstractGetAttributesNode>> failuresPairSet = ConcurrentHashMap.newKeySet(); var getKvEntryPairFutures = Futures.allAsList( getLatestTelemetry(ctx, entityId, TbNodeUtils.processPatterns(config.getLatestTsKeyNames(), msg), failuresPairSet), - getAttrAsync(ctx, entityId, CLIENT_SCOPE, TbNodeUtils.processPatterns(config.getClientAttributeNames(), msg), failuresPairSet), - getAttrAsync(ctx, entityId, SHARED_SCOPE, TbNodeUtils.processPatterns(config.getSharedAttributeNames(), msg), failuresPairSet), - getAttrAsync(ctx, entityId, SERVER_SCOPE, TbNodeUtils.processPatterns(config.getServerAttributeNames(), msg), failuresPairSet) + getAttrAsync(ctx, entityId, AttributeScope.CLIENT_SCOPE, TbNodeUtils.processPatterns(config.getClientAttributeNames(), msg), failuresPairSet), + getAttrAsync(ctx, entityId, AttributeScope.SHARED_SCOPE, TbNodeUtils.processPatterns(config.getSharedAttributeNames(), msg), failuresPairSet), + getAttrAsync(ctx, entityId, AttributeScope.SERVER_SCOPE, TbNodeUtils.processPatterns(config.getServerAttributeNames(), msg), failuresPairSet) ); withCallback(getKvEntryPairFutures, futuresList -> { var msgMetaData = msg.getMetaData().copy(); @@ -127,7 +128,7 @@ public abstract class TbAbstractGetAttributesNode>> getAttrAsync( TbContext ctx, EntityId entityId, - String scope, + AttributeScope scope, List keys, Set>> failuresPairSet ) { @@ -138,9 +139,9 @@ public abstract class TbAbstractGetAttributesNode { if (isTellFailureIfAbsent && attributeKvEntryList.size() != keys.size()) { List nonExistentKeys = getNonExistentKeys(attributeKvEntryList, keys); - failuresPairSet.add(new TbPair<>(scope, nonExistentKeys)); + failuresPairSet.add(new TbPair<>(scope.name(), nonExistentKeys)); } - return new TbPair<>(scope, attributeKvEntryList); + return new TbPair<>(scope.name(), attributeKvEntryList); }, ctx.getDbCallbackExecutor()); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java index 8362918e6d..1fd8832525 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetMappedDataNode.java @@ -25,6 +25,7 @@ import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.rule.engine.util.EntitiesFieldsAsyncLoader; import org.thingsboard.rule.engine.util.TbMsgSource; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.msg.TbMsg; @@ -36,7 +37,6 @@ import java.util.Map; import java.util.stream.Collectors; import static org.thingsboard.common.util.DonAsynchron.withCallback; -import static org.thingsboard.server.common.data.DataConstants.SERVER_SCOPE; @Slf4j public abstract class TbAbstractGetMappedDataNode extends TbAbstractNodeWithFetchTo { @@ -134,7 +134,7 @@ public abstract class TbAbstractGetMappedDataNode> getAttributesAsync(TbContext ctx, EntityId entityId, List attrKeys) { - var latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, attrKeys); + var latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, AttributeScope.SERVER_SCOPE, attrKeys); return Futures.transform(latest, l -> l.stream() .map(i -> (KvEntry) i) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java index b38fd29af7..73a4cc1fcd 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DeviceState.java @@ -21,6 +21,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.profile.state.PersistedAlarmState; import org.thingsboard.rule.engine.profile.state.PersistedDeviceState; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; @@ -382,9 +383,9 @@ class DeviceState { } } if (!attributeKeys.isEmpty()) { - addToSnapshot(result, ctx.getAttributesService().find(ctx.getTenantId(), originator, DataConstants.CLIENT_SCOPE, attributeKeys).get()); - addToSnapshot(result, ctx.getAttributesService().find(ctx.getTenantId(), originator, DataConstants.SHARED_SCOPE, attributeKeys).get()); - addToSnapshot(result, ctx.getAttributesService().find(ctx.getTenantId(), originator, DataConstants.SERVER_SCOPE, attributeKeys).get()); + addToSnapshot(result, ctx.getAttributesService().find(ctx.getTenantId(), originator, AttributeScope.CLIENT_SCOPE, attributeKeys).get()); + addToSnapshot(result, ctx.getAttributesService().find(ctx.getTenantId(), originator, AttributeScope.SHARED_SCOPE, attributeKeys).get()); + addToSnapshot(result, ctx.getAttributesService().find(ctx.getTenantId(), originator, AttributeScope.SERVER_SCOPE, attributeKeys).get()); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DynamicPredicateValueCtxImpl.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DynamicPredicateValueCtxImpl.java index 93ee38992f..111861ad34 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DynamicPredicateValueCtxImpl.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/DynamicPredicateValueCtxImpl.java @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.profile; import lombok.extern.slf4j.Slf4j; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.id.CustomerId; @@ -62,7 +63,7 @@ public class DynamicPredicateValueCtxImpl implements DynamicPredicateValueCtx { private EntityKeyValue getValue(EntityId entityId, String key) { try { - Optional entry = ctx.getAttributesService().find(tenantId, entityId, DataConstants.SERVER_SCOPE, key).get(); + Optional entry = ctx.getAttributesService().find(tenantId, entityId, AttributeScope.SERVER_SCOPE, key).get(); if (entry.isPresent()) { return DeviceState.toEntityValue(entry.get()); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 06498241fb..10c3a0c5db 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -28,6 +28,7 @@ import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.KvEntry; @@ -96,7 +97,7 @@ public class TbMsgAttributesNode implements TbNode { } List keys = newAttributes.stream().map(KvEntry::getKey).collect(Collectors.toList()); - ListenableFuture> findFuture = ctx.getAttributesService().find(ctx.getTenantId(), msg.getOriginator(), scope, keys); + ListenableFuture> findFuture = ctx.getAttributesService().find(ctx.getTenantId(), msg.getOriginator(), AttributeScope.valueOf(scope), keys); DonAsynchron.withCallback(findFuture, currentAttributes -> { diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java index 9eec38cfae..8ee70f23d7 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java @@ -39,6 +39,7 @@ import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; @@ -365,7 +366,7 @@ public class TbMathNodeTest { TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, originator, TbMsgMetaData.EMPTY, JacksonUtil.newObjectNode().toString()); - when(attributesService.find(tenantId, originator, DataConstants.SERVER_SCOPE, "a")) + when(attributesService.find(tenantId, originator, AttributeScope.SERVER_SCOPE, "a")) .thenReturn(Futures.immediateFuture(Optional.of(new BaseAttributeKvEntry(System.currentTimeMillis(), new DoubleDataEntry("a", 2.0))))); when(tsService.findLatest(tenantId, originator, "b")) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java index 1b8c95ab22..ebbaf90bf6 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNodeTest.java @@ -32,6 +32,7 @@ import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.util.TbMsgSource; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EntityId; @@ -106,13 +107,13 @@ public class TbGetAttributesNodeTest { tsKeys = List.of("temperature", "humidity", "unknown"); ts = System.currentTimeMillis(); - when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, DataConstants.CLIENT_SCOPE, clientAttributes)) + when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, AttributeScope.CLIENT_SCOPE, clientAttributes)) .thenReturn(Futures.immediateFuture(getListAttributeKvEntry(clientAttributes, ts))); - when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, DataConstants.SERVER_SCOPE, serverAttributes)) + when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, AttributeScope.SERVER_SCOPE, serverAttributes)) .thenReturn(Futures.immediateFuture(getListAttributeKvEntry(serverAttributes, ts))); - when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, DataConstants.SHARED_SCOPE, sharedAttributes)) + when(attributesServiceMock.find(TENANT_ID, ORIGINATOR, AttributeScope.SHARED_SCOPE, sharedAttributes)) .thenReturn(Futures.immediateFuture(getListAttributeKvEntry(sharedAttributes, ts))); when(timeseriesServiceMock.findLatest(TENANT_ID, ORIGINATOR, tsKeys)) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java index 291614464a..247d1d76bd 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java @@ -33,6 +33,7 @@ import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.util.TbMsgSource; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; @@ -277,7 +278,7 @@ public class TbGetCustomerAttributeNodeTest { doReturn(device).when(deviceServiceMock).findDeviceById(eq(TENANT_ID), eq(device.getId())); when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); - when(attributesServiceMock.find(eq(TENANT_ID), eq(CUSTOMER_ID), eq(DataConstants.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) + when(attributesServiceMock.find(eq(TENANT_ID), eq(CUSTOMER_ID), eq(AttributeScope.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) .thenReturn(Futures.immediateFuture(attributesList)); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); @@ -324,7 +325,7 @@ public class TbGetCustomerAttributeNodeTest { doReturn(Futures.immediateFuture(user)).when(userServiceMock).findUserByIdAsync(eq(TENANT_ID), eq(user.getId())); when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); - when(attributesServiceMock.find(eq(TENANT_ID), eq(CUSTOMER_ID), eq(DataConstants.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) + when(attributesServiceMock.find(eq(TENANT_ID), eq(CUSTOMER_ID), eq(AttributeScope.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) .thenReturn(Futures.immediateFuture(attributesList)); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java index dcf5c22ea5..216c5cf1cb 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetRelatedAttributeNodeTest.java @@ -34,6 +34,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.data.RelationsQuery; import org.thingsboard.rule.engine.util.TbMsgSource; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.DataConstants; @@ -291,7 +292,7 @@ public class TbGetRelatedAttributeNodeTest { doReturn(Futures.immediateFuture(List.of(entityRelation))).when(relationServiceMock).findByQuery(eq(TENANT_ID), any()); when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); - when(attributesServiceMock.find(eq(TENANT_ID), eq(user.getId()), eq(DataConstants.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) + when(attributesServiceMock.find(eq(TENANT_ID), eq(user.getId()), eq(AttributeScope.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) .thenReturn(Futures.immediateFuture(attributes)); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); @@ -342,7 +343,7 @@ public class TbGetRelatedAttributeNodeTest { doReturn(Futures.immediateFuture(List.of(entityRelation))).when(relationServiceMock).findByQuery(eq(TENANT_ID), any()); when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); - when(attributesServiceMock.find(eq(TENANT_ID), eq(secondCustomer.getId()), eq(DataConstants.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) + when(attributesServiceMock.find(eq(TENANT_ID), eq(secondCustomer.getId()), eq(AttributeScope.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) .thenReturn(Futures.immediateFuture(attributes)); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java index 87b34cffe0..8fb36f810b 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetTenantAttributeNodeTest.java @@ -32,6 +32,7 @@ import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.util.TbMsgSource; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; @@ -216,7 +217,7 @@ public class TbGetTenantAttributeNodeTest { when(ctxMock.getTenantId()).thenReturn(TENANT_ID); when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); - when(attributesServiceMock.find(eq(TENANT_ID), eq(TENANT_ID), eq(DataConstants.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) + when(attributesServiceMock.find(eq(TENANT_ID), eq(TENANT_ID), eq(AttributeScope.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) .thenReturn(Futures.immediateFuture(attributesList)); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); @@ -257,7 +258,7 @@ public class TbGetTenantAttributeNodeTest { when(ctxMock.getTenantId()).thenReturn(TENANT_ID); when(ctxMock.getAttributesService()).thenReturn(attributesServiceMock); - when(attributesServiceMock.find(eq(TENANT_ID), eq(TENANT_ID), eq(DataConstants.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) + when(attributesServiceMock.find(eq(TENANT_ID), eq(TENANT_ID), eq(AttributeScope.SERVER_SCOPE), argThat(new ListMatcher<>(expectedPatternProcessedKeysList)))) .thenReturn(Futures.immediateFuture(attributesList)); when(ctxMock.getDbCallbackExecutor()).thenReturn(DB_EXECUTOR); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index 1c798ea7de..0b94f07255 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -374,7 +374,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(attrListListenableFuture); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -458,11 +458,11 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(Futures.immediateFuture(Collections.emptyList())); - Mockito.when(attributesService.find(eq(tenantId), eq(customerId), Mockito.anyString(), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(customerId), Mockito.any(AttributeScope.class), Mockito.anyString())) .thenReturn(Futures.immediateFuture(Optional.empty())); - Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), Mockito.anyString(), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), Mockito.any(AttributeScope.class), Mockito.anyString())) .thenReturn(attrListListenableFuture); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -532,7 +532,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFutureWithLess); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -628,7 +628,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFuture); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -748,13 +748,13 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), Mockito.anyString(), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), Mockito.any(AttributeScope.class), Mockito.anyString())) .thenReturn(optionalDurationAttribute); Mockito.when(ctx.getDeviceService().findDeviceById(tenantId, deviceId)) .thenReturn(device); - Mockito.when(attributesService.find(eq(tenantId), eq(customerId), eq(DataConstants.SERVER_SCOPE), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(customerId), eq(AttributeScope.SERVER_SCOPE), Mockito.anyString())) .thenReturn(emptyOptional); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listNoDurationAttribute); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -865,7 +865,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFuture); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -977,13 +977,13 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), Mockito.anyString(), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), Mockito.any(AttributeScope.class), Mockito.anyString())) .thenReturn(optionalDurationAttribute); Mockito.when(ctx.getDeviceService().findDeviceById(tenantId, deviceId)) .thenReturn(device); - Mockito.when(attributesService.find(eq(tenantId), eq(customerId), eq(DataConstants.SERVER_SCOPE), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(customerId), eq(AttributeScope.SERVER_SCOPE), Mockito.anyString())) .thenReturn(emptyOptional); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listNoDurationAttribute); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1080,7 +1080,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFuture); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1179,7 +1179,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFuture); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1262,7 +1262,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFutureActiveSchedule); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1359,7 +1359,7 @@ public class TbDeviceProfileNodeTest { Mockito.when(alarmService.findLatestActiveByOriginatorAndType(tenantId, deviceId, "highTemperatureAlarm")) .thenReturn(null); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFutureInactiveSchedule); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1434,11 +1434,11 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFutureWithLess); Mockito.when(ctx.getDeviceService().findDeviceById(tenantId, deviceId)) .thenReturn(device); - Mockito.when(attributesService.find(eq(tenantId), eq(customerId), eq(DataConstants.SERVER_SCOPE), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(customerId), eq(AttributeScope.SERVER_SCOPE), Mockito.anyString())) .thenReturn(optionalListenableFutureWithLess); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1510,9 +1510,9 @@ public class TbDeviceProfileNodeTest { .thenReturn(null); registerCreateAlarmMock(alarmService.createAlarm(any()), true); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFutureWithLess); - Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), eq(DataConstants.SERVER_SCOPE), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), eq(AttributeScope.SERVER_SCOPE), Mockito.anyString())) .thenReturn(optionalListenableFutureWithLess); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1592,11 +1592,11 @@ public class TbDeviceProfileNodeTest { Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); Mockito.when(ctx.getDeviceService().findDeviceById(tenantId, deviceId)) .thenReturn(device); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFutureWithLess); - Mockito.when(attributesService.find(eq(tenantId), eq(customerId), Mockito.anyString(), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(customerId), Mockito.any(AttributeScope.class), Mockito.anyString())) .thenReturn(emptyOptionalFuture); - Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), eq(DataConstants.SERVER_SCOPE), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), eq(AttributeScope.SERVER_SCOPE), Mockito.anyString())) .thenReturn(optionalListenableFutureWithLess); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); @@ -1678,11 +1678,11 @@ public class TbDeviceProfileNodeTest { Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); Mockito.when(ctx.getDeviceService().findDeviceById(tenantId, deviceId)) .thenReturn(device); - Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.any(AttributeScope.class), Mockito.anySet())) .thenReturn(listListenableFutureWithLess); - Mockito.when(attributesService.find(eq(tenantId), eq(customerId), Mockito.anyString(), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(customerId), Mockito.any(AttributeScope.class), Mockito.anyString())) .thenReturn(emptyOptionalFuture); - Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), eq(DataConstants.SERVER_SCOPE), Mockito.anyString())) + Mockito.when(attributesService.find(eq(tenantId), eq(tenantId), eq(AttributeScope.SERVER_SCOPE), Mockito.anyString())) .thenReturn(optionalListenableFutureWithLess); TbMsg theMsg = TbMsg.newMsg(TbMsgType.ALARM, deviceId, TbMsgMetaData.EMPTY, TbMsg.EMPTY_STRING); From c7e06ec97e15b78d72a04b2a9d080b69c81afd79 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 20 Dec 2023 15:45:27 +0200 Subject: [PATCH 46/61] fixed TelemetryConrollerTest --- .../org/thingsboard/server/controller/TelemetryController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index 7033a9babc..91e5010888 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -425,7 +425,7 @@ public class TelemetryController extends BaseController { public DeferredResult saveEntityTelemetry( @Parameter(description = ENTITY_TYPE_PARAM_DESCRIPTION, required = true, schema = @Schema(defaultValue = "DEVICE")) @PathVariable("entityType") String entityType, @Parameter(description = ENTITY_ID_PARAM_DESCRIPTION, required = true) @PathVariable("entityId") String entityIdStr, - @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")AttributeScope scope, + @Parameter(description = TELEMETRY_SCOPE_DESCRIPTION, required = true, schema = @Schema(allowableValues = "ANY")) @PathVariable("scope")String scope, @Parameter(description = TELEMETRY_JSON_REQUEST_DESCRIPTION, required = true)@RequestBody String requestBody) throws ThingsboardException { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); return saveTelemetry(getTenantId(), entityId, requestBody, 0L); From 1fc704bae1ac2c8cbbc7a7bd486017171f764dd0 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 26 Dec 2023 11:08:06 +0100 Subject: [PATCH 47/61] test fixes and minor refactoring --- .../thingsboard/server/queue/pubsub/TbPubSubSettings.java | 2 +- .../java/org/thingsboard/script/api/tbel/TbDateTest.java | 2 +- pom.xml | 5 ----- .../org/thingsboard/rule/engine/rest/TbHttpClient.java | 2 +- .../rule/engine/profile/TbDeviceProfileNodeTest.java | 8 ++++---- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java b/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java index a0bd43c80f..b77fdec5aa 100644 --- a/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java +++ b/common/queue/src/main/java/org/thingsboard/server/queue/pubsub/TbPubSubSettings.java @@ -27,7 +27,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.common.util.ThingsBoardThreadFactory; import jakarta.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PreDestroy; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.concurrent.Executors; diff --git a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java index e8701be3ce..4988243a53 100644 --- a/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java +++ b/common/script/script-api/src/test/java/org/thingsboard/script/api/tbel/TbDateTest.java @@ -832,4 +832,4 @@ class TbDateTest { Assert.assertNotNull(serializedTbDate); Assert.assertEquals(expectedDate.toString(), serializedTbDate); } -} \ No newline at end of file +} diff --git a/pom.xml b/pom.xml index a5e05f695c..1204d02abf 100755 --- a/pom.xml +++ b/pom.xml @@ -1971,11 +1971,6 @@ hibernate-validator ${hibernate-validator.version} - - io.hypersistence - hypersistence-utils-hibernate-55 - ${hypersistence-utils.version} - io.hypersistence hypersistence-utils-hibernate-62 diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java index 6085abd859..4f1784d79a 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/rest/TbHttpClient.java @@ -393,4 +393,4 @@ public class TbHttpClient { } } -} \ No newline at end of file +} diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index ad23b7492b..0c60c3f975 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -211,7 +211,7 @@ public class TbDeviceProfileNodeTest { registerCreateAlarmMock(alarmService.updateAlarm(any()), false); - + Thread.sleep(1); TbMsg msg2 = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, deviceId, TbMsgMetaData.EMPTY, TbMsgDataType.JSON, JacksonUtil.toString(data), null, null); node.onMsg(ctx, msg2); @@ -644,7 +644,7 @@ public class TbDeviceProfileNodeTest { verify(ctx, Mockito.never()).tellNext(theMsg, "Alarm Created"); - Thread.sleep(halfOfAlarmDelay); + Thread.sleep(halfOfAlarmDelay + 1); TbMsg msg2 = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, deviceId, TbMsgMetaData.EMPTY, TbMsgDataType.JSON, JacksonUtil.toString(data), null, null); @@ -768,7 +768,7 @@ public class TbDeviceProfileNodeTest { verify(ctx, Mockito.never()).tellNext(theMsg, "Alarm Created"); - Thread.sleep(halfOfAlarmDelay); + Thread.sleep(halfOfAlarmDelay + 1); TbMsg msg2 = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, deviceId, TbMsgMetaData.EMPTY, TbMsgDataType.JSON, JacksonUtil.toString(data), null, null); @@ -1089,7 +1089,7 @@ public class TbDeviceProfileNodeTest { verify(ctx, Mockito.never()).tellNext(theMsg, "Alarm Created"); - Thread.sleep(halfOfAlarmDelay); + Thread.sleep(halfOfAlarmDelay + 1); TbMsg msg2 = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, deviceId, TbMsgMetaData.EMPTY, TbMsgDataType.JSON, JacksonUtil.toString(data), null, null); From c92a7ecf3a5d18b2f56c14a984ebe8e2bf7cf31e Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 2 Jan 2024 17:46:29 +0200 Subject: [PATCH 48/61] deleted attribute_kv_dictionary table (used ts_kv_dictionary instead), renamed ts_kv_dictionary to key_dictionary --- .../schema_update_attribute_kv.sql | 27 +++++++----- .../install/ThingsboardInstallService.java | 6 +-- .../install/SqlDatabaseUpgradeService.java | 6 +-- .../CassandraTsLatestToSqlMigrateService.java | 24 +++++------ .../model/sql/AttributeKvDictionaryEntry.java | 41 ------------------- ...ey.java => KeyDictionaryCompositeKey.java} | 2 +- ...ictionary.java => KeyDictionaryEntry.java} | 6 +-- .../AttributeKvDictionaryRepository.java | 27 ------------ .../dao/sql/attributes/JpaAttributeDao.java | 22 +++++----- .../dao/sql/query/EntityKeyMapping.java | 6 +-- .../sqlts/BaseAbstractSqlTimeseriesDao.java | 24 +++++------ ...tory.java => KeyDictionaryRepository.java} | 11 +++-- .../latest/SearchTsKvLatestRepository.java | 4 +- .../sqlts/latest/TsKvLatestRepository.java | 18 ++++---- .../main/resources/sql/schema-entities.sql | 10 +---- .../main/resources/sql/schema-timescale.sql | 6 +-- dao/src/main/resources/sql/schema-ts-psql.sql | 12 +++--- .../sql/schema-views-and-functions.sql | 8 ++-- .../profile/TbDeviceProfileNodeTest.java | 3 -- .../tools/migrator/DictionaryParser.java | 2 +- 20 files changed, 97 insertions(+), 168 deletions(-) rename application/src/main/data/upgrade/{3.6.2 => 3.6.3}/schema_update_attribute_kv.sql (88%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionaryEntry.java rename dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/{TsKvDictionaryCompositeKey.java => KeyDictionaryCompositeKey.java} (93%) rename dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/{TsKvDictionary.java => KeyDictionaryEntry.java} (91%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java rename dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/{TsKvDictionaryRepository.java => KeyDictionaryRepository.java} (65%) diff --git a/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql b/application/src/main/data/upgrade/3.6.3/schema_update_attribute_kv.sql similarity index 88% rename from application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql rename to application/src/main/data/upgrade/3.6.3/schema_update_attribute_kv.sql index 8a13029310..509a94bf20 100644 --- a/application/src/main/data/upgrade/3.6.2/schema_update_attribute_kv.sql +++ b/application/src/main/data/upgrade/3.6.3/schema_update_attribute_kv.sql @@ -46,13 +46,18 @@ $$ END; $$; --- create attribute_kv_dictionary table -CREATE TABLE IF NOT EXISTS attribute_kv_dictionary -( - key varchar(255) NOT NULL, - key_id serial UNIQUE, - CONSTRAINT attribute_key_id_pkey PRIMARY KEY (key) -); +-- rename ts_kv_dictionary table to key_dictionary +DO +$$ + BEGIN + IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'ts_kv_dictionary') THEN + ALTER TABLE ts_kv_dictionary + RENAME CONSTRAINT ts_key_id_pkey TO key_id_pkey; + ALTER TABLE ts_kv_dictionary + RENAME TO key_dictionary; + END IF; + END; +$$; -- create to_attribute_type_id CREATE OR REPLACE FUNCTION to_attribute_type_id(IN attribute_type varchar, OUT attribute_type_id int) AS @@ -70,7 +75,7 @@ END; $$ LANGUAGE plpgsql; --- insert keys into attribute_kv_dictionary +-- insert keys into key_dictionary DO $$ DECLARE @@ -84,8 +89,8 @@ BEGIN LOOP FETCH key_cursor INTO insert_record; EXIT WHEN NOT FOUND; - IF NOT EXISTS(SELECT key FROM attribute_kv_dictionary WHERE key = insert_record.attribute_key) THEN - INSERT INTO attribute_kv_dictionary(key) VALUES (insert_record.attribute_key); + IF NOT EXISTS(SELECT key FROM key_dictionary WHERE key = insert_record.attribute_key) THEN + INSERT INTO key_dictionary(key) VALUES (insert_record.attribute_key); END IF; END LOOP; CLOSE key_cursor; @@ -122,7 +127,7 @@ BEGIN dbl_v, json_v, last_update_ts - FROM attribute_kv_old INNER JOIN attribute_kv_dictionary ON (attribute_kv_old.attribute_key = attribute_kv_dictionary.key) + FROM attribute_kv_old INNER JOIN key_dictionary ON (attribute_kv_old.attribute_key = key_dictionary.key) WHERE attribute_type= ANY(%L)) AS records) TO %L;', attribute_scope_array, path_to_file); EXECUTE format('COPY attribute_kv FROM %L', path_to_file); SELECT COUNT(*) INTO row_num_old FROM attribute_kv_old; diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index f9fcf77001..383d22c21f 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -265,9 +265,9 @@ public class ThingsboardInstallService { case "3.6.0": log.info("Upgrading ThingsBoard from version 3.6.0 to 3.6.1 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.6.0"); - case "3.6.2": - log.info("Upgrading ThingsBoard from version 3.6.2 to 3.7.0 ..."); - databaseEntitiesUpgradeService.upgradeDatabase("3.6.2"); + case "3.6.3": + log.info("Upgrading ThingsBoard from version 3.6.3 to 3.7.0 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.6.3"); //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache break; default: diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 1a22b6e0e2..1ad5c9afe4 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -799,11 +799,11 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService log.error("Failed updating schema!!!", e); } break; - case "3.6.2": + case "3.6.3": try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { - if (isOldSchema(conn, 3006002)) { + if (isOldSchema(conn, 3006003)) { log.info("Updating schema ..."); - schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.6.2", LOAD_ATTRIBUTE_KV_FUNCTIONS_SQL); + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.6.3", LOAD_ATTRIBUTE_KV_FUNCTIONS_SQL); loadSql(schemaUpdateFile, conn); Path pathToTempAttributeKvFile; diff --git a/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java b/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java index 4357e6be63..083d513e6d 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraTsLatestToSqlMigrateService.java @@ -24,10 +24,10 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.UUIDConverter; import org.thingsboard.server.dao.cassandra.CassandraCluster; -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary; -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; -import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository; +import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository; import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository; import org.thingsboard.server.dao.util.NoSqlTsDao; import org.thingsboard.server.dao.util.SqlTsLatestDao; @@ -71,7 +71,7 @@ public class CassandraTsLatestToSqlMigrateService implements TsLatestMigrateServ protected CassandraCluster cluster; @Autowired - protected TsKvDictionaryRepository dictionaryRepository; + protected KeyDictionaryRepository dictionaryRepository; @Autowired private InstallScripts installScripts; @@ -192,22 +192,22 @@ public class CassandraTsLatestToSqlMigrateService implements TsLatestMigrateServ Integer keyId = tsKvDictionaryMap.get(strKey); if (keyId == null) { - Optional tsKvDictionaryOptional; - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); + Optional tsKvDictionaryOptional; + tsKvDictionaryOptional = dictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); if (!tsKvDictionaryOptional.isPresent()) { tsCreationLock.lock(); try { - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); + tsKvDictionaryOptional = dictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); if (!tsKvDictionaryOptional.isPresent()) { - TsKvDictionary tsKvDictionary = new TsKvDictionary(); - tsKvDictionary.setKey(strKey); + KeyDictionaryEntry keyDictionaryEntry = new KeyDictionaryEntry(); + keyDictionaryEntry.setKey(strKey); try { - TsKvDictionary saved = dictionaryRepository.save(tsKvDictionary); + KeyDictionaryEntry saved = dictionaryRepository.save(keyDictionaryEntry); tsKvDictionaryMap.put(saved.getKey(), saved.getKeyId()); keyId = saved.getKeyId(); } catch (ConstraintViolationException e) { - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); - TsKvDictionary dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!")); + tsKvDictionaryOptional = dictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + KeyDictionaryEntry dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!")); tsKvDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); keyId = dictionary.getKeyId(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionaryEntry.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionaryEntry.java deleted file mode 100644 index 98e3a0f5ab..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AttributeKvDictionaryEntry.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.model.sql; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import lombok.Data; -import org.hibernate.annotations.Generated; - -import static org.thingsboard.server.dao.model.ModelConstants.KEY_COLUMN; -import static org.thingsboard.server.dao.model.ModelConstants.KEY_ID_COLUMN; - -@Data -@Entity -@Table(name = "attribute_kv_dictionary") -public final class AttributeKvDictionaryEntry { - - @Id - @Column(name = KEY_COLUMN) - private String key; - - @Column(name = KEY_ID_COLUMN, unique = true, columnDefinition="int") - @Generated - private int keyId; - -} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionaryCompositeKey.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/KeyDictionaryCompositeKey.java similarity index 93% rename from dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionaryCompositeKey.java rename to dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/KeyDictionaryCompositeKey.java index 49ab8b6822..599c0e5eb7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionaryCompositeKey.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/KeyDictionaryCompositeKey.java @@ -25,7 +25,7 @@ import java.io.Serializable; @Data @NoArgsConstructor @AllArgsConstructor -public class TsKvDictionaryCompositeKey implements Serializable{ +public class KeyDictionaryCompositeKey implements Serializable{ @Transient private static final long serialVersionUID = -4089175869616037523L; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionary.java b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/KeyDictionaryEntry.java similarity index 91% rename from dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionary.java rename to dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/KeyDictionaryEntry.java index 5f1ff6a9c1..6063cbf70a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/TsKvDictionary.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sqlts/dictionary/KeyDictionaryEntry.java @@ -28,9 +28,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.KEY_ID_COLUMN; @Data @Entity -@Table(name = "ts_kv_dictionary") -@IdClass(TsKvDictionaryCompositeKey.class) -public final class TsKvDictionary { +@Table(name = "key_dictionary") +@IdClass(KeyDictionaryCompositeKey.class) +public final class KeyDictionaryEntry { @Id @Column(name = KEY_COLUMN) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java deleted file mode 100644 index aa0ca5b8a5..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvDictionaryRepository.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright © 2016-2023 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sql.attributes; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.thingsboard.server.dao.model.sql.AttributeKvDictionaryEntry; - -import java.util.Optional; - -public interface AttributeKvDictionaryRepository extends JpaRepository { - - Optional findByKeyId(int keyId); - -} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java index 50ee8c462c..01149d3d49 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java @@ -36,12 +36,14 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.attributes.AttributesDao; import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; -import org.thingsboard.server.dao.model.sql.AttributeKvDictionaryEntry; import org.thingsboard.server.dao.model.sql.AttributeKvEntity; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; +import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository; import org.thingsboard.server.dao.util.SqlDao; import java.util.ArrayList; @@ -64,7 +66,7 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl ScheduledLogExecutorComponent logExecutor; @Autowired - private AttributeKvDictionaryRepository dictionaryRepository; + private KeyDictionaryRepository keyDictionaryRepository; @Autowired private AttributeKvRepository attributeKvRepository; @@ -215,21 +217,21 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl private Integer getOrSaveKeyId(String attributeKey) { Integer keyId = attributeDictionaryMap.get(attributeKey); if (keyId == null) { - Optional byIdOptional = dictionaryRepository.findById(attributeKey); + Optional byIdOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(attributeKey)); if (byIdOptional.isEmpty()) { attributeCreationLock.lock(); try { - byIdOptional = dictionaryRepository.findById(attributeKey); + byIdOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(attributeKey)); if (byIdOptional.isEmpty()) { - AttributeKvDictionaryEntry attributeKvDictionaryEntry = new AttributeKvDictionaryEntry(); + KeyDictionaryEntry attributeKvDictionaryEntry = new KeyDictionaryEntry(); attributeKvDictionaryEntry.setKey(attributeKey); try { - AttributeKvDictionaryEntry saved = dictionaryRepository.save(attributeKvDictionaryEntry); + KeyDictionaryEntry saved = keyDictionaryRepository.save(attributeKvDictionaryEntry); attributeDictionaryMap.put(saved.getKey(), saved.getKeyId()); keyId = saved.getKeyId(); } catch (DataIntegrityViolationException | ConstraintViolationException e) { - byIdOptional = dictionaryRepository.findById(attributeKey); - AttributeKvDictionaryEntry dictionary = byIdOptional.orElseThrow(() -> new RuntimeException("Failed to get AttributeKvDictionary entity from DB!")); + byIdOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(attributeKey)); + KeyDictionaryEntry dictionary = byIdOptional.orElseThrow(() -> new RuntimeException("Failed to get AttributeKvDictionary entity from DB!")); attributeDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); keyId = dictionary.getKeyId(); } @@ -247,7 +249,7 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl return keyId; } private String getKey(Integer attributeKey) { - Optional byKeyId = dictionaryRepository.findByKeyId(attributeKey); - return byKeyId.map(AttributeKvDictionaryEntry::getKey).orElse(null); + Optional byKeyId = keyDictionaryRepository.findByKeyId(attributeKey); + return byKeyId.map(KeyDictionaryEntry::getKey).orElse(null); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java index 200e93765d..23d8e972b2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java @@ -256,13 +256,13 @@ public class EntityKeyMapping { } if (entityKey.getType().equals(EntityKeyType.TIME_SERIES)) { String join = (hasFilter() && hasFilterValues(ctx)) ? "inner join" : "left join"; - return String.format("%s ts_kv_latest %s ON %s.entity_id=entities.id AND %s.key = (select key_id from ts_kv_dictionary where key = :%s_key_id) %s", + return String.format("%s ts_kv_latest %s ON %s.entity_id=entities.id AND %s.key = (select key_id from key_dictionary where key = :%s_key_id) %s", join, alias, alias, alias, alias, filterQuery); } else { String query; if (!entityKey.getType().equals(EntityKeyType.ATTRIBUTE)) { String join = (hasFilter() && hasFilterValues(ctx)) ? "inner join" : "left join"; - query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.attribute_key=(select key_id from attribute_kv_dictionary where key = :%s_key_id) ", + query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.attribute_key=(select key_id from key_dictionary where key = :%s_key_id) ", join, alias, alias, alias, alias); int scope; if (entityKey.getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) { @@ -275,7 +275,7 @@ public class EntityKeyMapping { query = String.format("%s AND %s.attribute_type=%s %s", query, alias, scope, filterQuery); } else { String join = (hasFilter() && hasFilterValues(ctx)) ? "join LATERAL" : "left join LATERAL"; - query = String.format("%s (select * from attribute_kv %s WHERE %s.entity_id=entities.id AND %s.attribute_key=(select key_id from attribute_kv_dictionary where key = :%s_key_id) %s " + + query = String.format("%s (select * from attribute_kv %s WHERE %s.entity_id=entities.id AND %s.attribute_key=(select key_id from key_dictionary where key = :%s_key_id) %s " + "ORDER BY %s.last_update_ts DESC limit 1) as %s ON true", join, alias, alias, alias, alias, filterQuery, alias, alias); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java index 52c4216c69..9a33cba81e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java @@ -26,10 +26,10 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary; -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; -import org.thingsboard.server.dao.sqlts.dictionary.TsKvDictionaryRepository; +import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository; import jakarta.annotation.Nullable; import java.util.List; @@ -46,13 +46,13 @@ public abstract class BaseAbstractSqlTimeseriesDao extends JpaAbstractDaoListeni private final ConcurrentMap tsKvDictionaryMap = new ConcurrentHashMap<>(); protected static final ReentrantLock tsCreationLock = new ReentrantLock(); @Autowired - protected TsKvDictionaryRepository dictionaryRepository; + protected KeyDictionaryRepository dictionaryRepository; protected Integer getOrSaveKeyId(String strKey) { Integer keyId = tsKvDictionaryMap.get(strKey); if (keyId == null) { - Optional tsKvDictionaryOptional; - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); + Optional tsKvDictionaryOptional; + tsKvDictionaryOptional = dictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); if (tsKvDictionaryOptional.isEmpty()) { tsCreationLock.lock(); try { @@ -60,17 +60,17 @@ public abstract class BaseAbstractSqlTimeseriesDao extends JpaAbstractDaoListeni if (keyId != null) { return keyId; } - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); + tsKvDictionaryOptional = dictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); if (tsKvDictionaryOptional.isEmpty()) { - TsKvDictionary tsKvDictionary = new TsKvDictionary(); - tsKvDictionary.setKey(strKey); + KeyDictionaryEntry keyDictionaryEntry = new KeyDictionaryEntry(); + keyDictionaryEntry.setKey(strKey); try { - TsKvDictionary saved = dictionaryRepository.save(tsKvDictionary); + KeyDictionaryEntry saved = dictionaryRepository.save(keyDictionaryEntry); tsKvDictionaryMap.put(saved.getKey(), saved.getKeyId()); keyId = saved.getKeyId(); } catch (DataIntegrityViolationException | ConstraintViolationException e) { - tsKvDictionaryOptional = dictionaryRepository.findById(new TsKvDictionaryCompositeKey(strKey)); - TsKvDictionary dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!")); + tsKvDictionaryOptional = dictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + KeyDictionaryEntry dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!")); tsKvDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); keyId = dictionary.getKeyId(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/TsKvDictionaryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/KeyDictionaryRepository.java similarity index 65% rename from dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/TsKvDictionaryRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/KeyDictionaryRepository.java index 41e165b92f..12c2422094 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/TsKvDictionaryRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/KeyDictionaryRepository.java @@ -16,15 +16,14 @@ package org.thingsboard.server.dao.sqlts.dictionary; import org.springframework.data.jpa.repository.JpaRepository; -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionary; -import org.thingsboard.server.dao.model.sqlts.dictionary.TsKvDictionaryCompositeKey; -import org.thingsboard.server.dao.util.SqlTsOrTsLatestAnyDao; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; import java.util.Optional; -@SqlTsOrTsLatestAnyDao -public interface TsKvDictionaryRepository extends JpaRepository { +public interface KeyDictionaryRepository extends JpaRepository { + + Optional findByKeyId(int keyId); - Optional findByKeyId(int keyId); } \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java index beaa4a5f0d..fc7b2d568f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/SearchTsKvLatestRepository.java @@ -30,9 +30,9 @@ public class SearchTsKvLatestRepository { public static final String FIND_ALL_BY_ENTITY_ID = "findAllByEntityId"; - public static final String FIND_ALL_BY_ENTITY_ID_QUERY = "SELECT ts_kv_latest.entity_id AS entityId, ts_kv_latest.key AS key, ts_kv_dictionary.key AS strKey, ts_kv_latest.str_v AS strValue," + + public static final String FIND_ALL_BY_ENTITY_ID_QUERY = "SELECT ts_kv_latest.entity_id AS entityId, ts_kv_latest.key AS key, key_dictionary.key AS strKey, ts_kv_latest.str_v AS strValue," + " ts_kv_latest.bool_v AS boolValue, ts_kv_latest.long_v AS longValue, ts_kv_latest.dbl_v AS doubleValue, ts_kv_latest.json_v AS jsonValue, ts_kv_latest.ts AS ts FROM ts_kv_latest " + - "INNER JOIN ts_kv_dictionary ON ts_kv_latest.key = ts_kv_dictionary.key_id WHERE ts_kv_latest.entity_id = cast(:id AS uuid)"; + "INNER JOIN key_dictionary ON ts_kv_latest.key = key_dictionary.key_id WHERE ts_kv_latest.entity_id = cast(:id AS uuid)"; @PersistenceContext private EntityManager entityManager; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/TsKvLatestRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/TsKvLatestRepository.java index 835ce3a11b..abcae06e19 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/TsKvLatestRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/latest/TsKvLatestRepository.java @@ -26,19 +26,19 @@ import java.util.UUID; public interface TsKvLatestRepository extends JpaRepository { - @Query(value = "SELECT DISTINCT ts_kv_dictionary.key AS strKey FROM ts_kv_latest " + - "INNER JOIN ts_kv_dictionary ON ts_kv_latest.key = ts_kv_dictionary.key_id " + - "WHERE ts_kv_latest.entity_id IN (SELECT id FROM device WHERE device_profile_id = :device_profile_id AND tenant_id = :tenant_id limit 100) ORDER BY ts_kv_dictionary.key", nativeQuery = true) + @Query(value = "SELECT DISTINCT key_dictionary.key AS strKey FROM ts_kv_latest " + + "INNER JOIN key_dictionary ON ts_kv_latest.key = key_dictionary.key_id " + + "WHERE ts_kv_latest.entity_id IN (SELECT id FROM device WHERE device_profile_id = :device_profile_id AND tenant_id = :tenant_id limit 100) ORDER BY key_dictionary.key", nativeQuery = true) List getKeysByDeviceProfileId(@Param("tenant_id") UUID tenantId, @Param("device_profile_id") UUID deviceProfileId); - @Query(value = "SELECT DISTINCT ts_kv_dictionary.key AS strKey FROM ts_kv_latest " + - "INNER JOIN ts_kv_dictionary ON ts_kv_latest.key = ts_kv_dictionary.key_id " + - "WHERE ts_kv_latest.entity_id IN (SELECT id FROM device WHERE tenant_id = :tenant_id limit 100) ORDER BY ts_kv_dictionary.key", nativeQuery = true) + @Query(value = "SELECT DISTINCT key_dictionary.key AS strKey FROM ts_kv_latest " + + "INNER JOIN key_dictionary ON ts_kv_latest.key = key_dictionary.key_id " + + "WHERE ts_kv_latest.entity_id IN (SELECT id FROM device WHERE tenant_id = :tenant_id limit 100) ORDER BY key_dictionary.key", nativeQuery = true) List getKeysByTenantId(@Param("tenant_id") UUID tenantId); - @Query(value = "SELECT DISTINCT ts_kv_dictionary.key AS strKey FROM ts_kv_latest " + - "INNER JOIN ts_kv_dictionary ON ts_kv_latest.key = ts_kv_dictionary.key_id " + - "WHERE ts_kv_latest.entity_id IN :entityIds ORDER BY ts_kv_dictionary.key", nativeQuery = true) + @Query(value = "SELECT DISTINCT key_dictionary.key AS strKey FROM ts_kv_latest " + + "INNER JOIN key_dictionary ON ts_kv_latest.key = key_dictionary.key_id " + + "WHERE ts_kv_latest.entity_id IN :entityIds ORDER BY key_dictionary.key", nativeQuery = true) List findAllKeysByEntityIds(@Param("entityIds") List entityIds); } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index f376a777d3..9ce78bd56f 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -115,12 +115,6 @@ CREATE TABLE IF NOT EXISTS attribute_kv ( CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_id, attribute_type, attribute_key) ); -CREATE TABLE IF NOT EXISTS attribute_kv_dictionary ( - key varchar(255) NOT NULL, - key_id serial UNIQUE, - CONSTRAINT attribute_key_id_pkey PRIMARY KEY (key) -); - CREATE TABLE IF NOT EXISTS component_descriptor ( id uuid NOT NULL CONSTRAINT component_descriptor_pkey PRIMARY KEY, created_time bigint NOT NULL, @@ -552,11 +546,11 @@ CREATE TABLE IF NOT EXISTS ts_kv_latest CONSTRAINT ts_kv_latest_pkey PRIMARY KEY (entity_id, key) ); -CREATE TABLE IF NOT EXISTS ts_kv_dictionary +CREATE TABLE IF NOT EXISTS key_dictionary ( key varchar(255) NOT NULL, key_id serial UNIQUE, - CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) + CONSTRAINT key_id_pkey PRIMARY KEY (key) ); CREATE TABLE IF NOT EXISTS oauth2_params ( diff --git a/dao/src/main/resources/sql/schema-timescale.sql b/dao/src/main/resources/sql/schema-timescale.sql index 0a60b64a50..f547a72cd1 100644 --- a/dao/src/main/resources/sql/schema-timescale.sql +++ b/dao/src/main/resources/sql/schema-timescale.sql @@ -28,7 +28,7 @@ CREATE TABLE IF NOT EXISTS ts_kv ( CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts) ); -CREATE TABLE IF NOT EXISTS ts_kv_dictionary ( +CREATE TABLE IF NOT EXISTS key_dictionary ( key varchar(255) NOT NULL, key_id serial UNIQUE, CONSTRAINT ts_key_id_pkey PRIMARY KEY (key) @@ -104,7 +104,7 @@ BEGIN WHILE FOUND LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from key_dictionary where key = %L)', tenant_id_record, 'TTL') INTO tenant_ttl; if tenant_ttl IS NULL THEN tenant_ttl := system_ttl; @@ -122,7 +122,7 @@ BEGIN SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from key_dictionary where key = %L)', customer_id_record, 'TTL') INTO customer_ttl; IF customer_ttl IS NULL THEN customer_ttl_ts := tenant_ttl_ts; diff --git a/dao/src/main/resources/sql/schema-ts-psql.sql b/dao/src/main/resources/sql/schema-ts-psql.sql index 3f8f380b03..023e1b544d 100644 --- a/dao/src/main/resources/sql/schema-ts-psql.sql +++ b/dao/src/main/resources/sql/schema-ts-psql.sql @@ -27,7 +27,7 @@ CREATE TABLE IF NOT EXISTS ts_kv CONSTRAINT ts_kv_pkey PRIMARY KEY (entity_id, key, ts) ) PARTITION BY RANGE (ts); -CREATE TABLE IF NOT EXISTS ts_kv_dictionary +CREATE TABLE IF NOT EXISTS key_dictionary ( key varchar(255) NOT NULL, key_id serial UNIQUE, @@ -75,7 +75,7 @@ BEGIN WHERE schemaname = 'public' AND tablename like 'ts_kv_' || '%' AND tablename != 'ts_kv_latest' - AND tablename != 'ts_kv_dictionary' + AND tablename != 'key_dictionary' AND tablename != 'ts_kv_indefinite' AND tablename != partition_by_max_ttl_date LOOP @@ -96,7 +96,7 @@ BEGIN WHERE schemaname = 'public' AND tablename like 'ts_kv_' || '%' AND tablename != 'ts_kv_latest' - AND tablename != 'ts_kv_dictionary' + AND tablename != 'key_dictionary' AND tablename != 'ts_kv_indefinite' AND tablename != partition_by_max_ttl_date LOOP @@ -138,7 +138,7 @@ BEGIN WHERE schemaname = 'public' AND tablename like 'ts_kv_' || '%' AND tablename != 'ts_kv_latest' - AND tablename != 'ts_kv_dictionary' + AND tablename != 'key_dictionary' AND tablename != 'ts_kv_indefinite' AND tablename != partition_by_max_ttl_date LOOP @@ -272,7 +272,7 @@ BEGIN WHILE FOUND LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from key_dictionary where key = %L)', tenant_id_record, 'TTL') INTO tenant_ttl; if tenant_ttl IS NULL THEN tenant_ttl := system_ttl; @@ -290,7 +290,7 @@ BEGIN SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from key_dictionary where key = %L)', customer_id_record, 'TTL') INTO customer_ttl; IF customer_ttl IS NULL THEN customer_ttl_ts := tenant_ttl_ts; diff --git a/dao/src/main/resources/sql/schema-views-and-functions.sql b/dao/src/main/resources/sql/schema-views-and-functions.sql index 4d684c6406..bcb34a030a 100644 --- a/dao/src/main/resources/sql/schema-views-and-functions.sql +++ b/dao/src/main/resources/sql/schema-views-and-functions.sql @@ -23,7 +23,7 @@ SELECT d.* , COALESCE(da.bool_v, FALSE) as active FROM device d LEFT JOIN customer c ON c.id = d.customer_id - LEFT JOIN attribute_kv da ON da.entity_id = d.id AND da.attribute_type = 2 AND da.attribute_key = (select key_id from attribute_kv_dictionary where key = 'active'); + LEFT JOIN attribute_kv da ON da.entity_id = d.id AND da.attribute_type = 2 AND da.attribute_key = (select key_id from key_dictionary where key = 'active'); DROP VIEW IF EXISTS device_info_active_ts_view CASCADE; CREATE OR REPLACE VIEW device_info_active_ts_view AS @@ -34,7 +34,7 @@ SELECT d.* , COALESCE(dt.bool_v, FALSE) as active FROM device d LEFT JOIN customer c ON c.id = d.customer_id - LEFT JOIN ts_kv_latest dt ON dt.entity_id = d.id and dt.key = (select key_id from ts_kv_dictionary where key = 'active'); + LEFT JOIN ts_kv_latest dt ON dt.entity_id = d.id and dt.key = (select key_id from key_dictionary where key = 'active'); DROP VIEW IF EXISTS device_info_view CASCADE; CREATE OR REPLACE VIEW device_info_view AS SELECT * FROM device_info_active_attribute_view; @@ -312,7 +312,7 @@ BEGIN WHILE FOUND LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from key_dictionary where key = %L)', tenant_id_record, 'TTL') INTO tenant_ttl; if tenant_ttl IS NULL THEN tenant_ttl := system_ttl; @@ -330,7 +330,7 @@ BEGIN SELECT customer.id AS customer_id FROM customer WHERE customer.tenant_id = tenant_id_record LOOP EXECUTE format( - 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from attribute_kv_dictionary where key = %L)', + 'select attribute_kv.long_v from attribute_kv where attribute_kv.entity_id = %L and attribute_kv.attribute_key = (select key_id from key_dictionary where key = %L)', customer_id_record, 'TTL') INTO customer_ttl; IF customer_ttl IS NULL THEN customer_ttl_ts := tenant_ttl_ts; diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index 0b94f07255..2aafcc0381 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -30,10 +30,8 @@ import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.server.common.data.AttributeScope; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; import org.thingsboard.server.common.data.alarm.AlarmInfo; @@ -60,7 +58,6 @@ import org.thingsboard.server.common.data.msg.TbMsgType; import org.thingsboard.server.common.data.query.BooleanFilterPredicate; import org.thingsboard.server.common.data.query.DynamicValue; import org.thingsboard.server.common.data.query.DynamicValueSourceType; -import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.common.data.query.EntityKeyValueType; import org.thingsboard.server.common.data.query.FilterPredicateValue; import org.thingsboard.server.common.data.query.NumericFilterPredicate; diff --git a/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java b/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java index 3b1164e95b..b85171d6ac 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java +++ b/tools/src/main/java/org/thingsboard/client/tools/migrator/DictionaryParser.java @@ -40,7 +40,7 @@ public class DictionaryParser { } private boolean isBlockStarted(String line) { - return line.startsWith("COPY public.ts_kv_dictionary ("); + return line.startsWith("COPY public.key_dictionary ("); } private void parseDictionaryDump(LineIterator iterator) throws IOException { From 2ad19106f369dbf6b2b2251c56a1569d5eec0e2c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 4 Jan 2024 14:52:12 +0200 Subject: [PATCH 49/61] removed redundant code, fixed tests --- .../service/install/TimescaleTsDatabaseUpgradeService.java | 5 ----- .../main/java/org/thingsboard/server/dao/JpaDaoConfig.java | 6 +++--- .../org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java | 1 - .../timeseries/nosql/TimeseriesServiceNoSqlTest.java | 1 - 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java index 4477bef1c4..205ec14591 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java @@ -184,11 +184,6 @@ public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgr break; case "3.2.2": break; - case "3.6.2": - try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { - loadSql(conn, LOAD_TTL_FUNCTIONS_SQL, "3.6.2"); - } - break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java index 37ca4aecbc..40a45c3444 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/JpaDaoConfig.java @@ -27,9 +27,9 @@ import org.thingsboard.server.dao.util.TbAutoConfiguration; */ @Configuration @TbAutoConfiguration -@ComponentScan({"org.thingsboard.server.dao.sql", "org.thingsboard.server.dao.sqlts", "org.thingsboard.server.dao.attributes", "org.thingsboard.server.dao.cache", "org.thingsboard.server.cache"}) -@EnableJpaRepositories({"org.thingsboard.server.dao.sql", "org.thingsboard.server.dao.sqlts"}) -@EntityScan({"org.thingsboard.server.dao.model.sql", "org.thingsboard.server.dao.model.sqlts"}) +@ComponentScan({"org.thingsboard.server.dao.sql", "org.thingsboard.server.dao.attributes", "org.thingsboard.server.dao.cache", "org.thingsboard.server.cache"}) +@EnableJpaRepositories("org.thingsboard.server.dao.sql") +@EntityScan("org.thingsboard.server.dao.model.sql") @EnableTransactionManagement public class JpaDaoConfig { diff --git a/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java index 44658f114f..9693e2d10b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java @@ -27,7 +27,6 @@ import org.thingsboard.server.dao.util.TbAutoConfiguration; @EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.dictionary"}) @EntityScan({"org.thingsboard.server.dao.model.sqlts.dictionary"}) @EnableTransactionManagement -@SqlTsOrTsLatestAnyDao public class SqlTimeseriesDaoConfig { } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java index af1b11174a..efcf62be20 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/timeseries/nosql/TimeseriesServiceNoSqlTest.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.dao.service.timeseries.nosql; -import org.thingsboard.server.dao.AbstractJpaDaoTest; import org.thingsboard.server.dao.service.DaoNoSqlTest; import org.thingsboard.server.dao.service.timeseries.BaseTimeseriesServiceTest; From 237568997491b967e4b9b73be8e0c1ba9761b3ca Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 4 Jan 2024 18:55:00 +0200 Subject: [PATCH 50/61] refactoring: moved common method for retrieving key dictionary id to abstract class --- .../install/ThingsboardInstallService.java | 1 - .../install/SqlTsDatabaseUpgradeService.java | 2 - .../update/DefaultCacheCleanupService.java | 5 ++ ...paAbstractDaoListeningExecutorService.java | 55 +++++++++++++++++++ .../dao/sql/attributes/JpaAttributeDao.java | 47 ---------------- .../sqlts/BaseAbstractSqlTimeseriesDao.java | 54 ------------------ 6 files changed, 60 insertions(+), 104 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index ef5f3edd58..730ec0ec97 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -276,7 +276,6 @@ public class ThingsboardInstallService { } else { log.info("Skipping images migration. Run the upgrade with fromVersion as '3.6.2-images' to migrate"); } - //TODO DON'T FORGET to update switch statement in the CacheCleanupService if you need to clear the cache case "3.6.3": log.info("Upgrading ThingsBoard from version 3.6.3 to 3.7.0 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.6.3"); diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java index b61da45631..6400463e11 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java @@ -213,8 +213,6 @@ public class SqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeSer loadSql(conn, LOAD_DROP_PARTITIONS_FUNCTIONS_SQL, "2.4.3"); } break; - case "3.6.2": - break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultCacheCleanupService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultCacheCleanupService.java index 350005536a..e401ec2360 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultCacheCleanupService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultCacheCleanupService.java @@ -27,6 +27,7 @@ import org.springframework.stereotype.Service; import java.util.Objects; import java.util.Optional; +import static org.thingsboard.server.common.data.CacheConstants.ATTRIBUTES_CACHE; import static org.thingsboard.server.common.data.CacheConstants.RESOURCE_INFO_CACHE; import static org.thingsboard.server.common.data.CacheConstants.SECURITY_SETTINGS_CACHE; @@ -94,6 +95,10 @@ public class DefaultCacheCleanupService implements CacheCleanupService { clearCacheByName(SECURITY_SETTINGS_CACHE); clearCacheByName(RESOURCE_INFO_CACHE); break; + case "3.6.3": + log.info("Clearing cache to upgrade from version 3.6.3 to 3.7.0"); + clearCacheByName(ATTRIBUTES_CACHE); + break; default: //Do nothing, since cache cleanup is optional. } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java index 5646aa1b6c..3a10b7f619 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java @@ -16,17 +16,29 @@ package org.thingsboard.server.dao.sql; import lombok.extern.slf4j.Slf4j; +import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; +import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository; import javax.sql.DataSource; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.ReentrantLock; @Slf4j public abstract class JpaAbstractDaoListeningExecutorService { + private final ConcurrentMap keyDictionaryMap = new ConcurrentHashMap<>(); + protected static final ReentrantLock creationLock = new ReentrantLock(); + @Autowired protected JpaExecutorService service; @@ -36,6 +48,49 @@ public abstract class JpaAbstractDaoListeningExecutorService { @Autowired protected JdbcTemplate jdbcTemplate; + @Autowired + protected KeyDictionaryRepository keyDictionaryRepository; + + protected Integer getOrSaveKeyId(String strKey) { + Integer keyId = keyDictionaryMap.get(strKey); + if (keyId == null) { + Optional tsKvDictionaryOptional; + tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + if (tsKvDictionaryOptional.isEmpty()) { + creationLock.lock(); + try { + keyId = keyDictionaryMap.get(strKey); + if (keyId != null) { + return keyId; + } + tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + if (tsKvDictionaryOptional.isEmpty()) { + KeyDictionaryEntry keyDictionaryEntry = new KeyDictionaryEntry(); + keyDictionaryEntry.setKey(strKey); + try { + KeyDictionaryEntry saved = keyDictionaryRepository.save(keyDictionaryEntry); + keyDictionaryMap.put(saved.getKey(), saved.getKeyId()); + keyId = saved.getKeyId(); + } catch (DataIntegrityViolationException | ConstraintViolationException e) { + tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + KeyDictionaryEntry dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get KeyDictionaryEntry entity from DB!")); + keyDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); + keyId = dictionary.getKeyId(); + } + } else { + keyId = tsKvDictionaryOptional.get().getKeyId(); + } + } finally { + creationLock.unlock(); + } + } else { + keyId = tsKvDictionaryOptional.get().getKeyId(); + keyDictionaryMap.put(strKey, keyId); + } + } + return keyId; + } + protected void printWarnings(Statement statement) throws SQLException { SQLWarning warnings = statement.getWarnings(); if (warnings != null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java index 01149d3d49..54d0bf9495 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java @@ -22,10 +22,8 @@ import com.google.common.util.concurrent.MoreExecutors; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; -import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -37,13 +35,11 @@ import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.attributes.AttributesDao; import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; import org.thingsboard.server.dao.model.sql.AttributeKvEntity; -import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueWrapper; -import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository; import org.thingsboard.server.dao.util.SqlDao; import java.util.ArrayList; @@ -51,9 +47,6 @@ import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import java.util.stream.Collectors; @@ -65,9 +58,6 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl @Autowired ScheduledLogExecutorComponent logExecutor; - @Autowired - private KeyDictionaryRepository keyDictionaryRepository; - @Autowired private AttributeKvRepository attributeKvRepository; @@ -92,9 +82,6 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl @Value("${sql.batch_sort:true}") private boolean batchSortEnabled; - private final ConcurrentMap attributeDictionaryMap = new ConcurrentHashMap<>(); - private static final ReentrantLock attributeCreationLock = new ReentrantLock(); - private TbSqlBlockingQueueWrapper queue; @PostConstruct @@ -214,40 +201,6 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl attributeKey); } - private Integer getOrSaveKeyId(String attributeKey) { - Integer keyId = attributeDictionaryMap.get(attributeKey); - if (keyId == null) { - Optional byIdOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(attributeKey)); - if (byIdOptional.isEmpty()) { - attributeCreationLock.lock(); - try { - byIdOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(attributeKey)); - if (byIdOptional.isEmpty()) { - KeyDictionaryEntry attributeKvDictionaryEntry = new KeyDictionaryEntry(); - attributeKvDictionaryEntry.setKey(attributeKey); - try { - KeyDictionaryEntry saved = keyDictionaryRepository.save(attributeKvDictionaryEntry); - attributeDictionaryMap.put(saved.getKey(), saved.getKeyId()); - keyId = saved.getKeyId(); - } catch (DataIntegrityViolationException | ConstraintViolationException e) { - byIdOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(attributeKey)); - KeyDictionaryEntry dictionary = byIdOptional.orElseThrow(() -> new RuntimeException("Failed to get AttributeKvDictionary entity from DB!")); - attributeDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); - keyId = dictionary.getKeyId(); - } - } else { - keyId = byIdOptional.get().getKeyId(); - } - } finally { - attributeCreationLock.unlock(); - } - } else { - keyId = byIdOptional.get().getKeyId(); - attributeDictionaryMap.put(attributeKey, keyId); - } - } - return keyId; - } private String getKey(Integer attributeKey) { Optional byKeyId = keyDictionaryRepository.findByKeyId(attributeKey); return byKeyId.map(KeyDictionaryEntry::getKey).orElse(null); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java index e018cc1ef9..56f21aee39 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/BaseAbstractSqlTimeseriesDao.java @@ -19,75 +19,21 @@ import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; -import org.hibernate.exception.ConstraintViolationException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; import org.thingsboard.server.common.data.kv.ReadTsKvQuery; import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; -import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; -import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; -import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository; import jakarta.annotation.Nullable; import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; @Slf4j public abstract class BaseAbstractSqlTimeseriesDao extends JpaAbstractDaoListeningExecutorService { - private final ConcurrentMap tsKvDictionaryMap = new ConcurrentHashMap<>(); - protected static final ReentrantLock tsCreationLock = new ReentrantLock(); - @Autowired - protected KeyDictionaryRepository keyDictionaryRepository; - - protected Integer getOrSaveKeyId(String strKey) { - Integer keyId = tsKvDictionaryMap.get(strKey); - if (keyId == null) { - Optional tsKvDictionaryOptional; - tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); - if (tsKvDictionaryOptional.isEmpty()) { - tsCreationLock.lock(); - try { - keyId = tsKvDictionaryMap.get(strKey); - if (keyId != null) { - return keyId; - } - tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); - if (tsKvDictionaryOptional.isEmpty()) { - KeyDictionaryEntry keyDictionaryEntry = new KeyDictionaryEntry(); - keyDictionaryEntry.setKey(strKey); - try { - KeyDictionaryEntry saved = keyDictionaryRepository.save(keyDictionaryEntry); - tsKvDictionaryMap.put(saved.getKey(), saved.getKeyId()); - keyId = saved.getKeyId(); - } catch (DataIntegrityViolationException | ConstraintViolationException e) { - tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); - KeyDictionaryEntry dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get TsKvDictionary entity from DB!")); - tsKvDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); - keyId = dictionary.getKeyId(); - } - } else { - keyId = tsKvDictionaryOptional.get().getKeyId(); - } - } finally { - tsCreationLock.unlock(); - } - } else { - keyId = tsKvDictionaryOptional.get().getKeyId(); - tsKvDictionaryMap.put(strKey, keyId); - } - } - return keyId; - } - protected ListenableFuture getReadTsKvQueryResultFuture(ReadTsKvQuery query, ListenableFuture>> future) { return Futures.transform(future, new Function<>() { @Nullable From 6b7ae41c72ce95dd9a4b37fd324a5d066e8e651e Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 4 Jan 2024 19:23:43 +0200 Subject: [PATCH 51/61] refactoring: created KeyDictionaryDao --- .../dao/dictionary/KeyDictionaryDao.java | 25 +++++ ...paAbstractDaoListeningExecutorService.java | 55 ----------- .../dao/sql/attributes/JpaAttributeDao.java | 28 +++--- ...stractChunkedAggregationTimeseriesDao.java | 10 +- .../dao/sqlts/SqlTimeseriesLatestDao.java | 10 +- .../sqlts/dictionary/JpaKeyDictionaryDao.java | 92 +++++++++++++++++++ .../dao/sqlts/sql/JpaSqlTimeseriesDao.java | 5 +- .../timescale/TimescaleTimeseriesDao.java | 12 ++- 8 files changed, 156 insertions(+), 81 deletions(-) create mode 100644 dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java create mode 100644 dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java diff --git a/dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java b/dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java new file mode 100644 index 0000000000..aa663bf208 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java @@ -0,0 +1,25 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.dictionary; + + +public interface KeyDictionaryDao { + + Integer getOrSaveKeyId(String strKey); + + String getKey(Integer attributeKey); + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java index 3a10b7f619..5646aa1b6c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDaoListeningExecutorService.java @@ -16,29 +16,17 @@ package org.thingsboard.server.dao.sql; import lombok.extern.slf4j.Slf4j; -import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; import org.springframework.jdbc.core.JdbcTemplate; -import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; -import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; -import org.thingsboard.server.dao.sqlts.dictionary.KeyDictionaryRepository; import javax.sql.DataSource; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.ReentrantLock; @Slf4j public abstract class JpaAbstractDaoListeningExecutorService { - private final ConcurrentMap keyDictionaryMap = new ConcurrentHashMap<>(); - protected static final ReentrantLock creationLock = new ReentrantLock(); - @Autowired protected JpaExecutorService service; @@ -48,49 +36,6 @@ public abstract class JpaAbstractDaoListeningExecutorService { @Autowired protected JdbcTemplate jdbcTemplate; - @Autowired - protected KeyDictionaryRepository keyDictionaryRepository; - - protected Integer getOrSaveKeyId(String strKey) { - Integer keyId = keyDictionaryMap.get(strKey); - if (keyId == null) { - Optional tsKvDictionaryOptional; - tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); - if (tsKvDictionaryOptional.isEmpty()) { - creationLock.lock(); - try { - keyId = keyDictionaryMap.get(strKey); - if (keyId != null) { - return keyId; - } - tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); - if (tsKvDictionaryOptional.isEmpty()) { - KeyDictionaryEntry keyDictionaryEntry = new KeyDictionaryEntry(); - keyDictionaryEntry.setKey(strKey); - try { - KeyDictionaryEntry saved = keyDictionaryRepository.save(keyDictionaryEntry); - keyDictionaryMap.put(saved.getKey(), saved.getKeyId()); - keyId = saved.getKeyId(); - } catch (DataIntegrityViolationException | ConstraintViolationException e) { - tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); - KeyDictionaryEntry dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get KeyDictionaryEntry entity from DB!")); - keyDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); - keyId = dictionary.getKeyId(); - } - } else { - keyId = tsKvDictionaryOptional.get().getKeyId(); - } - } finally { - creationLock.unlock(); - } - } else { - keyId = tsKvDictionaryOptional.get().getKeyId(); - keyDictionaryMap.put(strKey, keyId); - } - } - return keyId; - } - protected void printWarnings(Statement statement) throws SQLException { SQLWarning warnings = statement.getWarnings(); if (warnings != null) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java index 54d0bf9495..7114d6db3e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/JpaAttributeDao.java @@ -33,9 +33,9 @@ import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; import org.thingsboard.server.dao.attributes.AttributesDao; +import org.thingsboard.server.dao.dictionary.KeyDictionaryDao; import org.thingsboard.server.dao.model.sql.AttributeKvCompositeKey; import org.thingsboard.server.dao.model.sql.AttributeKvEntity; -import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; import org.thingsboard.server.dao.sql.ScheduledLogExecutorComponent; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; @@ -67,6 +67,9 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl @Autowired private StatsFactory statsFactory; + @Autowired + private KeyDictionaryDao keyDictionaryDao; + @Value("${sql.attributes.batch_size:1000}") private int batchSize; @@ -114,7 +117,7 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl @Override public Optional find(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, String attributeKey) { AttributeKvCompositeKey compositeKey = - getAttributeKvCompositeKey(entityId, attributeScope.getId(), getOrSaveKeyId(attributeKey)); + getAttributeKvCompositeKey(entityId, attributeScope.getId(), keyDictionaryDao.getOrSaveKeyId(attributeKey)); Optional attributeKvEntityOptional = attributeKvRepository.findById(compositeKey); if (attributeKvEntityOptional.isPresent()) { AttributeKvEntity attributeKvEntity = attributeKvEntityOptional.get(); @@ -130,10 +133,10 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl attributeKeys .stream() .map(attributeKey -> - getAttributeKvCompositeKey(entityId, attributeScope.getId(), getOrSaveKeyId(attributeKey))) + getAttributeKvCompositeKey(entityId, attributeScope.getId(), keyDictionaryDao.getOrSaveKeyId(attributeKey))) .collect(Collectors.toList()); List attributes = attributeKvRepository.findAllById(compositeKeys); - attributes.forEach(attributeKvEntity -> attributeKvEntity.setStrKey(getKey(attributeKvEntity.getId().getAttributeKey()))); + attributes.forEach(attributeKvEntity -> attributeKvEntity.setStrKey(keyDictionaryDao.getKey(attributeKvEntity.getId().getAttributeKey()))); return DaoUtil.convertDataList(Lists.newArrayList(attributes)); } @@ -142,7 +145,7 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl List attributes = attributeKvRepository.findAllEntityIdAndAttributeType( entityId.getId(), attributeScope.getId()); - attributes.forEach(attributeKvEntity -> attributeKvEntity.setStrKey(getKey(attributeKvEntity.getId().getAttributeKey()))); + attributes.forEach(attributeKvEntity -> attributeKvEntity.setStrKey(keyDictionaryDao.getKey(attributeKvEntity.getId().getAttributeKey()))); return DaoUtil.convertDataList(Lists.newArrayList( attributes)); } @@ -151,10 +154,10 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl public List findAllKeysByDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId) { if (deviceProfileId != null) { return attributeKvRepository.findAllKeysByDeviceProfileId(tenantId.getId(), deviceProfileId.getId()) - .stream().map(this::getKey).collect(Collectors.toList()); + .stream().map(id -> keyDictionaryDao.getKey(id)).collect(Collectors.toList()); } else { return attributeKvRepository.findAllKeysByTenantId(tenantId.getId()) - .stream().map(this::getKey).collect(Collectors.toList()); + .stream().map(id -> keyDictionaryDao.getKey(id)).collect(Collectors.toList()); } } @@ -162,13 +165,13 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl public List findAllKeysByEntityIds(TenantId tenantId, List entityIds) { return attributeKvRepository .findAllKeysByEntityIds(entityIds.stream().map(EntityId::getId).collect(Collectors.toList())) - .stream().map(this::getKey).collect(Collectors.toList()); + .stream().map(id -> keyDictionaryDao.getKey(id)).collect(Collectors.toList()); } @Override public ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope attributeScope, AttributeKvEntry attribute) { AttributeKvEntity entity = new AttributeKvEntity(); - entity.setId(new AttributeKvCompositeKey(entityId.getId(), attributeScope.getId(), getOrSaveKeyId(attribute.getKey()))); + entity.setId(new AttributeKvCompositeKey(entityId.getId(), attributeScope.getId(), keyDictionaryDao.getOrSaveKeyId(attribute.getKey()))); entity.setLastUpdateTs(attribute.getLastUpdateTs()); entity.setStrValue(attribute.getStrValue().orElse(null)); entity.setDoubleValue(attribute.getDoubleValue().orElse(null)); @@ -187,7 +190,7 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl List> futuresList = new ArrayList<>(keys.size()); for (String key : keys) { futuresList.add(service.submit(() -> { - attributeKvRepository.delete(entityId.getId(), attributeScope.getId(), getOrSaveKeyId(key)); + attributeKvRepository.delete(entityId.getId(), attributeScope.getId(), keyDictionaryDao.getOrSaveKeyId(key)); return key; })); } @@ -200,9 +203,4 @@ public class JpaAttributeDao extends JpaAbstractDaoListeningExecutorService impl attributeType, attributeKey); } - - private String getKey(Integer attributeKey) { - Optional byKeyId = keyDictionaryRepository.findByKeyId(attributeKey); - return byKeyId.map(KeyDictionaryEntry::getKey).orElse(null); - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java index 991043db88..c023b2ede3 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/AbstractChunkedAggregationTimeseriesDao.java @@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.dictionary.KeyDictionaryDao; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; @@ -61,6 +62,9 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq @Autowired private StatsFactory statsFactory; + @Autowired + private KeyDictionaryDao keyDictionaryDao; + @PostConstruct protected void init() { TbSqlBlockingQueueParams tsParams = TbSqlBlockingQueueParams.builder() @@ -93,7 +97,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq return service.submit(() -> { tsKvRepository.delete( entityId.getId(), - getOrSaveKeyId(query.getKey()), + keyDictionaryDao.getOrSaveKeyId(query.getKey()), query.getStartTs(), query.getEndTs()); return null; @@ -132,7 +136,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq } private ReadTsKvQueryResult findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) { - Integer keyId = getOrSaveKeyId(query.getKey()); + Integer keyId = keyDictionaryDao.getOrSaveKeyId(query.getKey()); List tsKvEntities = tsKvRepository.findAllWithLimit( entityId.getId(), keyId, @@ -160,7 +164,7 @@ public abstract class AbstractChunkedAggregationTimeseriesDao extends AbstractSq } protected TsKvEntity switchAggregation(EntityId entityId, String key, long startTs, long endTs, Aggregation aggregation) { - var keyId = getOrSaveKeyId(key); + var keyId = keyDictionaryDao.getOrSaveKeyId(key); switch (aggregation) { case AVG: return tsKvRepository.findAvg(entityId.getId(), keyId, startTs, endTs); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java index 404855edf4..b7e871e3f5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/SqlTimeseriesLatestDao.java @@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.kv.TsKvLatestRemovingResult; import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.dictionary.KeyDictionaryDao; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestCompositeKey; import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; @@ -103,6 +104,9 @@ public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao impleme @Autowired private StatsFactory statsFactory; + @Autowired + private KeyDictionaryDao keyDictionaryDao; + @PostConstruct protected void init() { TbSqlBlockingQueueParams tsLatestParams = TbSqlBlockingQueueParams.builder() @@ -209,7 +213,7 @@ public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao impleme TsKvLatestCompositeKey compositeKey = new TsKvLatestCompositeKey( entityId.getId(), - getOrSaveKeyId(key)); + keyDictionaryDao.getOrSaveKeyId(key)); Optional entry = tsKvLatestRepository.findById(compositeKey); if (entry.isPresent()) { TsKvLatestEntity tsKvLatestEntity = entry.get(); @@ -232,7 +236,7 @@ public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao impleme if (ts >= query.getStartTs() && ts < query.getEndTs()) { TsKvLatestEntity latestEntity = new TsKvLatestEntity(); latestEntity.setEntityId(entityId.getId()); - latestEntity.setKey(getOrSaveKeyId(query.getKey())); + latestEntity.setKey(keyDictionaryDao.getOrSaveKeyId(query.getKey())); removedLatestFuture = service.submit(() -> { tsKvLatestRepository.delete(latestEntity); return true; @@ -259,7 +263,7 @@ public class SqlTimeseriesLatestDao extends BaseAbstractSqlTimeseriesDao impleme TsKvLatestEntity latestEntity = new TsKvLatestEntity(); latestEntity.setEntityId(entityId.getId()); latestEntity.setTs(tsKvEntry.getTs()); - latestEntity.setKey(getOrSaveKeyId(tsKvEntry.getKey())); + latestEntity.setKey(keyDictionaryDao.getOrSaveKeyId(tsKvEntry.getKey())); latestEntity.setStrValue(tsKvEntry.getStrValue().orElse(null)); latestEntity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null)); latestEntity.setLongValue(tsKvEntry.getLongValue().orElse(null)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java new file mode 100644 index 0000000000..3c2a4cd228 --- /dev/null +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java @@ -0,0 +1,92 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.dao.sqlts.dictionary; + +import lombok.extern.slf4j.Slf4j; +import org.hibernate.exception.ConstraintViolationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Component; +import org.thingsboard.server.dao.dictionary.KeyDictionaryDao; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryCompositeKey; +import org.thingsboard.server.dao.model.sqlts.dictionary.KeyDictionaryEntry; +import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; +import org.thingsboard.server.dao.util.SqlDao; + +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.ReentrantLock; + +@Component +@Slf4j +@SqlDao +public class JpaKeyDictionaryDao extends JpaAbstractDaoListeningExecutorService implements KeyDictionaryDao { + + private final ConcurrentMap keyDictionaryMap = new ConcurrentHashMap<>(); + protected static final ReentrantLock creationLock = new ReentrantLock(); + + @Autowired + private KeyDictionaryRepository keyDictionaryRepository; + + @Override + public Integer getOrSaveKeyId(String strKey) { + Integer keyId = keyDictionaryMap.get(strKey); + if (keyId == null) { + Optional tsKvDictionaryOptional; + tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + if (tsKvDictionaryOptional.isEmpty()) { + creationLock.lock(); + try { + keyId = keyDictionaryMap.get(strKey); + if (keyId != null) { + return keyId; + } + tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + if (tsKvDictionaryOptional.isEmpty()) { + KeyDictionaryEntry keyDictionaryEntry = new KeyDictionaryEntry(); + keyDictionaryEntry.setKey(strKey); + try { + KeyDictionaryEntry saved = keyDictionaryRepository.save(keyDictionaryEntry); + keyDictionaryMap.put(saved.getKey(), saved.getKeyId()); + keyId = saved.getKeyId(); + } catch (DataIntegrityViolationException | ConstraintViolationException e) { + tsKvDictionaryOptional = keyDictionaryRepository.findById(new KeyDictionaryCompositeKey(strKey)); + KeyDictionaryEntry dictionary = tsKvDictionaryOptional.orElseThrow(() -> new RuntimeException("Failed to get KeyDictionaryEntry entity from DB!")); + keyDictionaryMap.put(dictionary.getKey(), dictionary.getKeyId()); + keyId = dictionary.getKeyId(); + } + } else { + keyId = tsKvDictionaryOptional.get().getKeyId(); + } + } finally { + creationLock.unlock(); + } + } else { + keyId = tsKvDictionaryOptional.get().getKeyId(); + keyDictionaryMap.put(strKey, keyId); + } + } + return keyId; + } + + @Override + public String getKey(Integer attributeKey) { + Optional byKeyId = keyDictionaryRepository.findByKeyId(attributeKey); + return byKeyId.map(KeyDictionaryEntry::getKey).orElse(null); + } + +} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java index 15a7e99129..4b0d4d9428 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java @@ -27,6 +27,7 @@ import org.springframework.stereotype.Component; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.TsKvEntry; +import org.thingsboard.server.dao.dictionary.KeyDictionaryDao; import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; import org.thingsboard.server.dao.sqlts.AbstractChunkedAggregationTimeseriesDao; import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; @@ -59,6 +60,8 @@ public class JpaSqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao @Autowired private SqlPartitioningRepository partitioningRepository; + @Autowired + private KeyDictionaryDao keyDictionaryDao; private SqlTsPartitionDate tsFormat; @@ -83,7 +86,7 @@ public class JpaSqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao int dataPointDays = getDataPointDays(tsKvEntry, computeTtl(ttl)); savePartitionIfNotExist(tsKvEntry.getTs()); String strKey = tsKvEntry.getKey(); - Integer keyId = getOrSaveKeyId(strKey); + Integer keyId = keyDictionaryDao.getOrSaveKeyId(strKey); TsKvEntity entity = new TsKvEntity(); entity.setEntityId(entityId.getId()); entity.setTs(tsKvEntry.getTs()); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java index 128073323c..d7a6b45423 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/timescale/TimescaleTimeseriesDao.java @@ -33,6 +33,7 @@ import org.thingsboard.server.common.data.kv.ReadTsKvQueryResult; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.DaoUtil; +import org.thingsboard.server.dao.dictionary.KeyDictionaryDao; import org.thingsboard.server.dao.model.sql.AbstractTsKvEntity; import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; import org.thingsboard.server.dao.sql.TbSqlBlockingQueueParams; @@ -69,6 +70,9 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @Autowired protected InsertTsRepository insertRepository; + @Autowired + protected KeyDictionaryDao keyDictionaryDao; + protected TbSqlBlockingQueueWrapper tsQueue; @PostConstruct @@ -108,7 +112,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements public ListenableFuture save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) { int dataPointDays = getDataPointDays(tsKvEntry, computeTtl(ttl)); String strKey = tsKvEntry.getKey(); - Integer keyId = getOrSaveKeyId(strKey); + Integer keyId = keyDictionaryDao.getOrSaveKeyId(strKey); TimescaleTsKvEntity entity = new TimescaleTsKvEntity(); entity.setEntityId(entityId.getId()); entity.setTs(tsKvEntry.getTs()); @@ -130,7 +134,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements @Override public ListenableFuture remove(TenantId tenantId, EntityId entityId, DeleteTsKvQuery query) { String strKey = query.getKey(); - Integer keyId = getOrSaveKeyId(strKey); + Integer keyId = keyDictionaryDao.getOrSaveKeyId(strKey); return service.submit(() -> { tsKvRepository.delete( entityId.getId(), @@ -161,7 +165,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements private ReadTsKvQueryResult findAllAsyncWithLimit(EntityId entityId, ReadTsKvQuery query) { String strKey = query.getKey(); - Integer keyId = getOrSaveKeyId(strKey); + Integer keyId = keyDictionaryDao.getOrSaveKeyId(strKey); List timescaleTsKvEntities = tsKvRepository.findAllWithLimit( entityId.getId(), keyId, @@ -205,7 +209,7 @@ public class TimescaleTimeseriesDao extends AbstractSqlTimeseriesDao implements } private List switchAggregation(String key, long startTs, long endTs, long timeBucket, Aggregation aggregation, UUID entityId) { - Integer keyId = getOrSaveKeyId(key); + Integer keyId = keyDictionaryDao.getOrSaveKeyId(key); switch (aggregation) { case AVG: return aggregationRepository.findAvg(entityId, keyId, timeBucket, startTs, endTs); From 4c77a75ef63df33768dbb10ac4c38d3750ea05ca Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 5 Jan 2024 10:49:33 +0200 Subject: [PATCH 52/61] fixed tests --- .../java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java | 2 ++ .../org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java index 9693e2d10b..9b3818794e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/SqlTimeseriesDaoConfig.java @@ -16,6 +16,7 @@ package org.thingsboard.server.dao; import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; @@ -24,6 +25,7 @@ import org.thingsboard.server.dao.util.TbAutoConfiguration; @Configuration @TbAutoConfiguration +@ComponentScan({"org.thingsboard.server.dao.sqlts.dictionary"}) @EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.dictionary"}) @EntityScan({"org.thingsboard.server.dao.model.sqlts.dictionary"}) @EnableTransactionManagement diff --git a/dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java b/dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java index aa663bf208..64da0dd55d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dictionary/KeyDictionaryDao.java @@ -20,6 +20,6 @@ public interface KeyDictionaryDao { Integer getOrSaveKeyId(String strKey); - String getKey(Integer attributeKey); + String getKey(Integer keyId); } From a89985efdd4bad3ed6b81cf8113f74dda5974a90 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 5 Jan 2024 14:20:00 +0200 Subject: [PATCH 53/61] fixed AttributeKvRepository --- .../server/dao/sql/attributes/AttributeKvRepository.java | 4 ++-- .../server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java index a43be3e49d..f5487971c9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java @@ -42,12 +42,12 @@ public interface AttributeKvRepository extends JpaRepository findAllKeysByDeviceProfileId(@Param("tenantId") UUID tenantId, @Param("deviceProfileId") UUID deviceProfileId); - @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE entity_type = 'DEVICE' " + + @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE " + "AND entity_id in (SELECT id FROM device WHERE tenant_id = :tenantId limit 100) ORDER BY attribute_key", nativeQuery = true) List findAllKeysByTenantId(@Param("tenantId") UUID tenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java index 3c2a4cd228..90bb3bbed0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/dictionary/JpaKeyDictionaryDao.java @@ -84,8 +84,8 @@ public class JpaKeyDictionaryDao extends JpaAbstractDaoListeningExecutorService } @Override - public String getKey(Integer attributeKey) { - Optional byKeyId = keyDictionaryRepository.findByKeyId(attributeKey); + public String getKey(Integer keyId) { + Optional byKeyId = keyDictionaryRepository.findByKeyId(keyId); return byKeyId.map(KeyDictionaryEntry::getKey).orElse(null); } From 9619fb7fc5df1ec4cc0f348b2993cf43905d3c70 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 5 Jan 2024 14:23:12 +0200 Subject: [PATCH 54/61] fixed AttributeKvRepository --- .../server/dao/sql/attributes/AttributeKvRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java index f5487971c9..064fa1fdc7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/AttributeKvRepository.java @@ -43,12 +43,12 @@ public interface AttributeKvRepository extends JpaRepository findAllKeysByDeviceProfileId(@Param("tenantId") UUID tenantId, @Param("deviceProfileId") UUID deviceProfileId); @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE " + - "AND entity_id in (SELECT id FROM device WHERE tenant_id = :tenantId limit 100) ORDER BY attribute_key", nativeQuery = true) + "entity_id in (SELECT id FROM device WHERE tenant_id = :tenantId limit 100) ORDER BY attribute_key", nativeQuery = true) List findAllKeysByTenantId(@Param("tenantId") UUID tenantId); @Query(value = "SELECT DISTINCT attribute_key FROM attribute_kv WHERE " + From 56f9dce24244b4e8c6d7b516854bc19a65529100 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 9 Jan 2024 12:27:40 +0200 Subject: [PATCH 55/61] updated BaseAttributeService, InternalTelemetryService, RuleEngineTelemetryService to store old methods for backward compatibility --- .../main/data/upgrade/3.6.3/schema_update.sql | 100 +++++------------- .../controller/TelemetryController.java | 2 +- .../device/ClaimDevicesServiceImpl.java | 5 +- .../service/edge/rpc/EdgeGrpcService.java | 5 +- .../telemetry/BaseTelemetryProcessor.java | 2 +- .../DefaultTbEntityViewService.java | 5 +- .../install/SqlDatabaseUpgradeService.java | 60 +---------- .../ota/DefaultOtaPackageStateService.java | 5 +- .../state/DefaultDeviceStateService.java | 4 +- .../DefaultTbLocalSubscriptionService.java | 4 +- .../TbAttributeSubscriptionScope.java | 31 +++++- .../csv/AbstractBulkImportService.java | 3 +- .../DefaultTelemetrySubscriptionService.java | 95 ++++++++++++++++- .../telemetry/InternalTelemetryService.java | 7 ++ .../state/DefaultDeviceStateServiceTest.java | 23 ++-- .../dao/attributes/AttributesService.java | 22 ++++ .../server/dao/attributes/AttributeUtils.java | 6 ++ .../dao/attributes/BaseAttributesService.java | 57 +++++++++- .../attributes/CachedAttributesService.java | 36 +++++++ .../main/resources/sql/schema-entities.sql | 2 +- .../main/resources/sql/schema-timescale.sql | 2 +- dao/src/main/resources/sql/schema-ts-psql.sql | 2 +- .../api/RuleEngineTelemetryService.java | 37 +++++++ .../TbCopyAttributesToEntityViewNode.java | 13 +-- .../rule/engine/math/TbMathNode.java | 5 +- .../engine/telemetry/TbMsgAttributesNode.java | 18 ++-- .../telemetry/TbMsgDeleteAttributesNode.java | 16 +-- .../rule/engine/math/TbMathNodeTest.java | 4 +- .../rule/engine/profile/DeviceStateTest.java | 3 +- .../telemetry/TbMsgAttributesNodeTest.java | 9 +- .../TbMsgDeleteAttributesNodeTest.java | 3 +- 31 files changed, 380 insertions(+), 206 deletions(-) diff --git a/application/src/main/data/upgrade/3.6.3/schema_update.sql b/application/src/main/data/upgrade/3.6.3/schema_update.sql index 30d9fa3adb..e11c52f77f 100644 --- a/application/src/main/data/upgrade/3.6.3/schema_update.sql +++ b/application/src/main/data/upgrade/3.6.3/schema_update.sql @@ -21,14 +21,11 @@ $$ BEGIN -- in case of running the upgrade script a second time: IF EXISTS(SELECT 1 FROM information_schema.columns WHERE table_name = 'attribute_kv' and column_name='entity_type') THEN - IF EXISTS(SELECT 1 FROM pg_indexes WHERE indexname = 'idx_attribute_kv_by_key_and_last_update_ts') THEN - ALTER INDEX idx_attribute_kv_by_key_and_last_update_ts RENAME TO idx_attribute_kv_by_key_and_last_update_ts_old; - END IF; + ALTER INDEX IF EXISTS idx_attribute_kv_by_key_and_last_update_ts RENAME TO idx_attribute_kv_by_key_and_last_update_ts_old; IF EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'attribute_kv_pkey') THEN ALTER TABLE attribute_kv RENAME CONSTRAINT attribute_kv_pkey TO attribute_kv_pkey_old; END IF; - ALTER TABLE attribute_kv - RENAME TO attribute_kv_old; + ALTER TABLE attribute_kv RENAME TO attribute_kv_old; CREATE TABLE IF NOT EXISTS attribute_kv ( entity_id uuid, @@ -43,6 +40,8 @@ $$ CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_id, attribute_type, attribute_key) ); END IF; + DROP VIEW IF EXISTS device_info_view; + DROP VIEW IF EXISTS device_info_active_attribute_view; END; $$; @@ -51,14 +50,12 @@ DO $$ BEGIN IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'ts_kv_dictionary') THEN - ALTER TABLE ts_kv_dictionary - RENAME CONSTRAINT ts_key_id_pkey TO key_id_pkey; - ALTER TABLE ts_kv_dictionary - RENAME TO key_dictionary; + ALTER TABLE ts_kv_dictionary RENAME CONSTRAINT ts_key_id_pkey TO key_dictionary_id_pkey; + ALTER TABLE ts_kv_dictionary RENAME TO key_dictionary; ELSE CREATE TABLE IF NOT EXISTS key_dictionary( key varchar(255) NOT NULL, key_id serial UNIQUE, - CONSTRAINT key_id_pkey PRIMARY KEY (key) + CONSTRAINT key_dictionary_id_pkey PRIMARY KEY (key) ); END IF; END; @@ -83,83 +80,40 @@ $$ LANGUAGE plpgsql; -- insert keys into key_dictionary DO $$ -DECLARE - insert_record RECORD; - key_cursor refcursor; -BEGIN - IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'attribute_kv_old') THEN - OPEN key_cursor FOR SELECT DISTINCT attribute_key - FROM attribute_kv_old - ORDER BY attribute_key; - LOOP - FETCH key_cursor INTO insert_record; - EXIT WHEN NOT FOUND; - IF NOT EXISTS(SELECT key FROM key_dictionary WHERE key = insert_record.attribute_key) THEN - INSERT INTO key_dictionary(key) VALUES (insert_record.attribute_key); - END IF; - END LOOP; - CLOSE key_cursor; - END IF; -END; + BEGIN + IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'attribute_kv_old') THEN + INSERT INTO key_dictionary(key) SELECT DISTINCT attribute_key FROM attribute_kv_old ON CONFLICT DO NOTHING; + END IF; + END; $$; --- create procedure to migrate all rows from attribute_kv_old to attribute_kv -CREATE OR REPLACE PROCEDURE insert_into_attribute_kv(IN path_to_file varchar) - LANGUAGE plpgsql AS +-- migrate attributes from attribute_kv_old to attribute_kv +DO $$ DECLARE row_num_old integer; row_num integer; - attribute_scope_array text[]; BEGIN - attribute_scope_array := ARRAY['SERVER_SCOPE', 'CLIENT_SCOPE', 'SHARED_SCOPE']; IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'attribute_kv_old') THEN - EXECUTE format('COPY (SELECT records.entity_id AS entity_id, - to_attribute_type_id(records.attribute_type) AS attribute_type, - records.attribute_key AS attribute_key, - records.bool_v AS bool_v, - records.str_v AS str_v, - records.long_v AS long_v, - records.dbl_v AS dbl_v, - records.json_v AS json_v, - records.last_update_ts AS last_update_ts - FROM (SELECT entity_id, - attribute_type, - key_id AS attribute_key, - bool_v, - str_v, - long_v, - dbl_v, - json_v, - last_update_ts - FROM attribute_kv_old INNER JOIN key_dictionary ON (attribute_kv_old.attribute_key = key_dictionary.key) - WHERE attribute_type= ANY(%L)) AS records) TO %L;', attribute_scope_array, path_to_file); - EXECUTE format('COPY attribute_kv FROM %L', path_to_file); + INSERT INTO attribute_kv(entity_id, attribute_type, attribute_key, bool_v, str_v, long_v, dbl_v, json_v, last_update_ts) + SELECT a.entity_id, to_attribute_type_id(a.attribute_type), k.key_id, a.bool_v, a.str_v, a.long_v, a.dbl_v, a.json_v, a.last_update_ts + FROM attribute_kv_old a INNER JOIN key_dictionary k ON (a.attribute_key = k.key) + WHERE a.attribute_type IN ('SERVER_SCOPE', 'CLIENT_SCOPE', 'SHARED_SCOPE'); SELECT COUNT(*) INTO row_num_old FROM attribute_kv_old; SELECT COUNT(*) INTO row_num FROM attribute_kv; RAISE NOTICE 'Migrated % of % rows', row_num, row_num_old; + + IF row_num != 0 THEN + DROP TABLE IF EXISTS attribute_kv_old; + ELSE + RAISE EXCEPTION 'Table attribute_kv is empty'; + END IF; + + CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc); END IF; EXCEPTION WHEN others THEN ROLLBACK; RAISE EXCEPTION 'Error during COPY: %', SQLERRM; END -$$; - -CREATE OR REPLACE PROCEDURE drop_attribute_kv_old_table() - LANGUAGE plpgsql AS -$$ -DECLARE - row_num integer; -BEGIN - SELECT COUNT(*) INTO row_num FROM attribute_kv; - IF row_num != 0 then - DROP TABLE IF EXISTS attribute_kv_old; - DROP PROCEDURE IF EXISTS insert_into_attribute_kv(IN path_to_file varchar); - ELSE - RAISE EXCEPTION 'Table attribute_kv is empty'; - END IF; - RETURN; -END; -$$; - +$$; \ No newline at end of file diff --git a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java index e041975a15..3bde00c5f9 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TelemetryController.java @@ -631,7 +631,7 @@ public class TelemetryController extends BaseController { } SecurityUser user = getCurrentUser(); return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_ATTRIBUTES, entityIdSrc, (result, tenantId, entityId) -> { - tsSubService.saveAndNotify(tenantId, entityId, scope.name(), attributes, new FutureCallback() { + tsSubService.saveAndNotify(tenantId, entityId, scope, attributes, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { logAttributesUpdated(user, entityId, scope, attributes, null); diff --git a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java index 08852be7fa..882f5fade2 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java @@ -31,7 +31,6 @@ import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.CustomerId; @@ -187,7 +186,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { } SettableFuture result = SettableFuture.create(); telemetryService.saveAndNotify( - tenantId, savedDevice.getId(), DataConstants.SERVER_SCOPE, Collections.singletonList( + tenantId, savedDevice.getId(), AttributeScope.SERVER_SCOPE, Collections.singletonList( new BaseAttributeKvEntry(new BooleanDataEntry(CLAIM_ATTRIBUTE_NAME, true), System.currentTimeMillis()) ), new FutureCallback<>() { @@ -230,7 +229,7 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { } SettableFuture result = SettableFuture.create(); telemetryService.deleteAndNotify(device.getTenantId(), - device.getId(), DataConstants.SERVER_SCOPE, Arrays.asList(CLAIM_ATTRIBUTE_NAME, CLAIM_DATA_ATTRIBUTE_NAME), new FutureCallback<>() { + device.getId(), AttributeScope.SERVER_SCOPE, Arrays.asList(CLAIM_ATTRIBUTE_NAME, CLAIM_DATA_ATTRIBUTE_NAME), new FutureCallback<>() { @Override public void onSuccess(@Nullable Void tmp) { result.set(tmp); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 89cae58264..b57c85d982 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -29,6 +29,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.ResourceUtils; import org.thingsboard.server.common.data.edge.Edge; @@ -412,7 +413,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new LongDataEntry(key, value))), new AttributeSaveCallback(tenantId, edgeId, key, value)); } else { - tsSubService.saveAttrAndNotify(tenantId, edgeId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback(tenantId, edgeId, key, value)); + tsSubService.saveAttrAndNotify(tenantId, edgeId, AttributeScope.SERVER_SCOPE, key, value, new AttributeSaveCallback(tenantId, edgeId, key, value)); } } @@ -424,7 +425,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i Collections.singletonList(new BasicTsKvEntry(System.currentTimeMillis(), new BooleanDataEntry(key, value))), new AttributeSaveCallback(tenantId, edgeId, key, value)); } else { - tsSubService.saveAttrAndNotify(tenantId, edgeId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback(tenantId, edgeId, key, value)); + tsSubService.saveAttrAndNotify(tenantId, edgeId, AttributeScope.SERVER_SCOPE, key, value, new AttributeSaveCallback(tenantId, edgeId, key, value)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java index 51f3fac9f2..327048f27a 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/processor/telemetry/BaseTelemetryProcessor.java @@ -252,7 +252,7 @@ public abstract class BaseTelemetryProcessor extends BaseEdgeProcessor { JsonObject json = JsonUtils.getJsonObject(msg.getKvList()); List attributes = new ArrayList<>(JsonConverter.convertToAttributes(json)); String scope = metaData.getValue("scope"); - tsSubService.saveAndNotify(tenantId, entityId, scope, attributes, new FutureCallback() { + tsSubService.saveAndNotify(tenantId, entityId, AttributeScope.valueOf(scope), attributes, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { var defaultQueueAndRuleChain = getDefaultQueueNameAndRuleChainId(tenantId, entityId); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java index 665735cc22..a214a88d3e 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java @@ -26,7 +26,6 @@ import org.springframework.stereotype.Service; import org.springframework.util.ConcurrentReferenceHashMap; import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.User; @@ -288,7 +287,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen (startTime == 0 && endTime > lastUpdateTs) || (startTime < lastUpdateTs && endTime > lastUpdateTs); }).collect(Collectors.toList()); - tsSubService.saveAndNotify(entityView.getTenantId(), entityId, scope.name(), attributes, new FutureCallback() { + tsSubService.saveAndNotify(entityView.getTenantId(), entityId, scope, attributes, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { try { @@ -356,7 +355,7 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen EntityViewId entityId = entityView.getId(); SettableFuture resultFuture = SettableFuture.create(); if (keys != null && !keys.isEmpty()) { - tsSubService.deleteAndNotify(entityView.getTenantId(), entityId, scope.name(), keys, new FutureCallback() { + tsSubService.deleteAndNotify(entityView.getTenantId(), entityId, scope, keys, new FutureCallback() { @Override public void onSuccess(@Nullable Void tmp) { try { diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index e3927b376a..cbd8686918 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -779,31 +779,7 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService }); break; case "3.6.3": - updateSchema("3.6.3", 3006003, "3.7.0", 3007000, connection -> { - try { - Path pathToTempAttributeKvFile; - if (SystemUtils.IS_OS_WINDOWS) { - pathToTempAttributeKvFile = createTempFileWindows("attribute_kv_temp",".sql"); - } else { - pathToTempAttributeKvFile = createTempFile("attribute_kv", "attribute_kv_temp.sql"); - } - executeQuery(connection, "call insert_into_attribute_kv('" + pathToTempAttributeKvFile + "')"); - - // remove attribute_kv_old - executeQuery(connection, "call drop_attribute_kv_old_table()"); - - //create index for new table attribute_kv - executeQuery(connection, "CREATE INDEX IF NOT EXISTS idx_attribute_kv_by_key_and_last_update_ts ON attribute_kv(entity_id, attribute_key, last_update_ts desc);"); - - // remove temp files - boolean deleteTsKvFile = Files.deleteIfExists(pathToTempAttributeKvFile); - if (deleteTsKvFile) { - log.info("Successfully deleted the temp file for attribute_kv table upgrade!"); - } - } catch (Exception e) { - log.error("Failed updating schema!!!", e); - } - }); + updateSchema("3.6.3", 3006003, "3.7.0", 3007000, null); break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); @@ -829,40 +805,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } } - private static Path createTempFile(String tempDirectoryName, String tempFileName) throws IOException { - Path pathToTempAttributeKvFile; - Path tempDirPath = Files.createTempDirectory(tempDirectoryName); - File tempDirAsFile = tempDirPath.toFile(); - boolean writable = tempDirAsFile.setWritable(true, false); - boolean readable = tempDirAsFile.setReadable(true, false); - boolean executable = tempDirAsFile.setExecutable(true, false); - pathToTempAttributeKvFile = tempDirPath.resolve(tempFileName).toAbsolutePath(); - - if (!(writable && readable && executable)) { - throw new RuntimeException("Failed to grant write permissions for the: " + tempDirPath + "folder!"); - } - return pathToTempAttributeKvFile; - } - - private static Path createTempFileWindows(String prefix, String suffix) throws IOException { - Path pathToTempAttributeKvFile; - log.info("Lookup for environment variable: {} ...", THINGSBOARD_WINDOWS_UPGRADE_DIR); - Path pathToDir; - String thingsboardWindowsUpgradeDir = System.getenv("THINGSBOARD_WINDOWS_UPGRADE_DIR"); - if (StringUtils.isNotEmpty(thingsboardWindowsUpgradeDir)) { - log.info("Environment variable: {} was found!", THINGSBOARD_WINDOWS_UPGRADE_DIR); - pathToDir = Paths.get(thingsboardWindowsUpgradeDir); - } else { - log.info("Failed to lookup environment variable: {}", THINGSBOARD_WINDOWS_UPGRADE_DIR); - pathToDir = Paths.get(PATH_TO_USERS_PUBLIC_FOLDER); - } - log.info("Directory: {} will be used for creation temporary upgrade files!", pathToDir); - - Path attributeKvFile = Files.createTempFile(pathToDir, prefix, suffix); - pathToTempAttributeKvFile = attributeKvFile.toAbsolutePath(); - return pathToTempAttributeKvFile; - } - private void runSchemaUpdateScript(Connection connection, String version) throws Exception { Path schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", version, SCHEMA_UPDATE_SQL); loadSql(schemaUpdateFile, connection); diff --git a/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java b/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java index 70c6655620..adaa6012de 100644 --- a/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/ota/DefaultOtaPackageStateService.java @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.msg.rule.engine.DeviceAttributesEventNotificationMsg; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.DataConstants; @@ -335,7 +336,7 @@ public class DefaultOtaPackageStateService implements OtaPackageStateService { remove(device, otaPackageType, attrToRemove); - telemetryService.saveAndNotify(tenantId, deviceId, DataConstants.SHARED_SCOPE, attributes, new FutureCallback<>() { + telemetryService.saveAndNotify(tenantId, deviceId, AttributeScope.SHARED_SCOPE, attributes, new FutureCallback<>() { @Override public void onSuccess(@Nullable Void tmp) { log.trace("[{}] Success save attributes with target firmware!", deviceId); @@ -353,7 +354,7 @@ public class DefaultOtaPackageStateService implements OtaPackageStateService { } private void remove(Device device, OtaPackageType otaPackageType, List attributesKeys) { - telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, attributesKeys, + telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), AttributeScope.SHARED_SCOPE, attributesKeys, new FutureCallback<>() { @Override public void onSuccess(@Nullable Void tmp) { diff --git a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java index 0affb51fc4..d127259099 100644 --- a/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java +++ b/application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java @@ -806,7 +806,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService(deviceId, key, value)); } else { - tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); + tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, AttributeScope.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); } } @@ -817,7 +817,7 @@ public class DefaultDeviceStateService extends AbstractPartitionBasedService(deviceId, key, value)); } else { - tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); + tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, AttributeScope.SERVER_SCOPE, key, value, new TelemetrySaveCallback<>(deviceId, key, value)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java index a6d5716d2b..c2b218197d 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java @@ -449,8 +449,8 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer } final Map keyStates = subscription.getKeyStates(); AttributeScope scope; - if (subscription.getScope() != null && !TbAttributeSubscriptionScope.ANY_SCOPE.equals(subscription.getScope())) { - scope = AttributeScope.valueOf(subscription.getScope().name()); + if (subscription.getScope() != null && subscription.getScope().getAttributeScope() != null) { + scope = subscription.getScope().getAttributeScope(); } else { scope = AttributeScope.CLIENT_SCOPE; } diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAttributeSubscriptionScope.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAttributeSubscriptionScope.java index b3874e28fb..ed2558dd42 100644 --- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAttributeSubscriptionScope.java +++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAttributeSubscriptionScope.java @@ -15,8 +15,37 @@ */ package org.thingsboard.server.service.subscription; +import org.thingsboard.server.common.data.AttributeScope; + public enum TbAttributeSubscriptionScope { - ANY_SCOPE, CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE + ANY_SCOPE(), + CLIENT_SCOPE(AttributeScope.CLIENT_SCOPE), + SHARED_SCOPE(AttributeScope.SHARED_SCOPE), + SERVER_SCOPE(AttributeScope.SERVER_SCOPE); + + private final AttributeScope attributeScope; + + TbAttributeSubscriptionScope() { + this.attributeScope = null; + } + + TbAttributeSubscriptionScope(AttributeScope attributeScope) { + this.attributeScope = attributeScope; + } + + public AttributeScope getAttributeScope() { + return attributeScope; + } + + public static TbAttributeSubscriptionScope of(AttributeScope attributeScope) { + for (TbAttributeSubscriptionScope scope : TbAttributeSubscriptionScope.values()) { + if (attributeScope == scope.getAttributeScope()) { + return scope; + } + } + throw new IllegalArgumentException("Unknown AttributeScope: " + attributeScope.name()); + } + } diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java index 68c0347b40..5b2e458c59 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/csv/AbstractBulkImportService.java @@ -29,6 +29,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.HasAdditionalInfo; import org.thingsboard.server.common.data.HasTenantId; @@ -230,7 +231,7 @@ public abstract class AbstractBulkImportService attributes = new ArrayList<>(JsonConverter.convertToAttributes(kvsEntry.getValue())); accessValidator.validateEntityAndCallback(user, Operation.WRITE_ATTRIBUTES, entity.getId(), (result, tenantId, entityId) -> { - tsSubscriptionService.saveAndNotify(tenantId, entityId, scope, attributes, new FutureCallback<>() { + tsSubscriptionService.saveAndNotify(tenantId, entityId, AttributeScope.valueOf(scope), attributes, new FutureCallback<>() { @Override public void onSuccess(Void unused) { diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java index b01b103007..531f518579 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java @@ -242,19 +242,38 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer saveAndNotify(tenantId, entityId, scope, attributes, true, callback); } + @Override + + public void saveAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes, FutureCallback callback) { + saveAndNotify(tenantId, entityId, scope, attributes, true, callback); + } + @Override public void saveAndNotify(TenantId tenantId, EntityId entityId, String scope, List attributes, boolean notifyDevice, FutureCallback callback) { checkInternalEntity(entityId); saveAndNotifyInternal(tenantId, entityId, scope, attributes, notifyDevice, callback); } + @Override + public void saveAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes, boolean notifyDevice, FutureCallback callback) { + checkInternalEntity(entityId); + saveAndNotifyInternal(tenantId, entityId, scope, attributes, notifyDevice, callback); + } + @Override public void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List attributes, boolean notifyDevice, FutureCallback callback) { - ListenableFuture> saveFuture = attrService.save(tenantId, entityId, AttributeScope.valueOf(scope), attributes); + ListenableFuture> saveFuture = attrService.save(tenantId, entityId, scope, attributes); addVoidCallback(saveFuture, callback); addWsCallback(saveFuture, success -> onAttributesUpdate(tenantId, entityId, scope, attributes, notifyDevice)); } + @Override + public void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes, boolean notifyDevice, FutureCallback callback) { + ListenableFuture> saveFuture = attrService.save(tenantId, entityId, scope, attributes); + addVoidCallback(saveFuture, callback); + addWsCallback(saveFuture, success -> onAttributesUpdate(tenantId, entityId, scope.name(), attributes, notifyDevice)); + } + @Override public void saveLatestAndNotify(TenantId tenantId, EntityId entityId, List ts, FutureCallback callback) { checkInternalEntity(entityId); @@ -274,19 +293,38 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer deleteAndNotifyInternal(tenantId, entityId, scope, keys, false, callback); } + @Override + public void deleteAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List keys, FutureCallback callback) { + checkInternalEntity(entityId); + deleteAndNotifyInternal(tenantId, entityId, scope, keys, false, callback); + } + @Override public void deleteAndNotify(TenantId tenantId, EntityId entityId, String scope, List keys, boolean notifyDevice, FutureCallback callback) { checkInternalEntity(entityId); deleteAndNotifyInternal(tenantId, entityId, scope, keys, notifyDevice, callback); } + @Override + public void deleteAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List keys, boolean notifyDevice, FutureCallback callback) { + checkInternalEntity(entityId); + deleteAndNotifyInternal(tenantId, entityId, scope, keys, notifyDevice, callback); + } + @Override public void deleteAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List keys, boolean notifyDevice, FutureCallback callback) { - ListenableFuture> deleteFuture = attrService.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), keys); + ListenableFuture> deleteFuture = attrService.removeAll(tenantId, entityId, scope, keys); addVoidCallback(deleteFuture, callback); addWsCallback(deleteFuture, success -> onAttributesDelete(tenantId, entityId, scope, keys, notifyDevice)); } + @Override + public void deleteAndNotifyInternal(TenantId tenantId, EntityId entityId, AttributeScope scope, List keys, boolean notifyDevice, FutureCallback callback) { + ListenableFuture> deleteFuture = attrService.removeAll(tenantId, entityId, scope, keys); + addVoidCallback(deleteFuture, callback); + addWsCallback(deleteFuture, success -> onAttributesDelete(tenantId, entityId, scope.name(), keys, notifyDevice)); + } + @Override public void deleteLatest(TenantId tenantId, EntityId entityId, List keys, FutureCallback callback) { checkInternalEntity(entityId); @@ -328,24 +366,49 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer , System.currentTimeMillis())), callback); } + + @Override + public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, long value, FutureCallback callback) { + saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new LongDataEntry(key, value) + , System.currentTimeMillis())), callback); + } + @Override public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, String value, FutureCallback callback) { saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry(key, value) , System.currentTimeMillis())), callback); } + @Override + public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, String value, FutureCallback callback) { + saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry(key, value) + , System.currentTimeMillis())), callback); + } + @Override public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, double value, FutureCallback callback) { saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new DoubleDataEntry(key, value) , System.currentTimeMillis())), callback); } + @Override + public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, double value, FutureCallback callback) { + saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new DoubleDataEntry(key, value) + , System.currentTimeMillis())), callback); + } + @Override public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, boolean value, FutureCallback callback) { saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new BooleanDataEntry(key, value) , System.currentTimeMillis())), callback); } + @Override + public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, boolean value, FutureCallback callback) { + saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new BooleanDataEntry(key, value) + , System.currentTimeMillis())), callback); + } + @Override public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, long value) { SettableFuture future = SettableFuture.create(); @@ -353,6 +416,13 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer return future; } + @Override + public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, long value) { + SettableFuture future = SettableFuture.create(); + saveAttrAndNotify(tenantId, entityId, scope, key, value, new VoidFutureCallback(future)); + return future; + } + @Override public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, String value) { SettableFuture future = SettableFuture.create(); @@ -360,6 +430,13 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer return future; } + @Override + public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, String value) { + SettableFuture future = SettableFuture.create(); + saveAttrAndNotify(tenantId, entityId, scope, key, value, new VoidFutureCallback(future)); + return future; + } + @Override public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, double value) { SettableFuture future = SettableFuture.create(); @@ -367,6 +444,13 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer return future; } + @Override + public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, double value) { + SettableFuture future = SettableFuture.create(); + saveAttrAndNotify(tenantId, entityId, scope, key, value, new VoidFutureCallback(future)); + return future; + } + @Override public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, boolean value) { SettableFuture future = SettableFuture.create(); @@ -374,6 +458,13 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer return future; } + @Override + public ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, boolean value) { + SettableFuture future = SettableFuture.create(); + saveAttrAndNotify(tenantId, entityId, scope, key, value, new VoidFutureCallback(future)); + return future; + } + private void onAttributesUpdate(TenantId tenantId, EntityId entityId, String scope, List attributes, boolean notifyDevice) { forwardToSubscriptionManagerService(tenantId, entityId, subscriptionManagerService -> { subscriptionManagerService.onAttributesUpdate(tenantId, entityId, scope, attributes, notifyDevice, TbCallback.EMPTY); diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/InternalTelemetryService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/InternalTelemetryService.java index 301376b16a..5d451d4b32 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/InternalTelemetryService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/InternalTelemetryService.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.telemetry; import com.google.common.util.concurrent.FutureCallback; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -33,12 +34,18 @@ public interface InternalTelemetryService extends RuleEngineTelemetryService { void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, List ts, long ttl, FutureCallback callback); + @Deprecated(since = "3.7.0") void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List attributes, boolean notifyDevice, FutureCallback callback); + void saveAndNotifyInternal(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes, boolean notifyDevice, FutureCallback callback); + void saveLatestAndNotifyInternal(TenantId tenantId, EntityId entityId, List ts, FutureCallback callback); + @Deprecated(since = "3.7.0") void deleteAndNotifyInternal(TenantId tenantId, EntityId entityId, String scope, List keys, boolean notifyDevice, FutureCallback callback); + void deleteAndNotifyInternal(TenantId tenantId, EntityId entityId, AttributeScope scope, List keys, boolean notifyDevice, FutureCallback callback); + void deleteLatestInternal(TenantId tenantId, EntityId entityId, List keys, FutureCallback callback); } diff --git a/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java b/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java index 05624b8741..8bba931a0a 100644 --- a/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/state/DefaultDeviceStateServiceTest.java @@ -26,6 +26,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.test.util.ReflectionTestUtils; import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DeviceIdInfo; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; @@ -251,7 +252,7 @@ public class DefaultDeviceStateServiceTest { long newTimeout = System.currentTimeMillis() - deviceState.getLastActivityTime() + increase; service.onDeviceInactivityTimeoutUpdate(tenantId, deviceId, newTimeout); - verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(), eq(ACTIVITY_STATE), any(), any()); + verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(AttributeScope.class), eq(ACTIVITY_STATE), any(), any()); Thread.sleep(defaultTimeout + increase); service.checkStates(); activityVerify(false); @@ -290,7 +291,7 @@ public class DefaultDeviceStateServiceTest { long newTimeout = 1; Thread.sleep(newTimeout); - verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(), eq(ACTIVITY_STATE), any(), any()); + verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(AttributeScope.class), eq(ACTIVITY_STATE), any(), any()); } @Test @@ -311,7 +312,7 @@ public class DefaultDeviceStateServiceTest { service.onDeviceActivity(tenantId, deviceId, System.currentTimeMillis()); activityVerify(true); - verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(), eq(ACTIVITY_STATE), any(), any()); + verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(AttributeScope.class), eq(ACTIVITY_STATE), any(), any()); long newTimeout = 1; Thread.sleep(newTimeout); @@ -352,11 +353,11 @@ public class DefaultDeviceStateServiceTest { long newTimeout = 1; service.onDeviceInactivityTimeoutUpdate(tenantId, deviceId, newTimeout); - verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(), eq(ACTIVITY_STATE), any(), any()); + verify(telemetrySubscriptionService, never()).saveAttrAndNotify(any(), eq(deviceId), any(AttributeScope.class), eq(ACTIVITY_STATE), any(), any()); } private void activityVerify(boolean isActive) { - verify(telemetrySubscriptionService, times(1)).saveAttrAndNotify(any(), eq(deviceId), any(), eq(ACTIVITY_STATE), eq(isActive), any()); + verify(telemetrySubscriptionService, times(1)).saveAttrAndNotify(any(), eq(deviceId), any(AttributeScope.class), eq(ACTIVITY_STATE), eq(isActive), any()); } @Test @@ -403,19 +404,19 @@ public class DefaultDeviceStateServiceTest { assertThat(deviceState.isActive()).isEqualTo(true); assertThat(deviceState.getLastActivityTime()).isEqualTo(lastReportedActivity); then(telemetrySubscriptionService).should().saveAttrAndNotify( - any(), eq(deviceId), any(), eq(LAST_ACTIVITY_TIME), eq(lastReportedActivity), any() + any(), eq(deviceId), any(AttributeScope.class), eq(LAST_ACTIVITY_TIME), eq(lastReportedActivity), any() ); assertThat(deviceState.getLastInactivityAlarmTime()).isEqualTo(expectedInactivityAlarmTime); if (shouldSetInactivityAlarmTimeToZero) { then(telemetrySubscriptionService).should().saveAttrAndNotify( - any(), eq(deviceId), any(), eq(INACTIVITY_ALARM_TIME), eq(0L), any() + any(), eq(deviceId), any(AttributeScope.class), eq(INACTIVITY_ALARM_TIME), eq(0L), any() ); } if (shouldUpdateActivityStateToActive) { then(telemetrySubscriptionService).should().saveAttrAndNotify( - eq(TenantId.SYS_TENANT_ID), eq(deviceId), eq(SERVER_SCOPE), eq(ACTIVITY_STATE), eq(true), any() + eq(TenantId.SYS_TENANT_ID), eq(deviceId), eq(AttributeScope.SERVER_SCOPE), eq(ACTIVITY_STATE), eq(true), any() ); var msgCaptor = ArgumentCaptor.forClass(TbMsg.class); @@ -497,7 +498,7 @@ public class DefaultDeviceStateServiceTest { assertThat(deviceState.isActive()).isEqualTo(expectedActivityState); if (activityState && !expectedActivityState) { then(telemetrySubscriptionService).should().saveAttrAndNotify( - any(), eq(deviceId), any(), eq(ACTIVITY_STATE), eq(false), any() + any(), eq(deviceId), any(AttributeScope.class), eq(ACTIVITY_STATE), eq(false), any() ); } } @@ -594,7 +595,7 @@ public class DefaultDeviceStateServiceTest { if (shouldUpdateActivityStateToInactive) { then(telemetrySubscriptionService).should().saveAttrAndNotify( - eq(TenantId.SYS_TENANT_ID), eq(deviceId), eq(SERVER_SCOPE), eq(ACTIVITY_STATE), eq(false), any() + eq(TenantId.SYS_TENANT_ID), eq(deviceId), eq(AttributeScope.SERVER_SCOPE), eq(ACTIVITY_STATE), eq(false), any() ); var msgCaptor = ArgumentCaptor.forClass(TbMsg.class); @@ -611,7 +612,7 @@ public class DefaultDeviceStateServiceTest { assertThat(actualNotification.isActive()).isFalse(); then(telemetrySubscriptionService).should().saveAttrAndNotify( - eq(TenantId.SYS_TENANT_ID), eq(deviceId), eq(SERVER_SCOPE), + eq(TenantId.SYS_TENANT_ID), eq(deviceId), eq(AttributeScope.SERVER_SCOPE), eq(INACTIVITY_ALARM_TIME), eq(expectedLastInactivityAlarmTime), any() ); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java index ccbc90825a..d7c6f5981e 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/attributes/AttributesService.java @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.attributes; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.AttributeScope; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -31,20 +32,41 @@ import java.util.Optional; */ public interface AttributesService { + @Deprecated(since = "3.7.0") + ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey); + ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, String attributeKey); + @Deprecated(since = "3.7.0") + ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys); + ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, Collection attributeKeys); + @Deprecated(since = "3.7.0") + ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope); + ListenableFuture> findAll(TenantId tenantId, EntityId entityId, AttributeScope scope); + @Deprecated(since = "3.7.0") + ListenableFuture> save(TenantId tenantId, EntityId entityId, String scope, List attributes); + ListenableFuture> save(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes); + @Deprecated(since = "3.7.0") + ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute); + ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope scope, AttributeKvEntry attribute); + @Deprecated(since = "3.7.0") + ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys); + ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributeKeys); List findAllKeysByDeviceProfileId(TenantId tenantId, DeviceProfileId deviceProfileId); + @Deprecated(since = "3.7.0") + List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds); + List findAllKeysByEntityIds(TenantId tenantId, List entityIds); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java index 983661ff6e..7077edac40 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/AttributeUtils.java @@ -26,6 +26,12 @@ import java.util.List; public class AttributeUtils { + @Deprecated(since = "3.7.0") + public static void validate(EntityId id, String scope) { + Validator.validateId(id.getId(), "Incorrect id " + id); + Validator.validateString(scope, "Incorrect scope " + scope); + } + public static void validate(EntityId id, AttributeScope scope) { Validator.validateId(id.getId(), "Incorrect id " + id); Validator.checkNotNull(scope, "Incorrect scope " + scope); diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java index 3f8c88d609..84b504ca6e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/BaseAttributesService.java @@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.AttributeScope; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -53,6 +54,13 @@ public class BaseAttributesService implements AttributesService { this.attributesDao = attributesDao; } + @Override + public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey) { + validate(entityId, scope); + Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey); + return Futures.immediateFuture(attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKey)); + } + @Override public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, String attributeKey) { validate(entityId, scope); @@ -60,17 +68,30 @@ public class BaseAttributesService implements AttributesService { return Futures.immediateFuture(attributesDao.find(tenantId, entityId, scope, attributeKey)); } + @Override + public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys) { + validate(entityId, scope); + attributeKeys.forEach(attributeKey -> Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey)); + return Futures.immediateFuture(attributesDao.find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys)); + } + @Override public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, Collection attributeKeys) { validate(entityId, scope); attributeKeys.forEach(attributeKey -> Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey)); - return Futures.immediateFuture(attributesDao.find(tenantId, entityId, scope, attributeKeys)); + return Futures.immediateFuture(attributesDao.find(tenantId, entityId, scope, attributeKeys)); + } + + @Override + public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope) { + validate(entityId, scope); + return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, AttributeScope.valueOf(scope))); } @Override public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, AttributeScope scope) { validate(entityId, scope); - return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, scope)); + return Futures.immediateFuture(attributesDao.findAll(tenantId, entityId, scope)); } @Override @@ -78,29 +99,55 @@ public class BaseAttributesService implements AttributesService { return attributesDao.findAllKeysByDeviceProfileId(tenantId, deviceProfileId); } + @Override + public List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds) { + return attributesDao.findAllKeysByEntityIds(tenantId, entityIds); + } + @Override public List findAllKeysByEntityIds(TenantId tenantId, List entityIds) { return attributesDao.findAllKeysByEntityIds(tenantId, entityIds); } + @Override + public ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute) { + validate(entityId, scope); + AttributeUtils.validate(attribute, valueNoXssValidation); + return attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); + } + @Override public ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope scope, AttributeKvEntry attribute) { validate(entityId, scope); AttributeUtils.validate(attribute, valueNoXssValidation); - return attributesDao.save(tenantId, entityId, scope, attribute); + return attributesDao.save(tenantId, entityId, scope, attribute); + } + + @Override + public ListenableFuture> save(TenantId tenantId, EntityId entityId, String scope, List attributes) { + validate(entityId, scope); + AttributeUtils.validate(attributes, valueNoXssValidation); + List> saveFutures = attributes.stream().map(attribute -> attributesDao.save(tenantId, entityId, AttributeScope.valueOf(scope), attribute)).collect(Collectors.toList()); + return Futures.allAsList(saveFutures); } @Override public ListenableFuture> save(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes) { validate(entityId, scope); AttributeUtils.validate(attributes, valueNoXssValidation); - List> saveFutures = attributes.stream().map(attribute -> attributesDao.save(tenantId, entityId, scope, attribute)).collect(Collectors.toList()); + List> saveFutures = attributes.stream().map(attribute -> attributesDao.save(tenantId, entityId, scope, attribute)).collect(Collectors.toList()); return Futures.allAsList(saveFutures); } + @Override + public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys) { + validate(entityId, scope); + return Futures.allAsList(attributesDao.removeAll(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys)); + } + @Override public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributeKeys) { validate(entityId, scope); - return Futures.allAsList(attributesDao.removeAll(tenantId, entityId, scope, attributeKeys)); + return Futures.allAsList(attributesDao.removeAll(tenantId, entityId, scope, attributeKeys)); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java index 6029be94c9..f87827b535 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java @@ -27,6 +27,7 @@ import org.springframework.stereotype.Service; import org.thingsboard.server.cache.TbCacheValueWrapper; import org.thingsboard.server.cache.TbTransactionalCache; import org.thingsboard.server.common.data.AttributeScope; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; @@ -108,6 +109,11 @@ public class CachedAttributesService implements AttributesService { } + @Override + public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey) { + return find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKey); + } + @Override public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, String attributeKey) { validate(entityId, scope); @@ -137,6 +143,11 @@ public class CachedAttributesService implements AttributesService { } } + @Override + public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys) { + return find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys); + } + @Override public ListenableFuture> find(TenantId tenantId, EntityId entityId, AttributeScope scope, final Collection attributeKeysNonUnique) { validate(entityId, scope); @@ -204,6 +215,11 @@ public class CachedAttributesService implements AttributesService { return cachedAttributes; } + @Override + public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, String scope) { + return findAll(tenantId, entityId, AttributeScope.valueOf(scope)); + } + @Override public ListenableFuture> findAll(TenantId tenantId, EntityId entityId, AttributeScope scope) { validate(entityId, scope); @@ -215,11 +231,21 @@ public class CachedAttributesService implements AttributesService { return attributesDao.findAllKeysByDeviceProfileId(tenantId, deviceProfileId); } + @Override + public List findAllKeysByEntityIds(TenantId tenantId, EntityType entityType, List entityIds) { + return findAllKeysByEntityIds(tenantId, entityIds); + } + @Override public List findAllKeysByEntityIds(TenantId tenantId, List entityIds) { return attributesDao.findAllKeysByEntityIds(tenantId, entityIds); } + @Override + public ListenableFuture save(TenantId tenantId, EntityId entityId, String scope, AttributeKvEntry attribute) { + return save(tenantId, entityId, AttributeScope.valueOf(scope), attribute); + } + @Override public ListenableFuture save(TenantId tenantId, EntityId entityId, AttributeScope scope, AttributeKvEntry attribute) { validate(entityId, scope); @@ -228,6 +254,11 @@ public class CachedAttributesService implements AttributesService { return Futures.transform(future, key -> evict(entityId, scope, attribute, key), cacheExecutor); } + @Override + public ListenableFuture> save(TenantId tenantId, EntityId entityId, String scope, List attributes) { + return save(tenantId, entityId, scope, attributes); + } + @Override public ListenableFuture> save(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes) { validate(entityId, scope); @@ -249,6 +280,11 @@ public class CachedAttributesService implements AttributesService { return key; } + @Override + public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, String scope, List attributeKeys) { + return removeAll(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys); + } + @Override public ListenableFuture> removeAll(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributeKeys) { validate(entityId, scope); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index c0a3815dc2..056201a56e 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -551,7 +551,7 @@ CREATE TABLE IF NOT EXISTS key_dictionary ( key varchar(255) NOT NULL, key_id serial UNIQUE, - CONSTRAINT key_id_pkey PRIMARY KEY (key) + CONSTRAINT key_dictionary_id_pkey PRIMARY KEY (key) ); CREATE TABLE IF NOT EXISTS oauth2_params ( diff --git a/dao/src/main/resources/sql/schema-timescale.sql b/dao/src/main/resources/sql/schema-timescale.sql index 380f813680..caeadbe12e 100644 --- a/dao/src/main/resources/sql/schema-timescale.sql +++ b/dao/src/main/resources/sql/schema-timescale.sql @@ -31,7 +31,7 @@ CREATE TABLE IF NOT EXISTS ts_kv ( CREATE TABLE IF NOT EXISTS key_dictionary ( key varchar(255) NOT NULL, key_id serial UNIQUE, - CONSTRAINT key_id_pkey PRIMARY KEY (key) + CONSTRAINT key_dictionary_id_pkey PRIMARY KEY (key) ); CREATE TABLE IF NOT EXISTS ts_kv_latest ( diff --git a/dao/src/main/resources/sql/schema-ts-psql.sql b/dao/src/main/resources/sql/schema-ts-psql.sql index bd9713c104..69932e130f 100644 --- a/dao/src/main/resources/sql/schema-ts-psql.sql +++ b/dao/src/main/resources/sql/schema-ts-psql.sql @@ -31,7 +31,7 @@ CREATE TABLE IF NOT EXISTS key_dictionary ( key varchar(255) NOT NULL, key_id serial UNIQUE, - CONSTRAINT key_id_pkey PRIMARY KEY (key) + CONSTRAINT key_dictionary_id_pkey PRIMARY KEY (key) ); CREATE OR REPLACE PROCEDURE drop_partitions_by_system_ttl(IN partition_type varchar, IN system_ttl bigint, INOUT deleted bigint) diff --git a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineTelemetryService.java b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineTelemetryService.java index a61e83f48f..c54c6aed04 100644 --- a/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineTelemetryService.java +++ b/rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineTelemetryService.java @@ -17,6 +17,7 @@ package org.thingsboard.rule.engine.api; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.ListenableFuture; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.TenantId; @@ -40,32 +41,68 @@ public interface RuleEngineTelemetryService { void saveWithoutLatestAndNotify(TenantId tenantId, CustomerId id, EntityId entityId, List ts, long ttl, FutureCallback callback); + @Deprecated(since = "3.7.0") void saveAndNotify(TenantId tenantId, EntityId entityId, String scope, List attributes, FutureCallback callback); + void saveAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes, FutureCallback callback); + + @Deprecated(since = "3.7.0") void saveAndNotify(TenantId tenantId, EntityId entityId, String scope, List attributes, boolean notifyDevice, FutureCallback callback); + void saveAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes, boolean notifyDevice, FutureCallback callback); + void saveLatestAndNotify(TenantId tenantId, EntityId entityId, List ts, FutureCallback callback); + @Deprecated(since = "3.7.0") ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, long value); + ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, long value); + + @Deprecated(since = "3.7.0") ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, String value); + ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, String value); + + @Deprecated(since = "3.7.0") ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, double value); + ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, double value); + + @Deprecated(since = "3.7.0") ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, boolean value); + ListenableFuture saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, boolean value); + + @Deprecated(since = "3.7.0") void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, long value, FutureCallback callback); + void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, long value, FutureCallback callback); + + @Deprecated(since = "3.7.0") void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, String value, FutureCallback callback); + void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, String value, FutureCallback callback); + + @Deprecated(since = "3.7.0") void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, double value, FutureCallback callback); + void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, double value, FutureCallback callback); + + @Deprecated(since = "3.7.0") void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, boolean value, FutureCallback callback); + void saveAttrAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, String key, boolean value, FutureCallback callback); + + @Deprecated(since = "3.7.0") void deleteAndNotify(TenantId tenantId, EntityId entityId, String scope, List keys, FutureCallback callback); + void deleteAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List keys, FutureCallback callback); + + @Deprecated(since = "3.7.0") void deleteAndNotify(TenantId tenantId, EntityId entityId, String scope, List keys, boolean notifyDevice, FutureCallback callback); + void deleteAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List keys, boolean notifyDevice, FutureCallback callback); + void deleteLatest(TenantId tenantId, EntityId entityId, List keys, FutureCallback callback); void deleteAllLatest(TenantId tenantId, EntityId entityId, FutureCallback> callback); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java index b1248c0856..14b368e8dc 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java @@ -29,6 +29,7 @@ import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -79,8 +80,8 @@ public class TbCopyAttributesToEntityViewNode implements TbNode { ACTIVITY_EVENT, INACTIVITY_EVENT, POST_ATTRIBUTES_REQUEST)) { if (!msg.getMetaData().getData().isEmpty()) { long now = System.currentTimeMillis(); - String scope = msg.isTypeOf(POST_ATTRIBUTES_REQUEST) ? - DataConstants.CLIENT_SCOPE : msg.getMetaData().getValue(DataConstants.SCOPE); + AttributeScope scope = msg.isTypeOf(POST_ATTRIBUTES_REQUEST) ? + AttributeScope.CLIENT_SCOPE : AttributeScope.valueOf(msg.getMetaData().getValue(DataConstants.SCOPE)); ListenableFuture> entityViewsFuture = ctx.getEntityViewService().findEntityViewsByTenantIdAndEntityIdAsync(ctx.getTenantId(), msg.getOriginator()); @@ -145,17 +146,17 @@ public class TbCopyAttributesToEntityViewNode implements TbNode { ctx.enqueueForTellNext(ctx.newMsg(msg.getQueueName(), msg.getType(), entityView.getId(), msg.getCustomerId(), msg.getMetaData(), msg.getData()), SUCCESS); } - private boolean attributeContainsInEntityView(String scope, String attrKey, EntityView entityView) { + private boolean attributeContainsInEntityView(AttributeScope scope, String attrKey, EntityView entityView) { AttributesEntityView attributesEntityView = entityView.getKeys().getAttributes(); List keys = null; switch (scope) { - case DataConstants.CLIENT_SCOPE: + case CLIENT_SCOPE: keys = attributesEntityView.getCs(); break; - case DataConstants.SERVER_SCOPE: + case SERVER_SCOPE: keys = attributesEntityView.getSs(); break; - case DataConstants.SHARED_SCOPE: + case SHARED_SCOPE: keys = attributesEntityView.getSh(); break; } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java index 455e5c8da7..4f25e0760f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/math/TbMathNode.java @@ -34,7 +34,6 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.AttributeScope; -import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; @@ -213,11 +212,11 @@ public class TbMathNode implements TbNode { if (isIntegerResult(mathResultDef, config.getOperation())) { var value = toIntValue(result); return ctx.getTelemetryService().saveAttrAndNotify( - ctx.getTenantId(), msg.getOriginator(), attributeScope.name(), mathResultDef.getKey(), value); + ctx.getTenantId(), msg.getOriginator(), attributeScope, mathResultDef.getKey(), value); } else { var value = toDoubleValue(mathResultDef, result); return ctx.getTelemetryService().saveAttrAndNotify( - ctx.getTenantId(), msg.getOriginator(), attributeScope.name(), mathResultDef.getKey(), value); + ctx.getTenantId(), msg.getOriginator(), attributeScope, mathResultDef.getKey(), value); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java index 5fa7f91b9f..c29dd67915 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java @@ -90,7 +90,7 @@ public class TbMsgAttributesNode implements TbNode { ctx.tellSuccess(msg); return; } - String scope = getScope(msg.getMetaData().getValue(SCOPE)); + AttributeScope scope = getScope(msg.getMetaData().getValue(SCOPE)); boolean sendAttributesUpdateNotification = checkSendNotification(scope); if (!config.isUpdateAttributesOnlyOnValueChange()) { @@ -99,7 +99,7 @@ public class TbMsgAttributesNode implements TbNode { } List keys = newAttributes.stream().map(KvEntry::getKey).collect(Collectors.toList()); - ListenableFuture> findFuture = ctx.getAttributesService().find(ctx.getTenantId(), msg.getOriginator(), AttributeScope.valueOf(scope), keys); + ListenableFuture> findFuture = ctx.getAttributesService().find(ctx.getTenantId(), msg.getOriginator(), scope, keys); DonAsynchron.withCallback(findFuture, currentAttributes -> { @@ -110,7 +110,7 @@ public class TbMsgAttributesNode implements TbNode { MoreExecutors.directExecutor()); } - void saveAttr(List attributes, TbContext ctx, TbMsg msg, String scope, boolean sendAttributesUpdateNotification) { + void saveAttr(List attributes, TbContext ctx, TbMsg msg, AttributeScope scope, boolean sendAttributesUpdateNotification) { if (attributes.isEmpty()) { ctx.tellSuccess(msg); return; @@ -122,7 +122,7 @@ public class TbMsgAttributesNode implements TbNode { attributes, config.isNotifyDevice() || checkNotifyDeviceMdValue(msg.getMetaData().getValue(NOTIFY_DEVICE_METADATA_KEY)), sendAttributesUpdateNotification ? - new AttributesUpdateNodeCallback(ctx, msg, scope, attributes) : + new AttributesUpdateNodeCallback(ctx, msg, scope.name(), attributes) : new TelemetryNodeCallback(ctx, msg) ); } @@ -145,8 +145,8 @@ public class TbMsgAttributesNode implements TbNode { .collect(Collectors.toList()); } - private boolean checkSendNotification(String scope) { - return config.isSendAttributesUpdatedNotification() && !CLIENT_SCOPE.equals(scope); + private boolean checkSendNotification(AttributeScope scope) { + return config.isSendAttributesUpdatedNotification() && AttributeScope.CLIENT_SCOPE != scope; } private boolean checkNotifyDeviceMdValue(String notifyDeviceMdValue) { @@ -154,11 +154,11 @@ public class TbMsgAttributesNode implements TbNode { return StringUtils.isEmpty(notifyDeviceMdValue) || Boolean.parseBoolean(notifyDeviceMdValue); } - private String getScope(String mdScopeValue) { + private AttributeScope getScope(String mdScopeValue) { if (StringUtils.isNotEmpty(mdScopeValue)) { - return mdScopeValue; + return AttributeScope.valueOf(mdScopeValue); } - return config.getScope(); + return AttributeScope.valueOf(config.getScope()); } @Override diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNode.java index 112a3c26dd..7d61d7782e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNode.java @@ -22,6 +22,7 @@ import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; import org.thingsboard.rule.engine.api.util.TbNodeUtils; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; @@ -32,7 +33,6 @@ import java.util.stream.Collectors; import static org.thingsboard.server.common.data.DataConstants.NOTIFY_DEVICE_METADATA_KEY; import static org.thingsboard.server.common.data.DataConstants.SCOPE; -import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE; @Slf4j @RuleNode( @@ -69,7 +69,7 @@ public class TbMsgDeleteAttributesNode implements TbNode { if (keysToDelete.isEmpty()) { ctx.tellSuccess(msg); } else { - String scope = getScope(msg.getMetaData().getValue(SCOPE)); + AttributeScope scope = getScope(msg.getMetaData().getValue(SCOPE)); ctx.getTelemetryService().deleteAndNotify( ctx.getTenantId(), msg.getOriginator(), @@ -77,21 +77,21 @@ public class TbMsgDeleteAttributesNode implements TbNode { keysToDelete, checkNotifyDevice(msg.getMetaData().getValue(NOTIFY_DEVICE_METADATA_KEY), scope), config.isSendAttributesDeletedNotification() ? - new AttributesDeleteNodeCallback(ctx, msg, scope, keysToDelete) : + new AttributesDeleteNodeCallback(ctx, msg, scope.name(), keysToDelete) : new TelemetryNodeCallback(ctx, msg) ); } } - private String getScope(String mdScopeValue) { + private AttributeScope getScope(String mdScopeValue) { if (StringUtils.isNotEmpty(mdScopeValue)) { - return mdScopeValue; + return AttributeScope.valueOf(mdScopeValue); } - return config.getScope(); + return AttributeScope.valueOf(config.getScope()); } - private boolean checkNotifyDevice(String notifyDeviceMdValue, String scope) { - return SHARED_SCOPE.equals(scope) && (config.isNotifyDevice() || Boolean.parseBoolean(notifyDeviceMdValue)); + private boolean checkNotifyDevice(String notifyDeviceMdValue, AttributeScope scope) { + return (AttributeScope.SHARED_SCOPE == scope) && (config.isNotifyDevice() || Boolean.parseBoolean(notifyDeviceMdValue)); } } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java index 8ee70f23d7..c4e7c46f3e 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/math/TbMathNodeTest.java @@ -438,14 +438,14 @@ public class TbMathNodeTest { TbMsg msg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, originator, TbMsgMetaData.EMPTY, JacksonUtil.newObjectNode().put("a", 5).toString()); - when(telemetryService.saveAttrAndNotify(any(), any(), anyString(), anyString(), anyDouble())) + when(telemetryService.saveAttrAndNotify(any(), any(), any(AttributeScope.class), anyString(), anyDouble())) .thenReturn(Futures.immediateFuture(null)); node.onMsg(ctx, msg); ArgumentCaptor msgCaptor = ArgumentCaptor.forClass(TbMsg.class); verify(ctx, timeout(TIMEOUT)).tellSuccess(msgCaptor.capture()); - verify(telemetryService, times(1)).saveAttrAndNotify(any(), any(), anyString(), anyString(), anyDouble()); + verify(telemetryService, times(1)).saveAttrAndNotify(any(), any(), any(AttributeScope.class), anyString(), anyDouble()); TbMsg resultMsg = msgCaptor.getValue(); assertNotNull(resultMsg); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/DeviceStateTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/DeviceStateTest.java index eef77a5304..e523313a63 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/DeviceStateTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/DeviceStateTest.java @@ -22,6 +22,7 @@ import org.mockito.ArgumentCaptor; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.RuleEngineAlarmService; import org.thingsboard.rule.engine.api.TbContext; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; @@ -75,7 +76,7 @@ public class DeviceStateTest { when(ctx.getDeviceService()).thenReturn(mock(DeviceService.class)); AttributesService attributesService = mock(AttributesService.class); - when(attributesService.find(any(), any(), any(), anyCollection())).thenReturn(Futures.immediateFuture(Collections.emptyList())); + when(attributesService.find(any(), any(), any(AttributeScope.class), anyCollection())).thenReturn(Futures.immediateFuture(Collections.emptyList())); when(ctx.getAttributesService()).thenReturn(attributesService); RuleEngineAlarmService alarmService = mock(RuleEngineAlarmService.class); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java index fe2edc941b..3efbb2f009 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNodeTest.java @@ -29,7 +29,7 @@ import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.server.common.data.DataConstants; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; @@ -54,7 +54,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.willCallRealMethod; import static org.mockito.Mockito.mock; @@ -157,7 +156,7 @@ class TbMsgAttributesNodeTest { when(ctxMock.getTenantId()).thenReturn(tenantId); when(ctxMock.getTelemetryService()).thenReturn(telemetryServiceMock); willCallRealMethod().given(node).init(any(TbContext.class), any(TbNodeConfiguration.class)); - willCallRealMethod().given(node).saveAttr(any(), eq(ctxMock), any(TbMsg.class), anyString(), anyBoolean()); + willCallRealMethod().given(node).saveAttr(any(), eq(ctxMock), any(TbMsg.class), any(AttributeScope.class), anyBoolean()); node.init(ctxMock, tbNodeConfiguration); @@ -169,12 +168,12 @@ class TbMsgAttributesNodeTest { var testTbMsg = TbMsg.newMsg(TbMsgType.POST_TELEMETRY_REQUEST, deviceId, md, TbMsg.EMPTY_STRING); List testAttrList = List.of(new BaseAttributeKvEntry(0L, new StringDataEntry("testKey", "testValue"))); - node.saveAttr(testAttrList, ctxMock, testTbMsg, DataConstants.SHARED_SCOPE, false); + node.saveAttr(testAttrList, ctxMock, testTbMsg, AttributeScope.SHARED_SCOPE, false); ArgumentCaptor notifyDeviceCaptor = ArgumentCaptor.forClass(Boolean.class); verify(telemetryServiceMock, times(1)).saveAndNotify( - eq(tenantId), eq(deviceId), eq(DataConstants.SHARED_SCOPE), + eq(tenantId), eq(deviceId), eq(AttributeScope.SHARED_SCOPE), eq(testAttrList), notifyDeviceCaptor.capture(), any() ); boolean notifyDevice = notifyDeviceCaptor.getValue(); diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java index 632243676f..f3fc7e6163 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java @@ -25,6 +25,7 @@ import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; +import org.thingsboard.server.common.data.AttributeScope; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.msg.TbMsgType; @@ -81,7 +82,7 @@ public class TbMsgDeleteAttributesNodeTest { callBack.onSuccess(null); return null; }).given(telemetryService).deleteAndNotify( - any(), any(), anyString(), anyList(), anyBoolean(), any()); + any(), any(), any(AttributeScope.class), anyList(), anyBoolean(), any()); } @AfterEach From 5ecd9b623844093095a537e2c4ad380fbde5271c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 9 Jan 2024 14:47:01 +0200 Subject: [PATCH 56/61] fixed tests --- .../service/telemetry/DefaultTelemetrySubscriptionService.java | 1 - .../rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java index 531f518579..2424bd8676 100644 --- a/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java +++ b/application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java @@ -243,7 +243,6 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer } @Override - public void saveAndNotify(TenantId tenantId, EntityId entityId, AttributeScope scope, List attributes, FutureCallback callback) { saveAndNotify(tenantId, entityId, scope, attributes, true, callback); } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java index f3fc7e6163..be25c71cee 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/telemetry/TbMsgDeleteAttributesNodeTest.java @@ -153,6 +153,6 @@ public class TbMsgDeleteAttributesNodeTest { } verify(ctx, times(1)).tellSuccess(newMsgCaptor.capture()); verify(ctx, never()).tellFailure(any(), any()); - verify(telemetryService, times(1)).deleteAndNotify(any(), any(), anyString(), anyList(), eq(notifyDevice || notifyDeviceMetadata), any()); + verify(telemetryService, times(1)).deleteAndNotify(any(), any(), any(AttributeScope.class), anyList(), eq(notifyDevice || notifyDeviceMetadata), any()); } } From e94a7e6cf74f23143e5e76deb9f014fe06536af9 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 9 Jan 2024 18:43:07 +0200 Subject: [PATCH 57/61] fixed test --- .../org/thingsboard/server/controller/WebsocketApiTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java index 47ce021dae..59fa730d2a 100644 --- a/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/WebsocketApiTest.java @@ -700,7 +700,7 @@ public class WebsocketApiTest extends AbstractControllerTest { private void sendAttributes(TenantId tenantId, EntityId entityId, TbAttributeSubscriptionScope scope, List attrData) throws InterruptedException { CountDownLatch latch = new CountDownLatch(1); - tsService.saveAndNotify(tenantId, entityId, scope.name(), attrData, new FutureCallback() { + tsService.saveAndNotify(tenantId, entityId, scope.getAttributeScope(), attrData, new FutureCallback() { @Override public void onSuccess(@Nullable Void result) { log.debug("sendAttributes callback onSuccess"); From 192951d4eb4302f915999b1f1db3701c6f4cd6eb Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 9 Jan 2024 19:10:59 +0200 Subject: [PATCH 58/61] minor refactoring --- .../server/dao/attributes/CachedAttributesService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java index f87827b535..c5270cc830 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CachedAttributesService.java @@ -144,8 +144,8 @@ public class CachedAttributesService implements AttributesService { } @Override - public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, Collection attributeKeys) { - return find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeys); + public ListenableFuture> find(TenantId tenantId, EntityId entityId, String scope, final Collection attributeKeysNonUnique) { + return find(tenantId, entityId, AttributeScope.valueOf(scope), attributeKeysNonUnique); } @Override From 5b513b8d8e9a7f7def2aa8a5ce940cb4a9601a38 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 10 Jan 2024 12:06:42 +0200 Subject: [PATCH 59/61] deleted redundant method --- .../service/install/SqlDatabaseUpgradeService.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index cbd8686918..7045280f0c 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -819,18 +819,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService Thread.sleep(5000); } - private void executeQuery(Connection conn, String query) { - try { - Statement statement = conn.createStatement(); - statement.execute(query); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script - printWarnings(statement); - log.info("Successfully executed query: {}", query); - } catch (SQLException e) { - log.error("Failed to execute query: {} due to: {}", query, e.getMessage()); - throw new RuntimeException("Failed to execute query:" + query + " due to: ", e); - } - } - protected void printWarnings(Statement statement) throws SQLException { SQLWarning warnings = statement.getWarnings(); if (warnings != null) { From 44b5e91676e9b84112f80299c195b8b58327826c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 10 Jan 2024 15:56:24 +0200 Subject: [PATCH 60/61] updated upgrade script: inlined function, moved view dropping before table rename --- .../main/data/upgrade/3.6.3/schema_update.sql | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/application/src/main/data/upgrade/3.6.3/schema_update.sql b/application/src/main/data/upgrade/3.6.3/schema_update.sql index e11c52f77f..19e0d44839 100644 --- a/application/src/main/data/upgrade/3.6.3/schema_update.sql +++ b/application/src/main/data/upgrade/3.6.3/schema_update.sql @@ -21,6 +21,8 @@ $$ BEGIN -- in case of running the upgrade script a second time: IF EXISTS(SELECT 1 FROM information_schema.columns WHERE table_name = 'attribute_kv' and column_name='entity_type') THEN + DROP VIEW IF EXISTS device_info_view; + DROP VIEW IF EXISTS device_info_active_attribute_view; ALTER INDEX IF EXISTS idx_attribute_kv_by_key_and_last_update_ts RENAME TO idx_attribute_kv_by_key_and_last_update_ts_old; IF EXISTS(SELECT 1 FROM pg_constraint WHERE conname = 'attribute_kv_pkey') THEN ALTER TABLE attribute_kv RENAME CONSTRAINT attribute_kv_pkey TO attribute_kv_pkey_old; @@ -40,8 +42,6 @@ $$ CONSTRAINT attribute_kv_pkey PRIMARY KEY (entity_id, attribute_type, attribute_key) ); END IF; - DROP VIEW IF EXISTS device_info_view; - DROP VIEW IF EXISTS device_info_active_attribute_view; END; $$; @@ -61,22 +61,6 @@ $$ END; $$; --- create to_attribute_type_id -CREATE OR REPLACE FUNCTION to_attribute_type_id(IN attribute_type varchar, OUT attribute_type_id int) AS -$$ -BEGIN - CASE - WHEN attribute_type = 'CLIENT_SCOPE' THEN - attribute_type_id := 1; - WHEN attribute_type = 'SERVER_SCOPE' THEN - attribute_type_id := 2; - WHEN attribute_type = 'SHARED_SCOPE' THEN - attribute_type_id := 3; - END CASE; -END; -$$ LANGUAGE plpgsql; - - -- insert keys into key_dictionary DO $$ @@ -96,7 +80,13 @@ DECLARE BEGIN IF EXISTS(SELECT 1 FROM information_schema.tables WHERE table_name = 'attribute_kv_old') THEN INSERT INTO attribute_kv(entity_id, attribute_type, attribute_key, bool_v, str_v, long_v, dbl_v, json_v, last_update_ts) - SELECT a.entity_id, to_attribute_type_id(a.attribute_type), k.key_id, a.bool_v, a.str_v, a.long_v, a.dbl_v, a.json_v, a.last_update_ts + SELECT a.entity_id, CASE + WHEN a.attribute_type = 'CLIENT_SCOPE' THEN 1 + WHEN a.attribute_type = 'SERVER_SCOPE' THEN 2 + WHEN a.attribute_type = 'SHARED_SCOPE' THEN 3 + ELSE 0 + END, + k.key_id, a.bool_v, a.str_v, a.long_v, a.dbl_v, a.json_v, a.last_update_ts FROM attribute_kv_old a INNER JOIN key_dictionary k ON (a.attribute_key = k.key) WHERE a.attribute_type IN ('SERVER_SCOPE', 'CLIENT_SCOPE', 'SHARED_SCOPE'); SELECT COUNT(*) INTO row_num_old FROM attribute_kv_old; From d77b735de39f13d8aacc2190cb60519fe6df269c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Wed, 10 Jan 2024 16:31:03 +0200 Subject: [PATCH 61/61] updated upgrade script: deleted redundant WHERE --- application/src/main/data/upgrade/3.6.3/schema_update.sql | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/application/src/main/data/upgrade/3.6.3/schema_update.sql b/application/src/main/data/upgrade/3.6.3/schema_update.sql index 19e0d44839..9888ee0304 100644 --- a/application/src/main/data/upgrade/3.6.3/schema_update.sql +++ b/application/src/main/data/upgrade/3.6.3/schema_update.sql @@ -87,8 +87,7 @@ BEGIN ELSE 0 END, k.key_id, a.bool_v, a.str_v, a.long_v, a.dbl_v, a.json_v, a.last_update_ts - FROM attribute_kv_old a INNER JOIN key_dictionary k ON (a.attribute_key = k.key) - WHERE a.attribute_type IN ('SERVER_SCOPE', 'CLIENT_SCOPE', 'SHARED_SCOPE'); + FROM attribute_kv_old a INNER JOIN key_dictionary k ON (a.attribute_key = k.key); SELECT COUNT(*) INTO row_num_old FROM attribute_kv_old; SELECT COUNT(*) INTO row_num FROM attribute_kv; RAISE NOTICE 'Migrated % of % rows', row_num, row_num_old;